Summary
- RFC 3465 proposed Appropriate Byte Counting: grow TCP's congestion window from newly acknowledged bytes rather than the number of ACK messages, so delayed ACKs and ACK division could not arbitrarily change the credit.
- Byte evidence still needed limits. Slow start capped each ACK's increase with
L;Lcould not exceed two sender maximum segment sizes and had to fall to one after a retransmission timeout, when a cumulative ACK might cover old data rather than fresh path capacity.
An ACK message was not a unit of progress
Traditional congestion-window growth used an accessible proxy. In slow start, each arriving ACK could add a fixed amount; in congestion avoidance, implementations commonly approximated one segment of growth per round trip by adding a fraction for each ACK. The proxy worked neatly when a receiver acknowledged each segment and ACKs were not lost. Change the number of ACK messages, however, and the same byte progress produced a different sender response.
RFC 3465, published as Experimental in February 2003, replaced the proxy with what the cumulative acknowledgment actually covered. Its plain text, RFC Editor record, Datatracker entry, history, references, later citations and errata search bind the public record. The document modified the window-growth logic of RFC 2581, whose later standards-track successor was RFC 5681.
Delayed acknowledgments exposed one side of the mismatch. The receiver behavior bounded by RFC 1122 could acknowledge roughly every second full-sized segment. An ACK-counting sender then saw half as many opportunities to grow and could open its window at roughly half the intended pace. A lost ACK erased another opportunity even when a later cumulative ACK proved the same bytes had arrived.
The opposite manipulation was ACK division. A receiver could acknowledge small successive portions of one incoming segment with several ACKs. If every message earned a fixed congestion-window increase, one segment of delivered data could manufacture several units of sending credit. RFC 3465 made that receiver behavior visible as repeated messages carrying only the same bounded total of new byte evidence.
The sender kept a byte ledger
In congestion avoidance, Appropriate Byte Counting maintained bytes_acked in the TCP control block. Each ACK added only the previously unacknowledged bytes it covered. Once the accumulator reached the current cwnd, the sender subtracted that window amount and increased cwnd by one sender maximum segment size, or SMSS. This retained the target of roughly one segment per round trip without making the result depend on whether progress arrived in many ACKs or a few.
Slow start required a different rule. The sender could increase cwnd by the newly acknowledged bytes in an incoming ACK, but no more than a limit called L. With L=1*SMSS, the behavior was no more aggressive than the earlier rule, and RFC 3465 recommended ABC in that conservative form for TCP stacks. It allowed L=2*SMSS for experimentation because that could offset an ACK for every two segments, but it prohibited any value above two SMSS.
The cap protected more than fairness. A very large cumulative or stretch ACK could otherwise release a line-rate burst. Even at two SMSS, ABC could increase micro-bursts after one ACK and make slow start expand closer to a doubling each round trip. The RFC reported modestly higher loss in its limited simulations and encouraged further experimentation rather than claiming universal safety or deployment. It recommended pairing the behavior with selective acknowledgments from RFC 2018. RFC 2861 addressed the related problem of unused congestion-window credit accumulating during application-limited periods.
A cumulative ACK could carry old history
The sharpest boundary appeared after a retransmission timeout. Suppose an early segment was lost but later segments reached the receiver. When the timer expired, the sender retransmitted the missing segment. The next cumulative ACK could suddenly cover that retransmission plus data that had already arrived before the latest round trip. Those bytes were newly acknowledged to the sender, but they did not all demonstrate that equivalent data had just left the network.
RFC 3465 therefore required L=1*SMSS during slow-start recovery after an RTO. The timer rules then specified by RFC 2988, later replaced by RFC 6298, supplied the surrounding recovery context. The distinction is subtle: cumulative acknowledgment state is valid protocol evidence, yet its temporal meaning may be broader than the current capacity probe.
Other TCP mechanisms had different authority. RFC 3042 let Limited Transmit send new data before the third duplicate ACK under bounded conditions; it did not define ABC's window ledger. RFC 3449 analyzed asymmetric paths, ACK filtering and reconstruction; it did not move sender credit from message count to byte count. The implementation catalogue in RFC 2525 is context for why exact sender and receiver behavior mattered, not proof of ABC deployment.
Heng Lu's later reality-layer discipline helps separate four receipts: ACK messages observed, new bytes cumulatively acknowledged, credit admitted by the algorithm and data actually sent into the path. His case for running-code primacy directs attention to the accumulator, cap, recovery state and emitted burst. These are later editorial lenses, not claims about the RFC author's private intent.
RFC 3465 did not declare every acknowledged byte to be fresh capacity. It made the accounting harder to manipulate, then bounded what that accounting could authorize. The number of receipts could change. The underlying progress was supposed to remain the same.
Sources
Member Briefing
Deeper Profile Context
Sign in with the right membership level to unlock the full briefing and source notes.
Only for Strategic Circle
Strategic Circle
Open to all readers. Unlock profile briefings after joining and signing in.
Join Strategic CircleOnly for Leadership Alliance
Leadership Alliance
For qualified IP-asset owners and management; sign in to unlock alliance briefings.
Join Leadership Alliance
