<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.43 (Ruby 3.4.9) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-kazuho-ccwg-cuback-01" category="std" consensus="true" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.1 -->
  <front>
    <title abbrev="cuback">CUBACK: CUBIC Driven by the ACK Clock</title>
    <seriesInfo name="Internet-Draft" value="draft-kazuho-ccwg-cuback-01"/>
    <author fullname="奥 一穂" asciiFullname="Kazuho Oku">
      <organization>Fastly</organization>
      <address>
        <email>kazuhooku@gmail.com</email>
      </address>
    </author>
    <date year="2026" month="November" day="02"/>
    <workgroup>Congestion Control Working Group</workgroup>
    <keyword>internet-draft</keyword>
    <abstract>
      <?line 25?>

<t>This document specifies Cuback, an ACK-driven reformulation of CUBIC congestion
control. It simplifies implementation by replacing CUBIC's mutable time- and
ACK-driven state with pure functions over immutable per-epoch parameters, for
which test vectors are provided. Congestion-window growth uses the same
ACK-driven mechanism as Reno, removing several sources of implementation error.
When entering a high-capacity path, a newcomer converges on its share sooner
than under CUBIC, so short flows complete earlier.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
    Congestion Control Working Group Working Group mailing list (ccwg@ietf.org),
    which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/ccwg/"/>.</t>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/kazuho/draft-kazuho-ccwg-cuback"/>.</t>
    </note>
  </front>
  <middle>
    <?line 36?>

<section anchor="intro">
      <name>Introduction</name>
      <t>CUBIC <xref target="CUBIC"/> is a widely deployed congestion-control algorithm that
improves scalability over Reno <xref target="RENO"/> by defining congestion-window
growth as a cubic function of elapsed time. Its implementation, however, is more complex than the
growth function itself might suggest.</t>
      <t>During congestion avoidance, a CUBIC sender maintains two independently evolving
window estimates: the time-driven cubic window and the ACK-driven Reno-friendly
window. The sender must update both estimates and select the larger of the two.
In addition, because the cubic window advances with wall-clock time, the sender
needs mutable epoch state and a state machine that pauses the cubic clock when
the sender ceases to be congestion-control limited and resumes it when
transmission becomes limited by the congestion window again. Correctly
maintaining these states complicates implementations and their interaction with
application-limited periods and other congestion-control transitions.</t>
      <t>This document specifies Cuback, an ACK-driven reformulation of CUBIC. Cuback
expresses both the cubic and Reno-friendly growth functions in terms of the
amount of data that must be acknowledged for the congestion window to reach a
given value. The parameters defining those functions are established at the
beginning of a congestion-avoidance epoch and remain immutable for the duration
of that epoch. Congestion-window growth can therefore be calculated from a pure
function of the current congestion window and the per-epoch parameters, without
maintaining separately evolving cubic and Reno-friendly window estimates.</t>
      <t>This formulation also eliminates the need to pause and resume a
wall-clock-driven CUBIC epoch. When acknowledgments stop arriving, advancement
along the Cuback curves stops naturally. The remaining runtime state is
essentially the same as in Reno: the sender tracks how many additional bytes
need to be acknowledged before increasing the congestion window by one MSS.</t>
      <t>Cuback therefore retains the characteristic growth behavior of CUBIC while
reducing congestion avoidance to the same ACK-driven window-increase mechanism
used by Reno. In both Reno and Cuback, acknowledged bytes are accumulated until
enough have been received to increase the congestion window by one MSS. The
difference lies only in how the required number of acknowledged bytes is
calculated: Reno derives it directly from the current congestion window, whereas
Cuback obtains it by evaluating the pure functions defined in this document.</t>
      <t>What remains of CUBIC's complexity is confined to a pure function of the
congestion window and the per-epoch immutables, which can be validated directly
from its inputs and outputs without exercising a sequence of state-machine
transitions. An implementation can therefore be checked against known values,
and is correspondingly less prone to error. This document includes test vectors for
that purpose.</t>
      <t>The use of the ACK clock has a performance benefit as well. When a new flow joins a
high-capacity path already carrying an established flow, it acquires its share
more rapidly than it would under CUBIC. Cuback derives its growth rate from the
congestion window and round-trip time recorded at the previous congestion event.
Because the cubic function gives a flow with a smaller window a larger
proportional increase, a newcomer gains share; its ACK rate, and hence its ACK
clock, runs faster than originally anticipated. This gain compounds over
successive round trips, and reduces the time to completion of short flows, such
as the delivery of HTTP objects. The advantage diminishes as the flow's rate
converges on the value it recorded.</t>
      <t>Cuback alters only the congestion avoidance stage of CUBIC. All other behavior
