A TCP endpoint can finish an application’s close operation while the protocol still retains state for that connection. After an active close completes its FIN exchange, the endpoint normally enters TIME-WAIT instead of discarding the connection record immediately.

That retained state has two jobs. It leaves the endpoint able to acknowledge a retransmitted final FIN, and it separates a closed connection from a later incarnation that could use the same local and remote addresses and ports.

TIME-WAIT is therefore not an idle established connection. It is a protocol boundary between connection incarnations.

Closing TCP requires state after the last ACK

TCP closes each direction independently. In a common active-close sequence, one endpoint sends FIN, receives an acknowledgment, later receives the peer’s FIN, and sends the final ACK. The peer can discard its connection state after receiving that ACK.

The endpoint that sent the final ACK cannot assume the ACK reached the peer. ACK segments are not themselves acknowledged. If that packet is lost, the peer can retransmit its FIN.

TIME-WAIT leaves enough state at the final-ACK sender to recognize that retransmitted FIN and send the ACK again. Receipt of another valid FIN while in TIME-WAIT restarts the timer defined by TCP’s state processing.

Discarding all state immediately after transmitting the final ACK would remove that protocol context. A retransmitted FIN could then arrive at an endpoint that no longer has the matching connection record.

Delayed segments can outlive the application connection

IP networks can delay, duplicate, reorder, and reroute packets. TCP sequence numbers distinguish positions in a byte stream, but a new connection can eventually reuse the same pair of sockets.

A TCP connection is identified by its endpoint pair: local IP address and port together with remote IP address and port. Closing a connection does not make every segment from that connection disappear from the network at the same instant.

A later connection using the same four values is a new incarnation. TIME-WAIT limits immediate reuse so old segments have time to expire rather than being presented during the lifetime of that later incarnation.

Sequence-number selection provides another layer of separation. The combination of connection state, sequence space, and timing reduces ambiguity between traffic from successive incarnations.

The timer is tied to maximum segment lifetime

The TCP specification expresses TIME-WAIT duration as twice the Maximum Segment Lifetime, or 2×MSL. RFC 9293 takes MSL as two minutes for the specification while noting that the value is an engineering choice.

The protocol model uses this interval as a bound for old traffic remaining relevant in the network. TIME-WAIT keeps the transmission control block until its timer expires, then deletes that state and moves to CLOSED.

Operating systems can implement surrounding socket APIs and reuse policies differently, so an observed host timer does not have to appear as a literal four-minute application delay in every environment. TCP also defines conditions under which a new SYN can reopen a connection directly from TIME-WAIT when sequence-number constraints are satisfied.

The invariant is narrower: active close retains protocol state for a bounded interval instead of treating final-ACK transmission as immediate erasure.

TIME-WAIT usually appears on the active closer

The normal close state machine places the endpoint that performs the active close into FIN-WAIT-1 and then FIN-WAIT-2 while it waits for the peer’s FIN. Once that FIN arrives and is acknowledged, the active closer enters TIME-WAIT.

The peer follows a different path. After receiving the first FIN it enters CLOSE-WAIT, then moves to LAST-ACK after its application closes its side. Receipt of the ACK for its own FIN allows that endpoint to delete the connection state.

This asymmetry is operationally visible. A service that accepts connections but routinely waits for clients to close first can accumulate fewer TIME-WAIT entries than a component that actively closes large numbers of short-lived connections.

Simultaneous close is different. If both endpoints initiate close and exchange FINs concurrently, both can reach TIME-WAIT.

A TIME-WAIT entry is not a leaked live session

Socket inspection tools often display TIME-WAIT beside established and listening sockets. That presentation can make a large count look like a collection of connections that failed to close.

The state means the data-transfer phase has ended. Application payload is no longer flowing through an established stream. The kernel is retaining enough TCP identity and timing information to complete the close semantics and protect connection reuse.

A high count can still matter. Connection-heavy systems consume kernel bookkeeping, ephemeral-port combinations, and other networking resources. The impact depends on the operating system, address selection, destination distribution, port range, reuse rules, and connection rate.

The count alone does not establish a resource leak. It records recent close activity as well as the host’s TCP retention policy.

Connection pooling changes the rate of TIME-WAIT creation

Short-lived TCP connections repeatedly execute setup and teardown. Each active close can create another TIME-WAIT interval. A client opening a fresh connection for every small request can therefore generate state much faster than a client reusing persistent connections.

Pooling changes the frequency of connection lifecycles rather than altering TIME-WAIT semantics. One connection can carry multiple application exchanges before close, reducing the number of four-tuples cycling through teardown.

Protocols with persistent transport sessions often gain more than handshake savings from reuse. They also reduce churn in kernel connection tables and ephemeral-port allocation.

This effect is especially visible when one source address repeatedly connects to the same destination address and port, because the available local-port combinations form a finite space.

Port reuse is a four-tuple problem

TIME-WAIT is sometimes described as a port being unavailable, but TCP connection identity is more specific than a local port alone. The relevant connection includes both endpoint addresses and both endpoint ports.

Socket APIs add their own binding rules on top of TCP state. Options related to address reuse, listener binding, and ephemeral-port selection can change which local bindings the kernel permits. Those controls do not erase the protocol need to distinguish old and new connection incarnations.

Treating reuse as a four-tuple and sequence-space issue avoids a common misdiagnosis: a process can encounter connection pressure even though the machine still has many numerically unused TCP ports, while another workload can reuse the same local port across distinct remote endpoints under permitted socket rules.

TIME-WAIT sits at this boundary between protocol correctness and host resource policy. The application has finished with the stream, but TCP keeps a temporary record so the final close remains recoverable and stale traffic does not immediately become traffic for a new incarnation.