TCP Sequence Number: How It Works
- Average speed
- km/h
- Result
- Finish time
- 50 min
- You entered
- Distance
- 10 km
- You entered
TCP sequence numbers are 32-bit counters in each TCP segment that let the receiver reassemble data in the correct order and detect missing or duplicate packets. Every byte of data sent over a TCP connection is numbered, and the sequence number in a packet header tells the receiver which byte position this segment starts at. This article explains what sequence numbers are, how they are chosen, how they enable reliable delivery, and the common issues that arise with them.
Background: Why TCP Needs Sequence Numbers
TCP (Transmission Control Protocol) was designed in the 1970s to provide reliable, ordered delivery of a byte stream over an unreliable IP network. Unlike UDP, which simply sends datagrams and hopes they arrive, TCP must handle packets that arrive out of order, get duplicated, or are lost entirely. Sequence numbers are the core mechanism that makes this possible.
Each byte of data in a TCP connection is assigned a number, starting from an initial value (ISN) chosen during the connection setup. The sequence number field in the TCP header indicates the number of the first byte in that segment. The acknowledgment number (ACK) tells the sender which byte the receiver expects next. This numbering allows both sides to:
- Reassemble data in the correct order even if packets arrive scrambled.
- Detect missing bytes and request retransmission.
- Discard duplicate packets that arrive twice.
- Implement flow control by tracking how much data is in flight.
Without sequence numbers, a receiver could not tell if a segment was a duplicate, missing, or simply late. The design is elegant: the sender and receiver maintain a sliding window of acceptable sequence numbers, and any segment outside that window is either discarded or triggers a retransmission.
How TCP Sequence Numbers Work
When a TCP connection is established via the three-way handshake, each side chooses an Initial Sequence Number (ISN). The client sends a SYN packet with its ISN (e.g., 1000). The server responds with a SYN-ACK that contains its own ISN (e.g., 5000) and acknowledges the client’s ISN by setting the ACK number to 1001 (the client’s ISN + 1). The client then sends an ACK with sequence number 1001 and acknowledgment number 5001.
After setup, the sequence number in each data segment is the byte offset from the initial ISN. For example, if the client sends 100 bytes starting at sequence 1001, the next segment will start at sequence 1101. The receiver’s ACK number tells the sender the next expected byte, so an ACK of 1101 means all bytes up to 1100 have been received.
Sequence numbers are also used in the TCP window update and keep-alive mechanisms. A zero-length segment with a sequence number can be used to probe the receiver’s window without sending data. The numbers wrap around after 2^32 bytes (about 4 GB), but the TCP specification uses modular arithmetic so that comparisons still work correctly even after wrapping.
Initial Sequence Number (ISN) Selection
The ISN is not random in the sense of being arbitrary; it is chosen to prevent a stale segment from a previous connection from being mistaken as part of a new connection. The original RFC 793 suggested a global 32-bit counter that increments every 4 microseconds. This ensures that two connections with the same source and destination ports are unlikely to have overlapping sequence numbers.
Modern operating systems use a pseudo-random generator for the ISN to guard against off-path attacks. If an attacker can predict the ISN, they can spoof packets and inject data into a connection. This was the basis of the famous TCP sequence prediction attack described by Kevin Mitnick in 1994. Since then, ISNs are randomized to make prediction impractical.
The ISN is exchanged during the handshake, and both sides must keep track of it for the life of the connection. The sequence number of the first data byte is ISN+1 because the SYN flag itself consumes one sequence number. Similarly, the FIN flag consumes one sequence number, so the final ACK after a connection close acknowledges the FIN’s sequence number.
Common Problems and Misconceptions
One frequent misconception is that sequence numbers are per-packet. In reality, they are per-byte. A segment carrying 1000 bytes will have a sequence number that is 1000 higher than the previous segment. Another misconception is that the ACK number is the sequence number of the last received byte; it is actually the next expected byte.
A common problem is sequence number wrap-around. With a 32-bit field, after 4 GB of data, the numbers repeat. TCP handles this by using relative comparisons: a sequence number is considered “less than” another if the difference is less than 2^31. This works as long as the window size never exceeds 2^31, which is true for practical windows.
Another issue is the “sequence number attack” where an attacker sends a spoofed RST packet with a guessed sequence number to tear down a connection. This is mitigated by randomizing ISNs and by using TCP timestamps as an additional check. The timestamps option also helps with PAWS (Protection Against Wrapped Sequences) to avoid confusion after wrap-around.
Sequence Numbers vs. Acknowledgment Numbers
It is easy to confuse the two fields, but they serve different roles. The sequence number in a segment tells the receiver where this segment’s data starts. The acknowledgment number tells the sender what the receiver is expecting next. In a full-duplex connection, both sides maintain their own sequence numbers and send ACKs for the other side’s data.
For example, if a client sends a segment with sequence 1001 and 200 bytes, the server will reply with an ACK number of 1201, meaning it has received bytes up to 1200 and expects byte 1201 next. The server’s own data segments will have their own sequence numbers, independent of the client’s.
The ACK number is only valid when the ACK flag is set. In a pure ACK segment (no data), the sequence number is the next byte the sender will send, which is often the same as the last ACKed sequence. This is why you see ACK segments with sequence numbers that don’t change.
How Sequence Numbers Enable Reliability
Reliability in TCP is achieved through positive acknowledgments and retransmission. When a sender sends a segment, it starts a timer. If the timer expires before an ACK arrives, the sender retransmits the segment. The receiver uses sequence numbers to detect if a retransmitted segment is a duplicate: if it receives a segment with a sequence number lower than its expected next byte, it discards it and sends a duplicate ACK.
Out-of-order segments are buffered by the receiver until the missing bytes arrive. The receiver’s window is a range of sequence numbers it is willing to accept. This is called the receive window. The sender must not send data beyond the receiver’s advertised window, which is communicated in the window size field of the TCP header.
Sequence numbers also support Selective Acknowledgment (SACK), an optional feature that lets the receiver tell the sender exactly which segments are missing, rather than just the next expected byte. This improves efficiency when multiple segments are lost.
Frequently Asked Questions
What is the range of TCP sequence numbers?
TCP sequence numbers are 32-bit unsigned integers, so they range from 0 to 4,294,967,295. After the maximum value, they wrap around to 0. The TCP specification defines that numbers are compared using modular arithmetic, so a number is considered less than another if the difference is less than 2^31.
Can sequence numbers be negative?
No, they are unsigned. However, in the TCP header, the sequence number field is 32 bits, so it cannot represent negative numbers. The comparison logic treats numbers as if they are on a circle, so a number just after wrap-around is considered greater than a number near the maximum.
How does a receiver detect a duplicate segment?
The receiver keeps track of the next expected sequence number. If a segment arrives with a sequence number that is lower than the expected number, it is a duplicate or an old segment. The receiver discards it and sends an ACK for the next expected byte to remind the sender.
What is a sequence number attack?
An attacker can send a forged TCP segment (such as a RST or data) with a guessed sequence number. If the guess is within the receiver’s window, the receiver will accept it as legitimate. By randomizing the ISN, the attacker cannot easily predict the next sequence number, making the attack difficult.
Why does the sequence number increase by more than 1 for data?
Because each byte of data consumes one sequence number. A segment with 1000 bytes of payload will have a sequence number that is 1000 higher than the previous segment’s sequence number. The SYN and FIN flags also consume one sequence number each, but they are not data bytes.
What happens if the sequence number wraps around?
TCP handles wrap-around by using relative comparisons. As long as the difference between two sequence numbers is less than 2^31, the comparison is valid. The PAWS mechanism using timestamps can also help disambiguate old segments after a wrap-around.
Related
Formula used
in t | Finish time | min | 50 | 0 in d | Distance | km | 10 | 0 out pace | Average pace | min/km | t / d | 2 out speed | Average speed | km/h | d / (t / 60) | 2
Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.