specified in <xref target="CUBIC"/> applies unchanged.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

<t>This document uses the notation of <xref target="CUBIC"/>, in which window sizes are
expressed in segments. An implementation that counts bytes instead scales each
window value by SMSS, divides the sums appearing in <xref target="ca"/> by SMSS, and
expresses the lower bound on D(w) as 2 * SMSS.</t>
    </section>
    <section anchor="ca">
      <name>Cuback Congestion Avoidance</name>
      <t>During congestion avoidance, a Reno sender accumulates the data acknowledged and
increases cwnd by one segment each time a threshold D(cwnd) is reached:</t>
      <artwork><![CDATA[
on entering congestion avoidance:
  pending = 0

on receiving an acknowledgement, while cwnd >= ssthresh:
  pending = pending + segments_acked
  while pending >= D(cwnd):
    pending = pending - D(cwnd)
    cwnd = cwnd + 1
]]></artwork>
      <t>In Reno, that threshold is the congestion window itself:</t>
      <artwork><![CDATA[
D_reno(cwnd) = cwnd
]]></artwork>
      <t>Cuback retains the mechanism above unchanged and replaces only the threshold,
where A(w) is the amount of data, counted from the beginning of the current
congestion avoidance stage, that has to be acknowledged for the congestion
window to reach w:</t>
      <artwork><![CDATA[
D(w)       = max(2, A(w + 1) - A(w))

A(w)       = min(A_cubic(w), A_reno(w))

A_cubic(w) = bandwidth * (K(W_max, cwnd_epoch) + cbrt((w - W_max) / C))

A_reno(w)  = (w - cwnd_epoch) * (w + cwnd_epoch - 1)
               / (2 * alpha_cubic)                            w <= W_max

           = (W_max - cwnd_epoch) * (W_max + cwnd_epoch - 1)
               / (2 * alpha_cubic)
             + (w - W_max) * (w + W_max - 1) / 2              w >  W_max

K(W_max, cwnd_epoch) = cbrt((W_max - cwnd_epoch) / C)
]]></artwork>
      <t>W_max, bandwidth, and cwnd_epoch are fixed when the congestion avoidance stage
begins and do not change until the next congestion event:</t>
      <ul spacing="normal">
        <li>
          <t>W_max is as defined in <xref section="4.1.2" sectionFormat="of" target="CUBIC"/>. It is set to cwnd_prior,
the congestion window before the reduction at the congestion event that began
the stage.</t>
        </li>
        <li>
          <t>bandwidth is an estimate of the rate at which the bottleneck delivers data, in
segments per second. It is set at the congestion event to cwnd_prior divided
by the smoothed round-trip time.</t>
        </li>
        <li>
          <t>cwnd_epoch is the congestion window at the beginning of the congestion
avoidance stage, as defined in <xref section="4.1.2" sectionFormat="of" target="CUBIC"/>.</t>
        </li>
      </ul>
      <t>alpha_cubic, beta_cubic, and C are the constants defined in <xref target="CUBIC"/>, with
recommended values:</t>
      <artwork><![CDATA[
beta_cubic  = 0.7
alpha_cubic = 0.529  # 3 * (1 - beta_cubic) / (1 + beta_cubic)
C           = 0.4
]]></artwork>
      <t>A sender that derives ssthresh from flight_size rather than from cwnd
(<xref section="4.6" sectionFormat="of" target="CUBIC"/>) <bcp14>MUST</bcp14> use flight_size in place of cwnd_prior
throughout this section. W_max, cwnd_epoch, and bandwidth <bcp14>MUST</bcp14> be derived from
the same quantity.</t>
      <t>When congestion avoidance is entered without a congestion event, such as on
exiting slow start, the parameters are established at that point instead. cwnd
is not reduced, so W_max equals cwnd_epoch and K is zero, and A(w) describes
growth along the convex region alone.</t>
      <t>The expressions above are derived in <xref target="derivation"/>.</t>
      <section anchor="fast-convergence">
        <name>Fast Convergence</name>
        <t>Fast convergence is applied as described in <xref section="4.7" sectionFormat="of" target="CUBIC"/>: on a
congestion event, if cwnd is below W_max, W_max is reduced before cwnd is:</t>
        <artwork><![CDATA[
W_max = cwnd * (1 + beta_cubic) / 2
]]></artwork>
        <t><xref section="4.3" sectionFormat="of" target="CUBIC"/> keys the switch to alpha_cubic = 1 to cwnd_prior rather
