HyStart++: Modified Slow Start for TCP
Extracted elements (19)
CSS is introduced between Slow Start and Congestion Avoidance to handle jitter: if RTT returns to baseline during CSS, the earlier delay spike was not congestion-induced and slow start resumes, preventing premature bandwidth limitation due to transient delay spikes.
HyStart++ drops the Inter-Packet Arrival algorithm from the original HyStart and relies solely on the Delay Increase algorithm, because the Inter-Packet Arrival algorithm performs poorly in practice due to ACK compression and fails to detect congestion early.
HyStart++ is recommended only for the initial slow start because subsequent slow starts use the discovered ssthresh to exit slow start, naturally avoiding the overshoot problem that HyStart++ is designed to prevent.
HyStart++ limits cwnd increase per ACK to L*SMSS bytes to control burstiness. For non-paced implementations L=8 balances cwnd growth on high-speed networks against burstiness; for paced implementations L=infinity is safe because pacing already smooths output.
In application-limited scenarios where in-flight data falls below the BDP, smaller RTT samples may repeatedly trigger the CSS-to-slow-start reentry, causing oscillation between CSS and slow start. This is expected and harmless: it neither causes premature congestion avoidance entry nor overshooting.
While HyStart++ is described for TCP, it can also be applied to other transport protocols that use slow start, such as QUIC (RFC 9002) and SCTP (RFC 9260).
A paced TCP implementation SHOULD use L = infinity, as pacing mitigates burst concerns and allows optimal cwnd growth on modern networks.
An implementation MAY use HyStart++ to grow the restart window after a long idle period, and MAY tune the algorithm constants for different network characteristics.
An implementation SHOULD use HyStart++ only for the initial slow start (when ssthresh is at its initial arbitrarily high value per RFC 5681) and fall back to standard slow start for the remainder of the connection lifetime.
At any given time, a TCP sender MUST NOT send data with a sequence number higher than the sum of the highest acknowledged sequence number and the minimum of cwnd and rwnd.
Implementations of HyStart++ are RECOMMENDED to take at least N_RTT_SAMPLE RTT samples per round, even though TCP implementations are only REQUIRED to take at least one RTT sample each round.
It is RECOMMENDED that HyStart++ implementations use the specified default constants: MIN_RTT_THRESH=4ms, MAX_RTT_THRESH=16ms, MIN_RTT_DIVISOR=8, N_RTT_SAMPLE=8, CSS_GROWTH_DIVISOR=4, CSS_ROUNDS=5, L=infinity if paced or L=8 if non-paced.
The minimum value of CSS_GROWTH_DIVISOR MUST be at least 2. A value of 1 results in the same aggressive behavior as regular slow start.
During CSS, cwnd is grown as cwnd + (min(N, L * SMSS) / CSS_GROWTH_DIVISOR), providing exponential growth with a smaller base than standard slow start to cautiously probe whether the slow start exit was premature.
HyStart++ tracks rounds using sequence numbers: windowEnd is initialized to SND.NXT, and when windowEnd is ACKed the current round ends and windowEnd is reset to SND.NXT. At the start of each round, lastRoundMinRTT and currentRoundMinRTT are updated.
The RTT threshold RttThresh is computed each round as max(MIN_RTT_THRESH, min(lastRoundMinRTT / MIN_RTT_DIVISOR, MAX_RTT_THRESH)). Slow start exit is triggered when currentRoundMinRTT >= lastRoundMinRTT + RttThresh and at least N_RTT_SAMPLE samples have been collected.
An attacker can cause HyStart++ to exit slow start prematurely and impair TCP connection performance by dropping data packets or their acknowledgments, triggering the RTT-increase heuristic falsely.
The ACK division attack (SCWA99) does not affect HyStart++ because cwnd increase is based on the number of bytes newly acknowledged per ACK rather than a fixed constant per ACK arrival, removing the incentive to split ACKs.
A TCP sender progresses through three phases: standard Slow Start, Conservative Slow Start (CSS), and Congestion Avoidance. The trigger from Slow Start to CSS is a round-trip delay increase exceeding RttThresh; CSS returns to Slow Start if currentRoundMinRTT drops below cssBaselineMinRtt, and advances to Congestion Avoidance after CSS_ROUNDS rounds or on loss/ECN.