The TCP Three-Way Handshake

Run a Speed Test

Before a single byte of a web page, an email, or an SSH session crosses the wire, the two computers involved hold a brief, three-message conversation to agree that they are both ready to talk. That conversation is the TCP three-way handshake — SYN, SYN-ACK, ACK — and it is the moment a "connection" actually comes into existence.

Why TCP Needs a Handshake at All

TCP promises something the underlying network does not: that bytes arrive in order, exactly once, with nothing lost. IP on its own makes no such promise — packets can be dropped, duplicated, or delivered out of order. TCP builds reliability on top of that unreliable foundation, and to do so it has to track every byte it sends using a sequence number. Before any data flows, both ends must agree on where their sequence numbers start.

That is the real job of the handshake. It is not a polite greeting — it is the step where each side announces its initial sequence number (ISN) and confirms it has heard the other side's. Once both ISNs are known and acknowledged, the connection is "established" and every subsequent byte can be numbered, ordered, and acknowledged. Skipping this step would leave both ends with no shared reference point for detecting loss or reordering.

The initial sequence number is deliberately randomised rather than starting at zero. A predictable ISN would let an attacker forge segments that slot neatly into the byte stream — the classic TCP sequence-prediction attack. Randomising the starting point makes that guessing game impractical.

The Three Steps, One at a Time

Call the side that opens the connection the client (your browser, say) and the side waiting for connections the server. The exchange runs like this:

  1. SYN — The client picks a random ISN (call it x) and sends a segment with the SYN flag set and sequence number x. In plain terms: "I want to open a connection; my bytes will be numbered starting from x."
  2. SYN-ACK — The server picks its own random ISN (y), and replies with a single segment carrying both the SYN and ACK flags. Its sequence number is y and its acknowledgement number is x+1. Meaning: "I heard you — I expect your next byte to be x+1 — and by the way my own bytes start at y."
  3. ACK — The client sends a final segment with the ACK flag, acknowledgement number y+1. "Got it. I expect your next byte to be y+1." The connection is now established at both ends.

The reason it is three messages and not four is that the server folds its acknowledgement of the client's SYN and its own SYN into a single segment. Each direction of the connection is opened independently — a SYN must be acknowledged each way — but two of those four logical events ride in one packet.

StepDirectionFlagsSequenceAcknowledgement
1Client → ServerSYNx
2Server → ClientSYN, ACKyx+1
3Client → ServerACKx+1y+1

Notice that the SYN flag itself consumes one sequence number even though it carries no application data — that is why the acknowledgement is x+1 rather than x. The same is true of the FIN flag used to close a connection.

What Else Gets Negotiated

The handshake is also where the two ends settle on the rules of engagement, using TCP options carried in the SYN and SYN-ACK segments. These are agreed once, up front, because changing them mid-stream would be awkward:

  • Maximum Segment Size (MSS) — the largest chunk of data each side is willing to receive in one segment, derived from the link's MTU. See MSS vs MTU for how the two relate.
  • Window scaling — an extension that lets the receive window grow beyond the original 64 KB limit, which is essential for high-speed, high-latency links.
  • Selective Acknowledgement (SACK) — permission to acknowledge non-contiguous blocks of received data, so a single lost segment does not force the retransmission of everything after it.
  • Timestamps — used to measure round-trip time accurately and to protect against very old, wrapped sequence numbers.

If one side does not advertise support for an option in its SYN, that option is simply not used for the connection. This is why both ends must offer window scaling for it to take effect.

Closing the Connection: A Separate, Four-Way Dance

Opening is symmetric and quick; closing is not the same exchange in reverse. Because either side can keep sending after the other has finished, TCP tears the connection down one direction at a time. One side sends FIN, the other ACKs it, then sends its own FIN, which is ACKed in turn — four segments in the general case. The side that closes first lingers in the TIME_WAIT state for a while to absorb any straggling packets before the four-tuple can be reused. The handshake opens the connection; the FIN exchange retires it.

Why the Handshake Costs You a Round Trip

The practical consequence of all this ceremony is latency. No application data can be sent until the client has received the SYN-ACK — that is one full round trip (RTT) of waiting. On a connection with 40 ms of latency to the server, every new TCP connection starts with roughly 40 ms of dead air before the request even leaves.

For an HTTPS request the cost stacks up further, because the TLS handshake runs after the TCP handshake completes — historically adding one or two more round trips on top. This layering is exactly what newer designs attack:

  • TCP Fast Open lets a client send data in the very first SYN on repeat visits, reclaiming that initial round trip.
  • HTTP keep-alive reuses one established connection for many requests, so the handshake is paid once rather than per request.
  • QUIC (the basis of HTTP/3) runs over UDP and merges the transport and cryptographic handshakes, cutting connection setup to a single round trip — or zero on resumption.

This is why connecting to a distant server feels sluggish even on a fast plan: throughput is plentiful, but each new connection still has to pay the round-trip toll. You can see the round-trip component directly in the ping figure of a speed test.

When the Handshake Goes Wrong

Most "connection refused" and "connection timed out" symptoms trace back to a handshake that never completed:

  • No SYN-ACK, silent timeout — a firewall is dropping the SYN. The client retransmits the SYN a few times with growing back-off, then gives up. The connection appears to hang.
  • RST instead of SYN-ACK — the destination is reachable but nothing is listening on that port, so the host actively refuses with a reset. This is the fast, explicit "connection refused".
  • SYN flood — an attacker sends a torrent of SYNs and never sends the final ACK. Each half-open connection ties up an entry in the server's backlog queue. SYN cookies defend against this by encoding the connection state into the server's own ISN, so no memory is allocated until a valid ACK returns.

You can watch a real handshake in a packet capture: filter for the SYN flag in a tool like tcpdump or Wireshark and you will see the SYN, SYN-ACK, ACK trio at the start of every TCP conversation.

Frequently Asked Questions

What is the TCP three-way handshake?

It is the exchange of three segments — SYN, SYN-ACK, ACK — that establishes a TCP connection before any application data is sent. It lets both ends confirm two-way reachability and agree on the initial sequence numbers used to order and acknowledge bytes.

Why is it called a three-way handshake?

Because three segments are exchanged. The server combines its acknowledgement of the client's SYN and its own SYN into one SYN-ACK segment, so what is logically four events becomes three messages.

What do SYN and ACK mean?

SYN (synchronise) proposes an initial sequence number and requests a connection; ACK (acknowledge) confirms receipt of bytes up to a given sequence number. Both are single-bit control flags in the TCP header.

How long does the handshake take?

One full round trip before data can flow — the SYN out and the SYN-ACK back. On a 40 ms link that is about 40 ms of unavoidable setup delay per new connection, which is why keep-alive and QUIC exist to avoid paying it repeatedly.

What is a SYN flood and how is it stopped?

A SYN flood sends many SYNs without completing the handshake, exhausting the server's half-open connection table. SYN cookies are the standard defence: the server encodes connection state into the sequence number it returns and allocates no memory until the client's final ACK proves the request was genuine.

Related Guides

More From This Section