than to W_max, so A_reno in <xref target="ca"/> uses cwnd_prior in its place; a sender that
does not retain it can recover it as cwnd_epoch / beta_cubic.</t>
      </section>
      <section anchor="spurious">
        <name>Spurious Congestion Events</name>
        <t>When a congestion event is determined to have been spurious (<xref section="4.9" sectionFormat="of" target="CUBIC"/>), a sender that reverts cwnd and ssthresh <bcp14>MUST</bcp14> also restore W_max,
bandwidth, and cwnd_epoch to the values they held before the event.</t>
      </section>
      <section anchor="app-limited">
        <name>Application-Limited Senders</name>
        <t><xref target="CUBIC"/> places two separate requirements on an application-limited sender.
<xref section="4.2" sectionFormat="of" target="CUBIC"/> requires that the elapsed time used by the cubic curve
exclude application-limited periods, and <xref section="5.8" sectionFormat="of" target="CUBIC"/> restricts the
increase of cwnd.</t>
        <t>The former has no counterpart in Cuback, there being no clock to pause and
resume. Growth is governed by acknowledged data rather than by elapsed time: an
idle sender accrues no growth, while a sender that continues to deliver data
below cwnd grows only in proportion to that delivered data.</t>
        <t>The latter applies to Cuback as it does to <xref target="CUBIC"/>. Stacks might meet it by
applying <xref target="RATE-LIMITED"/> as described in
<xref target="rli"/>. Other means are also possible, such as suspending the
increase while bytes in flight are below cwnd, as in <xref section="7.8" sectionFormat="of" target="RFC9002"/>.</t>
        <section anchor="rli">
          <name>Applying Rate-Limited Increase</name>
          <t><xref target="RATE-LIMITED"/> caps cwnd at limit(maxFS), the largest
congestion window that the congestion controller would yield from the
acknowledgements produced by one window of maxFS, the largest FlightSize
observed since cwnd was last reduced. Each congestion controller defines its own
limit(). Under <xref target="CUBIC"/>, the growth produced by a window of acknowledgements
results from per-acknowledgement updates to cwnd and W_est, which depend on each
other and on the time at which each acknowledgement arrives, making limit()
complex to derive. Under Cuback, it is determined by A(w) alone.</t>
          <t>Within one window of acknowledgements, cwnd can be raised from maxFS to w + 1
approximately when A(w + 1) - A(maxFS) does not exceed maxFS, with the lower
bound on D(w) further limiting cwnd to 1.5 * maxFS. Separately, as in the limit that
<xref target="RATE-LIMITED"/> gives for Reno, cwnd is allowed to reach
maxFS + 1, so that a sender limited by cwnd continues to grow even where a
one-segment increase takes more than one window of acknowledgements.</t>
          <t>An increase of cwnd from w to w + 1 is therefore permitted when:</t>
          <artwork><![CDATA[
(A(w + 1) - A(maxFS) <= maxFS and w + 1 <= 1.5 * maxFS) or
  w <= maxFS
]]></artwork>
          <t>A(w + 1) is evaluated for D(w) in any case, and A(maxFS) changes only when
maxFS does, so the check adds no cube root to an increase.</t>
        </section>
      </section>
    </section>
    <section anchor="relationship">
      <name>Relationship to RFC 9438</name>
      <section anchor="sensitivity">
        <name>Sensitivity to the Bandwidth Estimate</name>
        <t>bandwidth scales A_cubic linearly, so an error in it is an error in the rate at
which the cubic curve is traversed: an underestimate traverses the curve more
quickly than elapsed time would, and an overestimate more slowly. The
round-trip time it is derived from has to describe the path as it was while cwnd
was at its peak, with the bottleneck queue at its deepest.</t>
        <t>The error is bounded in either direction by mechanisms already present. An
overstated bandwidth makes A_cubic large, and A_reno carries no bandwidth term
at all, so A(w) becomes A_reno(w): the flow then grows at the Reno-friendly
rate, and no error in bandwidth can slow it below that. An understated bandwidth
makes A_cubic small, and the lower bound of two segments on D(w) caps growth at
half the congestion window per round trip, which <xref target="CUBIC"/> adopts to keep the
increase below that of slow start.</t>
        <t>Between those bounds the estimate matters only at windows large enough for the
cubic curve to govern. Windows that large deliver many acknowledgements per
round trip, and a QUIC sender takes a round-trip sample from every
acknowledgement that advances the largest acknowledged packet number
<xref target="RFC9002"/>, so the smoothed round-trip time follows the path closely by the
time the estimate matters.</t>
      </section>
      <section anchor="convergence">
        <name>Convergence under the ACK Clock</name>
        <t>Deriving the clock from acknowledgements reinforces the convergence that AIMD
