<?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-00" 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-00"/>
    <author fullname="奥 一穂" asciiFullname="Kazuho Oku">
      <organization>Fastly</organization>
      <address>
        <email>kazuhooku@gmail.com</email>
      </address>
    </author>
    <date year="2026" month="September" day="25"/>
    <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>The application-limited clock handling required by <xref section="4.2" sectionFormat="of" target="CUBIC"/> has
no counterpart in Cuback, there being no clock to pause and resume.</t>
        <t>The rules of <xref target="I-D.ietf-ccwg-ratelimited-increase"/>, which update <xref target="CUBIC"/>,
bound the increase of a rate-limited sender without any determination of its
state. Even without them, 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; see
<xref target="clock-timing"/>.</t>
      </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="I-D.ietf-ccwg-ratelimited-increase"/> 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="I-D.ietf-ccwg-ratelimited-increase"/> 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="I-D.ietf-ccwg-ratelimited-increase">
          <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 390?>

<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:
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
/f6plZcPIjubMoGozpDdFy5fGdLBbrbuaIgzQKNyGmLQPQ8ADmA3El5QOdQp
IxJyql3A1wZJyihUj/sCkiBn1UoxNoTQRRYbVUleISIuo+ret1LduyHQEBPA
uK7m98CSs60a6LKGZVZQ1cIlrcG8xSiIbQo6xKqsxMWuQX2gavDJeEqUAsS4
HI7iMu5mpUbEuW4Lbn+4v//m9fB6lJtmyt06VEJiMH1tgCwRWXypRwcLpTj6
RBz5TD7V3nAdf14hnVeZ5dozgw/LgXcV5YdHxFd+MCy9GLjkJGbdkGNLRlYn
NKBQNDY9k7WKewzO0aHJs8JEsWzdklzI8i4y7PIaVmfzklijUuLj8GasUYgH
cYFQjQjZSWYuspo0UeB8DjsY0BpcMGswazdjrQlxIBfg7Bydmkq/e3WlsasD
mKuOXj2wVBrKoN9i7ljY+IW3dy+d8wYCGsbBxGASJUchsY3GVEpSF2tSOIl0
w7BicQ6hexJ5gyp4g1Lpx1odOV91gg4h1lhcC4z3KN071yKAUzB7rUAW0o8u
ex0TkPPYLL6Ym72NVqO8N9pYqQmqfoo6FxUUTL8LMZ2BEbPMDSuYNcfcvc8U
KPwKdCQVa5KP7Jv1XeBfWtMaNywzZsn9J2RBGXOW8zVszkxO3MrFFWnC8gG6
9YUANL2of/RlqfDUJCaxZ7NIPsZUxBS5GHw2GlhJyJnTwySUPwWgJkXBBgad
A9dF4YPUc59Fxg+lMLr4z90mlpBcL6vAKGFDtDjkBmFtzPCKCZ2KWaN/LNU9
FpUCBr581Ul+TalZxwcbLhmWAvM41QF8Ok+KvpvvAgIMT0LC3qm7KF+dVcuG
2OUjUJVKI17fhbNQDt87ekD4F6ZZGYovsX9hwoUCMiiecZMmJNoxsiJ4LBNR
S+lUsh4qFi8AhVUheL4yh0DgiU5PcSG7mwCjYEzFp+Umnj/8ELqgGkJ9EgdY
4CUvCykNofldq966vL9vKvKtSbbpKuolJtIaqdAqbCp7dXW2t7ePZsZWnwzw
ABNFwUcVWQUNarHngSNDxXWVLQhm4x07o62o+KjNFROiHd/02nBzAnMNDeF+
jj5Ga0Ntne7csTtLWLl8/d21krZGG1qygnBwBcYGverFjhRPOs8NAeJ6DRol
nivID4/DJB2XXJkFuAeRi2rtkpN/laWYO/bPlItZqrA3COiskjJRJZsDNCB/
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
vTs8k7uBKeVK1GM51VuWqMyynyEsxd5bjwTL1eLoRlXm+s2xS9RIfMcFUL4I
R246qWLuQpjUjXSrUYYV9FsywZJtiR3Z6TotOGeHEJkFyEWCeQ6wJyvKDLpr
PNTOA9xFs+agcziYA/uZ1uslBn7jw+O9IYbDvoVYmoDoDuzLm+Fvr74bjvdP
9TJfGmoHB6jHo2MJoZHGBA1dZiMWq2rMmtKVkYjlUNI58u70KweHRZ6oTjDC
TqMTXHamJLBKRIcSdwAYRALfaoau9tQdsyMfXDHGq/iUYs0e78+OwFfNepmn
dFeF8y3TpI7rolpuzSeYh3vV1ggmvh5wlxB3Q/avwDpoQ0tRSmZv4u4rQnQX
G3snmY6ZfMMtLoxIjbQlVxzdjtRAiUbXb8BVS4IJvRBgemcKKSPGeUA0rlgm
MJEQdQQXa+o36PVhcvgK+B6c1jpxiWArb7BZ4+31Wz+SWudfX35/uTklT8rk
oX/TQNIHNIPvglv3Kw50/xpWu/b9UQ6prx0uXjl7df806qLiIsKn6py51Dkp
ALVda0RazHD+/dG7gN2y5zn7ZMEHr3vd170qKUUHFCqi7+LExUOApo7u62NV
0mAtAYFnWBauC5ThCj0toRHTUo6sEUcIO5jH4Kk+88mGx9xb9Sn3dqS/r/r3
JnpGXOwStXtSQod+fQLivqpk8VLRRV+6pBQ64p3cFyssZywrqkqQ7yK5q4bv
2m29Ee+j/9oRunvL3F8cBWcZYy0kTwew6AayC39zLAGDjWgXun+MaLSSa4qx
U0PJTe1uwEeLUCExL+lrFFLKDADucgMf7FZwbofDX8QdcY531aL76wSE9y7V
lvgVU2AFpe+cB5TbPtxRtEGNTttLPOAhwEo5JfUVgBf1R1Quyu+mwxO76VOi
QXYZRolaFLZdUkVfGgil28xVsH3mM/N33BCsN+gvYaWdDJEHJum0+n2JYZY7
8mZPtisbu24lXIrsSuW87si3X+JdmWzLpXWpJL5uXPuIov4pQ12yrgM5ugeB
IF3EnbrciR8C581sD6mGqL/9M+IO5SNz7ldZuwTERmzqu1qp0E/Zuzh4H8V+
9QbL92P2OL7q59FU1IS6zWv43DTHQHFZPBon93H8Faqqa/LlppTlHseRvmkX
C/9zGcpf3bGB8LLx0C5pWddt4ru0Q0vkivOMrKFD+29oQMXf1XG+I24q2JSe
UuvpQjLrbzTRThIAc4/VpM0Ll1x0bUf+ko6/K3MBAHVwyOz1foNSIRcU9A/l
tr2Gie5A+Q5KMUdUzOS+BlJ7pNq5F4bSTYjGz0yuSa8BtqeQC7MAhEBYK50+
VtoCu3PcvXv0oZKaLsX2UMxsEf0sxxvXq9e7l0i/VYHndkEK1snCXZden97W
g3iaxLELEcUFN0r370K5S08wtHvxCbMR2y9EER3BP3qPadN/lNv390/lHv6D
XNHyhpZ+H6z3c2OPdXX5nzoIzfYgrsy+zkKuPdLl5wV8SkqTlXW/B8DlN5eh
iu5kKH+JQ3oCYwFG3sEU2GdfwYidaa+pASq6yyF9JdMcwxf5lQWzLcUo2evO
dZ5OR5nPnXoDau5SSqwIe2NekrSXuxqLV4tDn2AetQjqcCVjRPD1lFNkuDAu
2/PaT348o4MwahnwSo9SC97LnHLQ4lUshlBBz6BfhdefQylh00wzR0eK7kKf
eHBUBOhFDKfcA5BrMfELtHnRfZmxtpFJpLFh8JeWLt+teHi4d3jNggSAwN/e
aA/+4MP4YLQPf/jiNHzFT0ejMfzhizP4t386OoA/fHFCc+HFGBc4PPIv9vyL
MXw9Ci/G/gWufHxML4Ji5ftaPUaLVMfGTRbuP0/R+pRexb2h3+ERIhHycFW8
TM2cFhhPfq7o1zgvvooZsR68Fr0i98V0x53zdikkt4gnVEhDpaBWJ/TiKJAt
vjfibtnQuWSei19hCl2MGajgBTI+6B7P0K5BX4BnkmpOkrDJ3sKQxxHP9Fly
73Gm3PvfsWWXMd/E976QRu6e6Mo9vhQuJfDC3x49OzuSZ/A/MxQDpPlDeCbj
xtG4Qxm3L+OI+1xS7xFbFf0KkERKPvi3TuU2PuklN4TtI5aytaEfKcqnScOL
mOL4Z42U/OQMRQJE8k69AzZD/mujHyax1O8PfpNP6j7w5fzLEivL0a5iyq7w
OO8wl3H/lNJsrqHQpTh82MTcmVv/m5nEkOD3CH7kZ3FEo3Ljvlq2kwJwmlUL
+im819hZw6H665cvX+qTo0M9Af+iXh8f8i8zuvCPbyDcRt3sxMzqYHRkhkde
rnrD+HYH5yLDTaxTnHMY6uL0QwlY29hIJODVbkkSIjNLIo3FOPfJR70t+agS
/U/ADQfY+GFE2p7yXUt9/eLb/Rev39/sgMrY2dlpS8rASJOknj7XLcjt8eGH
RrfP9cPu/d3D7qjd9dNx6j6s0ZseTwpLyfTprlLykLntAzlF8uhuV92TPIU1
QBwjMJ933yYT+wFHtPrv9d7dybT71xsMLjwM5Slff62P9p+zjOdTvSMLga4I
97drQ6Wtu+d+FK0AY/Rf/qLdZ9x1Yw6dCaHlqZh2xrvm8GEX5w1BEewfPPcv
f4GXBnyh6FFNj4bkNf0SIKj1VwCivg8b6i8u3Dz8Gw5l9IPqnn4B/pk/PmJr
C6qECgsY52lL8/4C9HUr7SLs+quvAIG77oQycQ0Th2BrYcTJ2fHB3uH+/hhE
af+Ql1+TLt47PTw+Oxmf7Z+dgWYcH5+A/7eAU67DIFhj/+z09PDgZP/w6ODo
9Gxvf3PQ3uhkfHJyfHywf3p6djo+Oj3cNuZo7/j46Oz04GDvGJY5iMbQILxx
gboVHVh3CiTe/oem+lD/6eAnWOQenISBHo/2j87O9sd7h2enZ4enJwfj48PT
Qf/3AB7/G4+OTk8OATVH47Pj0/HZ2eHJ4elDB++gxnHbX2L0B7Tv/IIxBeB+
V5AvR1jrZxcxzPVPcD63FK8vXLlDfH8MC3yjh2t9jlh4YHMDirj704Tq/pyv
J5js4skUTL554jLEkVM5Uv8Dtit/DklbAAA=

-->

</rfc>