provides, because bandwidth records the rate the flow was achieving before it
reduced. A flow holding a large share gives up the most at a congestion
event, so the rate it goes on to achieve falls below the value it recorded and
its clock runs slow. A flow arriving with a small share records a correspondingly
small rate and then achieves more than it recorded, so its clock runs fast. The
congestion window advances fastest for the flow gaining share and slowest for
the one giving it up.</t>
        <t>The curve advances at the ratio of the rate the flow is currently achieving to
the rate recorded at the last congestion event. A flow that has since doubled
its share traverses the curve twice as fast as elapsed time would carry it; one
that has halved its share, half as fast. The advantage therefore decays as the
achieved rate converges on the recorded one.</t>
      </section>
      <section anchor="clock-timing">
        <name>Sensitivity to the Timing of Clock Transitions</name>
        <t><xref section="4.2" sectionFormat="of" target="CUBIC"/> requires that elapsed time exclude periods during which
cwnd was not updated because the sender was application limited. A CUBIC sender
therefore has to pause its clock as the flow becomes application limited and
resume it as the flow ceases to be, and an error at either edge is an error in
the elapsed time the curve is read against.</t>
        <t>Treating an application-limited sender as congestion-window limited leaves the
clock running. W_cubic(t) advances while the flow is not filling cwnd, and cwnd
grows on evidence the path never supplied; <xref section="5.8" sectionFormat="of" target="CUBIC"/> names the
consequence, that W_cubic(t) "might be very high after restarting from these
periods". Treating a congestion-window-limited sender as application limited
stops the clock instead, so the elapsed time that should have advanced the curve
is never accrued and the flow grows too slowly.</t>
        <t>Neither edge is easy to observe. A sender might emit as many datagrams as it
can in one pass and so appear limited by the congestion controller, even though
its bytes in flight are below cwnd. Conversely, an in-stack pacer might withhold
emission after a train of acknowledgements, leaving bytes in flight below cwnd
although the connection is still limited by the congestion window. <xref target="RATE-LIMITED"/> updates
<xref target="CUBIC"/>, mitigating the impact of such overgrowth by capping cwnd at a value
derived from the largest FlightSize observed, but a CUBIC sender is still
required to pause and resume its clock at the correct moments.</t>
        <t>Cuback has no clock to stop or start. When the sender stops, the advance of A(w)
stops with it: no acknowledgements arrive, and nothing accrues to be caught up
when transmission resumes. The case in which a mistimed CUBIC clock does the
most damage therefore does not arise.</t>
        <t>A sender that keeps sending but holds less than cwnd in flight is not protected
altogether, only bounded. Growth is governed by the amount of data acknowledged,
as in Reno, so cwnd advances in proportion to what the path delivered rather
than in proportion to elapsed time. Applying
<xref target="RATE-LIMITED"/> caps what remains, holding cwnd to what
one window of the largest FlightSize observed would yield.</t>
      </section>
      <section anchor="reno-estimate">
        <name>The Reno-Friendly Estimate</name>
        <t><xref section="4.3" sectionFormat="of" target="CUBIC"/> advances W_est on each acknowledgement:</t>
        <artwork><![CDATA[
W_est = W_est + alpha_cubic * segments_acked / cwnd
]]></artwork>
        <t>where cwnd is the congestion window in effect. While the cubic curve governs, that window is larger than W_est, so the
growth of W_est depends on the trajectory of the other curve. This coupling
cannot be expressed as a function of W_est alone, and A_reno instead inverts the
standalone recurrence, in which the divisor is the Reno-friendly window itself.</t>
        <t>Where A_reno is the smaller of the two curves, cwnd is the Reno-friendly window
and the two formulations coincide exactly: both increase the window by one
segment for every cwnd / alpha_cubic segments acknowledged. They differ only in
where that region is entered. Because the standalone recurrence uses the smaller
divisor, it advances faster while the cubic curve governs, and a Cuback sender
enters the Reno-friendly region somewhat earlier than a sender following
<xref target="CUBIC"/>.</t>
      </section>
      <section anchor="smoothing">
        <name>Smoothing the Cubic Growth</name>
        <t><xref section="4.4" sectionFormat="of" target="CUBIC"/> and <xref section="4.5" sectionFormat="of" target="CUBIC"/> advance cwnd toward a
target one round trip ahead, W_cubic(t + RTT), rather than assigning W_cubic(t) to cwnd directly.
Because the CUBIC curve is driven by elapsed time, the growth owed at an
acknowledgement depends on how long has passed since the previous one, and
assigning the curve directly would turn a gap in acknowledgements into a step in
cwnd, which is a burst. The one-round-trip target, together with the
per-acknowledgement increase of (target - cwnd) / cwnd, spreads one round trip
of the curve across one round trip of acknowledgements, making the increase
proportional to the data acknowledged however the acknowledgements are
distributed in time.</t>
        <t>Cuback needs no such smoothing. D(w) is a function of acknowledged data alone, so
a gap in acknowledgements accrues no growth to be caught up, and the increase is
proportional to the ack stream by construction.</t>
      </section>
      <section anchor="overhead">
        <name>Calculation Overhead</name>
        <t>A_reno is arithmetic, but A_cubic requires a cube root. <xref target="CUBIC"/> evaluates one
when the epoch begins, to obtain K, and thereafter only cubes; Cuback evaluates
one whenever it computes D(w).</t>
        <t>Storing the data still needed to increase the window by one segment, rather than
recomputing D(w) on every acknowledgement, moves the evaluation from once per
acknowledgement to once per increase. Each increase then evaluates three roots:
K, A_cubic(w), and A_cubic(w + 1).</t>
        <t>Calculating a cube root to the accuracy required here is cheap. The
approximation must be continuous in slope, adjacent evaluations being
differenced, and one meeting that condition is given in <xref target="cbrt"/>. It runs in
about nine cycles on contemporary hardware, against roughly nine hundred to
encrypt a 1460-byte segment through an AES-GCM-128 pipeline at 1.6 bytes per
cycle. In the worst case, the window growing by one segment for every segment
acknowledged, the overhead is therefore around three percent of the cost of
encrypting the data that drove it; during congestion avoidance the window
typically grows far more slowly than that.</t>
        <t>Furthermore, K is fixed for the duration of the epoch and could be retained
rather than recomputed, and A(w + 1) for one increase is A(w) for the next and
could be carried forward. Together these leave a single cube root per increase.</t>
      </section>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>TODO Security</t>
    </section>
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="CUBIC">
          <front>
            <title>CUBIC for Fast and Long-Distance Networks</title>
            <author fullname="L. Xu" initials="L." surname="Xu"/>
            <author fullname="S. Ha" initials="S." surname="Ha"/>
            <author fullname="I. Rhee" initials="I." surname="Rhee"/>
            <author fullname="V. Goel" initials="V." surname="Goel"/>
            <author fullname="L. Eggert" initials="L." role="editor" surname="Eggert"/>
            <date month="August" year="2023"/>
            <abstract>
              <t>CUBIC is a standard TCP congestion control algorithm that uses a cubic function instead of a linear congestion window increase function to improve scalability and stability over fast and long-distance networks. CUBIC has been adopted as the default TCP congestion control algorithm by the Linux, Windows, and Apple stacks.</t>
              <t>This document updates the specification of CUBIC to include algorithmic improvements based on these implementations and recent academic work. Based on the extensive deployment experience with CUBIC, this document also moves the specification to the Standards Track and obsoletes RFC 8312. This document also updates RFC 5681, to allow for CUBIC's occasionally more aggressive sending behavior.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9438"/>
          <seriesInfo name="DOI" value="10.17487/RFC9438"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="RENO">
          <front>
            <title>TCP Congestion Control</title>
            <author fullname="M. Allman" initials="M." surname="Allman"/>
            <author fullname="V. Paxson" initials="V." surname="Paxson"/>
            <author fullname="E. Blanton" initials="E." surname="Blanton"/>
            <date month="September" year="2009"/>
            <abstract>
              <t>This document defines TCP's four intertwined congestion control algorithms: slow start, congestion avoidance, fast retransmit, and fast recovery. In addition, the document specifies how TCP should begin transmission after a relatively long idle period, as well as discussing various acknowledgment generation methods. This document obsoletes RFC 2581. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5681"/>
          <seriesInfo name="DOI" value="10.17487/RFC5681"/>
        </reference>
        <reference anchor="RATE-LIMITED">
          <front>
            <title>Increase of the Congestion Window when the Sender Is Rate-Limited</title>
            <author fullname="Michael Welzl" initials="M." surname="Welzl">
              <organization>University of Oslo</organization>
            </author>
            <author fullname="Tom Henderson" initials="T." surname="Henderson">
              <organization>University of Washington</organization>
            </author>
            <author fullname="Gorry Fairhurst" initials="G." surname="Fairhurst">
              <organization>University of Aberdeen</organization>
            </author>
            <author fullname="Mohit P. Tahiliani" initials="M. P." surname="Tahiliani">
              <organization>National Institute of Technology Karnataka</organization>
            </author>
            <date day="6" month="September" year="2026"/>
            <abstract>
              <t>   This document specifies how transport protocols increase their
   congestion window when the sender is rate-limited, and updates RFCs
   4341, 5681, 9002, 9260, and 9438.  Such a limitation can be caused by
   the sending application not supplying data or by receiver flow
   control.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-ccwg-ratelimited-increase-11"/>
        </reference>
        <reference anchor="RFC9002">
          <front>
            <title>QUIC Loss Detection and Congestion Control</title>
            <author fullname="J. Iyengar" initials="J." role="editor" surname="Iyengar"/>
            <author fullname="I. Swett" initials="I." role="editor" surname="Swett"/>
            <date month="May" year="2021"/>
            <abstract>
              <t>This document describes loss detection and congestion control mechanisms for QUIC.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9002"/>
          <seriesInfo name="DOI" value="10.17487/RFC9002"/>
        </reference>
      </references>
    </references>
    <?line 423?>

<section anchor="derivation">
      <name>Derivation of the Increase Function</name>
      <t>The lower bound of two segments in D(w) limits the increase to one half of the
congestion window per round trip: cwnd segments are acknowledged per round trip,
and each one-segment increase consumes at least two of them. It is the
counterpart of the constraint target &lt;= 1.5 * cwnd in <xref section="4.4" sectionFormat="of" target="CUBIC"/>
and <xref section="4.5" sectionFormat="of" target="CUBIC"/>. No lower bound on the increase is needed, as A(w)
is monotonically
increasing and D(w) is therefore always positive.</t>
      <t>CUBIC sets its congestion window to the larger of two window growth functions.
Both are monotonically increasing, so their maximum is monotonically increasing
as well, and the inverse of that maximum is the minimum of the two inverses.
A(w) is therefore obtained by inverting each function separately and taking the
smaller of the two results.</t>
      <t>A_cubic is the inverse of W_cubic(t) of <xref section="4.2" sectionFormat="of" target="CUBIC"/>, multiplied
by bandwidth to express elapsed time as acknowledged data. That the curve is
zero at w = cwnd_epoch follows from the definition of K.</t>
      <t>Sampling bandwidth as cwnd_prior / RTT is the rate at which the flow was
delivering data over the round trip preceding the congestion event. It carries
an identity:</t>
      <artwork><![CDATA[
bandwidth * RTT = cwnd_prior
]]></artwork>
      <t>While the congestion window is at cwnd_prior, one round trip of acknowledgements
advances A(w) by exactly one round trip along the underlying cubic curve.</t>
      <t>A_reno is the inverse of the Reno-friendly increase of <xref section="4.3" sectionFormat="of" target="CUBIC"/>: one segment for every cwnd / alpha_cubic segments acknowledged,
with alpha_cubic replaced by one once the window reaches W_max. Summing those
thresholds over the segment-spaced windows from cwnd_epoch to w yields the
expression in <xref target="ca"/>.</t>
      <t>Differencing A_reno recovers exactly the threshold from which it was built:</t>
      <artwork><![CDATA[
A_reno(w + 1) - A_reno(w) = w / alpha_cubic
]]></artwork>
      <t>The Reno-friendly region is therefore not a separate mechanism in Cuback. It is
the value that D(w) takes wherever A_reno is the smaller of the two curves. The
closed form exists only so that the two curves can be compared.</t>
      <t>Differencing A_cubic eliminates K, so an implementation need not evaluate it
when the cubic curve is the smaller of the two:</t>
      <artwork><![CDATA[
A_cubic(w + 1) - A_cubic(w)
  = bandwidth * (cbrt((w + 1 - W_max) / C) - cbrt((w - W_max) / C))
]]></artwork>
    </section>
    <section anchor="vectors">
      <name>Test Vectors</name>
      <t>A(w) and D(w) are pure functions of the congestion window and the parameters of
<xref target="ca"/>, so they can be checked directly. Both vectors below use the recommended
constants, with alpha_cubic taken as 3 * (1 - beta_cubic) / (1 + beta_cubic)
rather than the rounded 0.529.</t>
      <t>The first exercises the Reno-friendly curve. bandwidth is large enough here that
A_cubic exceeds A_reno at every window shown, so A(w) is A_reno(w) throughout.
The window reaches cwnd_prior at 10 segments, where alpha_cubic is replaced by
one and each further segment costs exactly its own window in acknowledged data.</t>
      <artwork><![CDATA[
cwnd_epoch = 7 segments
cwnd_prior = 10 segments
W_max      = 10 segments
RTT        = 0.1 s
bandwidth  = 100 segments/s

   w      A(w)      D(w)
   7    0.0000   13.2222
   8   13.2222   15.1111
   9   28.3333   17.0000
  10   45.3333   10.0000
  11   55.3333   11.0000
  12   66.3333
]]></artwork>
      <t>The second exercises the cubic curve, the parameters being chosen so that K is
exactly 10 seconds. A_reno exceeds A_cubic at every window shown, so A(w) is
A_cubic(w) throughout. A(W_max) divided by bandwidth recovers K, and the data
needed to climb the 50 segments below W_max equals that needed for the 50 above,
the curve being point-symmetric about W_max.</t>
      <artwork><![CDATA[
cwnd_epoch = 600 segments
cwnd_prior = 1000 segments
W_max      = 1000 segments
RTT        = 0.1 s
bandwidth  = 10000 segments/s
K          = 10 s

      w        A(w)
    600           0
    950      50 000
   1000     100 000
   1050     150 000
   1400     200 000
]]></artwork>
      <t>D(w) on the cubic curve is the difference of two cube roots taken at adjacent
windows, so an implementation using an approximation should compare accumulated
values, as above, rather than individual increases; see <xref target="overhead"/>.</t>
    </section>
    <section anchor="cbrt">
      <name>An Approximation of the Cube Root</name>
      <t>The cube root function below is provided for reference and is placed in the
public domain. It assumes IEEE 754 binary64. Its maximum relative error is about
3.5e-5 and the relative error of its slope is below 8.5e-4, holding each
per-segment increase to roughly 0.1 percent, and it runs in about nine cycles on
a Zen 3 core.</t>
      <artwork><![CDATA[
#define DBL2BITS(x) (((union { double f; uint64_t u; }){x}).u)
#define BITS2DBL(x) (((union { uint64_t u; double f; }){x}).f)

double approx_cbrt(double x)
{
    uint64_t u = DBL2BITS(x);
    uint64_t abs_u = u & 0x7fffffffffffffff;
    uint64_t exp = abs_u >> 52;

    if (abs_u == 0)
        return x;
    if (exp == 0 || exp == 0x7ff)
        return cbrt(x);

    int e = (int)exp - 1023;
    int q = e / 3;
    int r = e - 3 * q;
    if (r < 0) {
        r += 3;
        --q;
    }

    uint64_t mant = abs_u & 0xfffffffffffff;
    double m = BITS2DBL(mant | ((uint64_t)1023 << 52));

    double y = -0.010279630422175424;
    y = 0.08469719299100167 + m * y;
    y = -0.2988437245358902 + m * y;
    y = 0.7177663288981584 + m * y;
    y = 0.5066598330689034 + m * y;

    static const double cbrt2_to_r[3] = {1.0, 1.2599210498948731648,
                                         1.5874010519681994748};
    double two_to_q = BITS2DBL((uint64_t)(q + 1023) << 52);

    y *= cbrt2_to_r[r] * two_to_q;
    return (u >> 63) ? -y : y;
}
]]></artwork>
    </section>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA6183XLjRpbmfT5FTlXEjGSTtKh/qSx75VK5u6JsV48lr2Om
o6MCJCESXSBAI4FisdXq2Ngn2Zu5mDeY632WnZjX2POdczKRAKmyZ2IUUVEk
mEicPP+/GA6Hps7qPL20z17+9M31yzeXlv5//dLeVNmHtLCTja0XqaUf7Mu8
nL5/ZpLJpEo/0PppM0lwYZrU6bysNpfW1TMzK6dFsqT9ZlVyXw/fJ39pFuVw
Ol3Ph3LD8GBs1mX1fl6VzQqPLYt56uqsLCx9rKsytz/Tz1kxt7/DkmcmW1WX
tq4aVx8eHFwcHJr36YZ2mF3arKjTqkjrIT/MrLJL+8e6nA6sK6u6Su8dfdos
8eFPxtVJMXuX5GVBwG1SZ5KmXpTVpbFDY+nvvslzhpy/WXt5af/9X/7F/r9/
+1//8a//W68lbprRM97woezb9w1fL6v5pf02cXW+4e/pMsnySytHL983/2OO
C6NpuTSmKKtlUhNqL43Jivvo22g0MmY4HNpk4uoqmdbG3C0yZwmhzTItautW
6TS7z1JnXzIiBzYpQBg6PJOKjknbNXnCuCzvlZDTgF8zFfyO7GvaLVuuctkO
n1I8Qu4kklfpKk+mIAHv8Q/OLps6meSprbNlSiAWMxM9mVBbp3ad1Qu7aqqU
UFlMsZWz5Ye0ov393au0GqarckrrkopwTdQjEhHYZr3I6GpNgNoP6bQuK2cT
2mlVlR+yWTob2ZZNhuusmJVrSwy0pic2jo4AHnW0YQzVMp0ukiJzSyKb/TEt
ygGda0n70bFcSoAlOfFJU03pfsJWDwtpVZXVyPy8oJ1SsBluS+wimy+G02RF
2Kk3dIp6QWSwRbom6tJRCcO08Rw7FjarnXULHMOVxHWVqQke2xQzWsh4BZ/S
CuJVe5+Xa0e3AwjCZZpUeZbS84UlltlslqfGPLevQcFZw+i1D88zfH00Rkj9
8PB3/OHqx29fXhwfnT8+WmKghCgzS/ONnRFVy006i1hiqCxhk5xEmAi4JFQm
tSFkEObpGG6a5Mkky3FaJiYQSQ/6+sdXP7zFc05Oz8f0nAm2v88KYGnaJ5VR
UiUAhrRANg0sAsynebJyBBZ4C7zZ58iBXZRrEGyA4yxLQqgg6qNljBLx/RPC
toT7NL8nxM0XxOvNHAARNm+aqguhTT6U2SwppinoKGh0KZOIhJYAyIiL63VJ
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
24H1GxEkAoT+DkYH9EcfxkejQ/rDD+ftV3w6GY3pDz9c0L/D89ER/eGHM76X
fhhjg+OT8MNB+GFMX0/aH8bhB+x8eso/tIpVBn17jBapjq0RSJn8mcL6FEHF
veEXuCmRGHnYFW/hEE5rGU/fc/drnBfP8EesRz+rXtFBY9tx54JdapNbMvXT
pqGmpFYn/MNJS7Z44NCPZ/K59D4fv9ItPFE5MK0XKPjgAdCh25C+wJyVlSSJ
mOwdDHka8UyfJQ+eZsqD/xxbdhnzTTwwDBr5Fwys/eVr5VIGr/074GsXJ3qN
/heGEoCsfGiv6bpxtO5Y1x3qOuY+n9R7wlZFr4/TSCkE/86r3DokvfTVEu4J
S9m4tsUoyqdpD4ua4vh9eEbfVcaRAJO8U++gh4H/muiNVu4FITslvykkdR/l
rS7XBWrI0VPVlL3EcX5ELuPhOafZfI+gT3GEsEm4M3PhZcvMkOT3KH70fWqq
UaUX36yaSU44nZVLfofqazTLSKj++tWrV/bs5NhOyL+oNqfH8kpfH/7JUMGH
qEGdmdkcjU7S4UmQq94yvJ+5dpKLbEd4z3HPcVsX5+kT1Da2R0bKkCQEM2si
TcQ4C8lHuyv5aBL7z8QNR2jxSFXanssklb355rvDb17f3e6Rytjb22sKzsBo
36O9f2EbktvT43e1bV7Yx/2Hj4/7o2Y/3I5bD2mP3u3xTe1Wevv9vjF6Ubjt
HTtFeunjvnlgeWr3IHGMwHzR/TWZuHdY0di/twcfz+67f73F5MLTUrnlq6/s
yeELkfHs3u7pRqQr2hd/VCmXtj6+CKt4B1pj//pX6z/jqVv38JkArdyKtDNe
UkIf9nHfkBTB4dGL8OMv9GNKvlB0qeJLQ/aafmkhqOyXBKJ9aB9oP7/y9+Fv
ONTVj6Z7+iX5Z+H4wNYOVCkVlrQu0Jbv+yvR1++0D9jtl18SAvf9CfXGDd04
JFtLK84uTo8Ojg8PxyRKh8ey/YZ18cH58enF2fji8OKCNOP49Iz8vyWdctMu
oj0OL87Pj4/ODo9Pjk7OLw4OtxcdjM7GZ2enp0eH5+cX5+OT8+Nda04OTk9P
Ls6Pjg5OaZujaA0vwhAFdCscWH8KEO/wXV2+q/549Cfa5IGchIEdjw5PLi4O
xwfHF+cXx+dnR+PT4/NB/0UyT/+NRyfnZ8eEmpPxxen5+OLi+Oz4/LGDd1Lj
eOwvMfpbtO/9gpiCcL+vyNcjbOxnVzHM1Z/ofH4r2V+5co/5/pQ2+NoON/YS
WHgUc0OKuPtOW/NwKRMH6ezq2T2Z/PSZzxBHTuXI/H+xlaSSgmEAAA==

-->

</rfc>
