<?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.23 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-ccwg-bbr-02" category="exp" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.27.0 -->
  <front>
    <title abbrev="BBR">BBR Congestion Control</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-ccwg-bbr-02"/>
    <author initials="N." surname="Cardwell" fullname="Neal Cardwell" role="editor">
      <organization>Google</organization>
      <address>
        <email>ncardwell@google.com</email>
      </address>
    </author>
    <author initials="I." surname="Swett" fullname="Ian Swett" role="editor">
      <organization>Google</organization>
      <address>
        <email>ianswett@google.com</email>
      </address>
    </author>
    <author initials="J." surname="Beshay" fullname="Joseph Beshay" role="editor">
      <organization>Meta</organization>
      <address>
        <email>jbeshay@meta.com</email>
      </address>
    </author>
    <date year="2024" month="October" day="16"/>
    <area>IETF</area>
    <workgroup>CCWG</workgroup>
    <keyword>Congestion Control</keyword>
    <abstract>
      <?line 190?>

<t>This document specifies the BBR congestion control algorithm. BBR ("Bottleneck
Bandwidth and Round-trip propagation time") uses recent measurements of a
transport connection's delivery rate, round-trip time, and packet loss rate
to build an explicit model of the network path. BBR then uses this model to
control both how fast it sends data and the maximum volume of data it allows
in flight in the network at any time. Relative to loss-based congestion control
algorithms such as Reno <xref target="RFC5681"/> or CUBIC <xref target="RFC9438"/>, BBR offers
substantially higher throughput for bottlenecks
with shallow buffers or random losses, and substantially lower queueing delays
for bottlenecks with deep buffers (avoiding "bufferbloat"). BBR can be
implemented in any transport protocol that supports packet-delivery
acknowledgment. Thus far, open source implementations are available
for TCP <xref target="RFC9293"/> and QUIC <xref target="RFC9000"/>. This document
specifies version 3 of the BBR algorithm, BBRv3.</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/ietf-wg-ccwg/draft-cardwell-ccwg-bbr"/>.</t>
    </note>
  </front>
  <middle>
    <?line 208?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The Internet has traditionally used loss-based congestion control algorithms
like Reno (<xref target="Jac88"/>, <xref target="Jac90"/>, <xref target="WS95"/>  <xref target="RFC5681"/>) and CUBIC (<xref target="HRX08"/>,
<xref target="RFC9438"/>). These algorithms worked well for many years because
they were sufficiently well-matched to the prevalent range of bandwidth-delay
products and degrees of buffering in Internet paths. As the Internet has
evolved, loss-based congestion control is increasingly problematic in several
important scenarios:</t>
      <ol spacing="normal" type="1"><li>
          <t>Shallow buffers: In shallow buffers, packet loss can happen even when a link
  has low utilization. With high-speed, long-haul links employing commodity
  switches with shallow buffers, loss-based congestion control can cause abysmal
  throughput because it overreacts, making large multiplicative decreases in
  sending rate upon packet loss (by 50% in Reno <xref target="RFC5681"/> or 30%
  in CUBIC <xref target="RFC9438"/>), and only slowly growing its sending rate
  thereafter. This can happen even if the packet loss arises from transient
  traffic bursts when the link is mostly idle.</t>
        </li>
        <li>
          <t>Deep buffers: At the edge of today's Internet, loss-based congestion control
  can cause the problem of  "bufferbloat", by repeatedly filling deep buffers
  in last-mile links and causing high queuing delays.</t>
        </li>
        <li>
          <t>Dynamic traffic workloads: With buffers of any depth, dynamic mixes of
  newly-entering flows or flights of data from recently idle flows can cause
  frequent packet loss. In such scenarios loss-based congestion control can
  fail to maintain its fair share of bandwidth, leading to poor application
  performance.</t>
        </li>
      </ol>
      <t>In both the shallow-buffer (1.) or dynamic-traffic (3.) scenarios mentioned
above it is difficult to achieve full throughput with loss-based congestion
control in practice: for CUBIC, sustaining 10Gbps over 100ms RTT needs a
packet loss rate below 0.000003% (i.e., more than 40 seconds between packet losses),
and over a 100ms RTT path a more feasible loss rate like 1% can only sustain
at most 3 Mbps <xref target="RFC9438"/>. These limitations apply no matter what
the bottleneck link is capable of or what the connection's fair share
is. Furthermore, failure to reach the fair share can cause poor throughput
and poor tail latency for latency-sensitive applications.</t>
      <t>The BBR ("Bottleneck Bandwidth and Round-trip propagation time") congestion
control algorithm is a model-based algorithm that takes an approach different
from loss-based congestion control: BBR uses recent measurements of a transport
connection's delivery rate,  round-trip time, and packet loss rate to build
an explicit model of the network path, including its estimated available
bandwidth, bandwidth-delay product, and the maximum volume of data that the
connection can place in-flight in the network without causing excessive queue
pressure. It then uses this model in order to guide its control behavior
in seeking high throughput and low queue pressure.</t>
      <t>This document describes the current version of the BBR algorithm, BBRv3.
The original version of the algorithm, BBRv1, was described previously at a
high level <xref target="CCGHJ16"/><xref target="CCGHJ17"/>. The implications of BBR
in allowing high utilization of high-speed networks with shallow buffers
have been discussed in other work <xref target="MM19"/>. Active work on the BBR
algorithm is continuing.</t>
      <t>This document is organized as follows. Section 2 provides various definitions
that will be used throughout this document. Section 3 provides an overview
of the design of the BBR algorithm, and section 4 describes the BBR algorithm
in detail, including BBR's network path model, control parameters, and state
machine. Section 5 describes the implementation status, section 6 describes
security considerations, section 7 notes that there are no IANA considerations,
and section 8 closes with Acknowledgments.</t>
    </section>
    <section anchor="terminology">
      <name>Terminology</name>
      <t>This document defines state variables and constants for the BBR algorithm.</t>
      <t>Variables for connection state (C), per-packet state (P), or per-ACK rate
sample (rs) that are not defined below are defined in
<xref target="delivery-rate-samples"/>, "Delivery Rate Samples".</t>
      <t>In this document, "acknowledged" or "delivered" data means any transmitted
data that the remote transport endpoint has confirmed that it has received,
e.g., via a QUIC ACK Range <xref target="RFC9000"/>, TCP cumulative acknowledgment
<xref target="RFC793"/>, or TCP SACK ("Selective Acknowledgment") block <xref target="RFC2018"/>.</t>
      <section anchor="transport-connection-state">
        <name>Transport Connection State</name>
        <t>C.delivered: The total amount of data (tracked in octets or in packets)
delivered so far over the lifetime of the transport connection C.</t>
        <t>SMSS: The Sender Maximum Segment Size.</t>
        <t>is_cwnd_limited: True if the connection has fully utilized its cwnd at any
point in the last packet-timed round trip.</t>
        <t>InitialCwnd: The initial congestion window set by the transport protocol
implementation for the connection at initialization time.</t>
      </section>
      <section anchor="per-packet-state">
        <name>Per-Packet State</name>
        <t>packet.delivered: C.delivered when the given packet was sent by transport
connection C.</t>
        <t>packet.departure_time: The earliest pacing departure time for the given packet.</t>
        <t>packet.tx_in_flight: The volume of data that was estimated to be in flight
at the time of the transmission of the packet.</t>
      </section>
      <section anchor="per-ack-rate-sample-state">
        <name>Per-ACK Rate Sample State</name>
        <t>rs.delivered: The volume of data delivered between the transmission of the
packet that has just been ACKed and the current time.</t>
        <t>rs.delivery_rate: The delivery rate (aka bandwidth) sample obtained from
the packet that has just been ACKed.</t>
        <t>rs.rtt: The RTT sample calculated based on the most recently-sent segment
of the segments that have just been ACKed.</t>
        <t>rs.newly_acked: The volume of data cumulatively or selectively acknowledged
upon the ACK that was just received. (This quantity is referred to as
"DeliveredData" in <xref target="RFC6937"/>.)</t>
        <t>rs.newly_lost: The volume of data newly marked lost upon the ACK that was
just received.</t>
        <t>rs.tx_in_flight: The volume of data that was estimated to be in flight at
the time of the transmission of the packet that has just been ACKed (the
most recently sent segment among segments ACKed by the ACK that was just
received).</t>
        <t>rs.lost: The volume of data that was declared lost between the transmission
and acknowledgement of the packet that has just been ACKed (the most recently
sent segment among segments ACKed by the ACK that was just received).</t>
      </section>
      <section anchor="output-control-parameters">
        <name>Output Control Parameters</name>
        <t>cwnd: The transport sender's congestion window, which limits the amount of
data in flight.</t>
        <t>BBR.pacing_rate: The current pacing rate for a BBR flow, which controls
inter-packet spacing.</t>
        <t>BBR.send_quantum: The maximum size of a data aggregate scheduled and transmitted
together.</t>
      </section>
      <section anchor="pacing-state-and-parameters">
        <name>Pacing State and Parameters</name>
        <t>BBR.pacing_gain: The dynamic gain factor used to scale BBR.bw to produce
BBR.pacing_rate.</t>
        <t>BBRPacingMarginPercent: The static discount factor of 1% used to scale BBR.bw
to produce BBR.pacing_rate.</t>
        <t>BBR.next_departure_time: The earliest pacing departure time for the next
packet BBR schedules for transmission.</t>
        <t>BBRStartupPacingGain: A constant specifying the minimum gain value for
calculating the pacing rate that will allow the sending rate to double each
round (4 * ln(2) ~= 2.77) <xref target="BBRStartupPacingGain"/>; used in
Startup mode for BBR.pacing_gain.</t>
        <t>BBRDrainPacingGain: A constant specifying the pacing gain value used in
Drain mode, to attempt to drain the estimated queue at the bottleneck link
in one round-trip or less. As noted in <xref target="BBRDrainPacingGain"/>, any
value at or below 1 / BBRStartupCwndGain = 1 / 2 = 0.5 will theoretically
achieve this. BBR uses the value 0.35, which has been shown to offer good
performance when compared with other alternatives.</t>
      </section>
      <section anchor="cwnd-state-and-parameters">
        <name>cwnd State and Parameters</name>
        <t>BBR.cwnd_gain: The dynamic gain factor used to scale the estimated BDP to
produce a congestion window (cwnd).</t>
        <t>BBRDefaultCwndGain: A constant specifying the minimum gain value that allows
the sending rate to double each round (2) <xref target="BBRStartupCwndGain"/>.
Used by default in most phases for BBR.cwnd_gain.</t>
      </section>
      <section anchor="general-algorithm-state">
        <name>General Algorithm State</name>
        <t>BBR.state: The current state of a BBR flow in the BBR state machine.</t>
        <t>BBR.round_count: Count of packet-timed round trips elapsed so far.</t>
        <t>BBR.round_start: A boolean that BBR sets to true once per packet-timed round
trip, on ACKs that advance BBR.round_count.</t>
        <t>BBR.next_round_delivered: packet.delivered value denoting the end of a
packet-timed round trip.</t>
        <t>BBR.idle_restart: A boolean that is true if and only if a connection is
restarting after being idle.</t>
      </section>
      <section anchor="core-algorithm-design-parameters">
        <name>Core Algorithm Design Parameters</name>
        <t>BBRLossThresh: The maximum tolerated per-round-trip packet loss rate when
probing for bandwidth (the default is 2%).</t>
        <t>BBRBeta: The default multiplicative decrease to make upon each round trip
during which the connection detects packet loss (the value is 0.7).</t>
        <t>BBRHeadroom: The multiplicative factor to apply to BBR.inflight_longterm when
calculating a volume of free headroom to try to leave unused in the path
(e.g. free space in the bottleneck buffer or free time slots in the bottleneck
link) that can be used by cross traffic (the value is 0.15).</t>
        <t>BBRMinPipeCwnd: The minimal cwnd value BBR targets, to allow pipelining with
endpoints that follow an "ACK every other packet" delayed-ACK policy:
4 * SMSS.</t>
      </section>
      <section anchor="network-path-model-parameters">
        <name>Network Path Model Parameters</name>
        <section anchor="data-rate-network-path-model-parameters">
          <name>Data Rate Network Path Model Parameters</name>
          <t>The data rate model parameters together estimate both the sending rate required
to reach the full bandwidth available to the flow (BBR.max_bw), and the maximum
pacing rate control parameter that is consistent with the queue pressure
objective (BBR.bw).</t>
          <t>BBR.max_bw: The windowed maximum recent bandwidth sample, obtained using
the BBR delivery rate sampling algorithm in <xref target="delivery-rate-samples"/>,
measured during the current or previous bandwidth probing cycle (or during
Startup, if the flow is still in that state). (Part of the long-term
model.)</t>
          <t>BBR.bw_shortterm: The short-term maximum sending bandwidth that the algorithm
estimates is safe for matching the current network path delivery rate, based
on any loss signals in the current bandwidth probing cycle. This is generally
lower than max_bw. (Part of the short-term model.)</t>
          <t>BBR.bw: The maximum sending bandwidth that the algorithm estimates is
appropriate for matching the current network path delivery rate, given all
available signals in the model, at any time scale. It is the min() of max_bw
and bw_shortterm.</t>
        </section>
        <section anchor="data-volume-network-path-model-parameters">
          <name>Data Volume Network Path Model Parameters</name>
          <t>The data volume model parameters together estimate both the volume of in-flight
data required to reach the full bandwidth available to the flow
(BBR.max_inflight), and the maximum volume of data that is consistent with the
queue pressure objective (cwnd).</t>
          <t>BBR.min_rtt: The windowed minimum round-trip time sample measured over the
last MinRTTFilterLen = 10 seconds. This attempts to estimate the two-way
propagation delay of the network path when all connections sharing a bottleneck
are using BBR, but also allows BBR to estimate the value required for a BBR.bdp
estimate that allows full throughput if there are legacy loss-based Reno
or CUBIC flows sharing the bottleneck.</t>
          <t>BBR.bdp: The estimate of the network path's BDP (Bandwidth-Delay Product),
computed as: BBR.bdp = BBR.bw * BBR.min_rtt.</t>
          <t>BBR.extra_acked: A volume of data that is the estimate of the recent degree
of aggregation in the network path.</t>
          <t>BBR.offload_budget: The estimate of the minimum volume of data necessary
to achieve full throughput when using sender (TSO/GSO)  and receiver (LRO,
GRO) host offload mechanisms.</t>
          <t>BBR.max_inflight: The estimate of the volume of in-flight data required to
fully utilize the bottleneck bandwidth available to the flow, based on the
BDP estimate (BBR.bdp), the aggregation estimate (BBR.extra_acked), the offload
budget (BBR.offload_budget), and BBRMinPipeCwnd.</t>
          <t>BBR.inflight_longterm: The long-term maximum volume of in-flight data that the
algorithm estimates will produce acceptable queue pressure, based on signals
in the current or previous bandwidth probing cycle, as measured by loss. That
is, if a flow is probing for bandwidth, and observes that sending a particular
volume of in-flight data causes a loss rate higher than the loss rate
objective, it sets inflight_longterm to that volume of data. (Part of the long-term
model.)</t>
          <t>BBR.inflight_shortterm: Analogous to BBR.bw_shortterm, the short-term maximum
volume of in-flight data that the algorithm estimates is safe for matching the
current network path delivery process, based on any loss signals in the current
bandwidth probing cycle. This is generally lower than max_inflight or
inflight_longterm. (Part of the short-term model.)</t>
        </section>
      </section>
      <section anchor="state-for-responding-to-congestion">
        <name>State for Responding to Congestion</name>
        <t>BBR.bw_latest: a 1-round-trip max of delivered bandwidth (rs.delivery_rate).</t>
        <t>BBR.inflight_latest: a 1-round-trip max of delivered volume of data
(rs.delivered).</t>
      </section>
      <section anchor="estimating-bbrmaxbw">
        <name>Estimating BBR.max_bw</name>
        <t>BBR.MaxBwFilter: The filter for tracking the maximum recent rs.delivery_rate
sample, for estimating BBR.max_bw.</t>
        <t>MaxBwFilterLen: The filter window length for BBR.MaxBwFilter = 2 (representing
up to 2 ProbeBW cycles, the current cycle and the previous full cycle).</t>
        <t>BBR.cycle_count: The virtual time used by the BBR.max_bw filter window. Note
that BBR.cycle_count only needs to be tracked with a single bit, since the
BBR.MaxBwFilter only needs to track samples from two time slots: the previous
ProbeBW cycle and the current ProbeBW cycle.</t>
      </section>
      <section anchor="estimating-bbrextraacked">
        <name>Estimating BBR.extra_acked</name>
        <t>BBR.extra_acked_interval_start: the start of the time interval for estimating
the excess amount of data acknowledged due to aggregation effects.</t>
        <t>BBR.extra_acked_delivered: the volume of data marked as delivered since
BBR.extra_acked_interval_start.</t>
        <t>BBR.ExtraACKedFilter: the max filter tracking the recent maximum degree of
aggregation in the path.</t>
        <t>BBRExtraAckedFilterLen = The window length of the BBR.ExtraACKedFilter max
filter window in steady-state: 10 (in units of packet-timed round trips).</t>
      </section>
      <section anchor="startup-parameters-and-state">
        <name>Startup Parameters and State</name>
        <t>BBR.full_bw_reached: A boolean that records whether BBR estimates that it
has ever fully utilized its available bandwidth over the lifetime of the
connection.</t>
        <t>BBR.full_bw_now: A boolean that records whether BBR estimates that it has
fully utilized its available bandwidth since it most recetly started looking.</t>
        <t>BBR.full_bw: A recent baseline BBR.max_bw to estimate if BBR has "filled
the pipe" in Startup.</t>
        <t>BBR.full_bw_count: The number of non-app-limited round trips without large
increases in BBR.full_bw.</t>
      </section>
      <section anchor="probertt-and-minrtt-parameters-and-state">
        <name>ProbeRTT and min_rtt Parameters and State</name>
        <section anchor="parameters-for-estimating-bbrminrtt">
          <name>Parameters for Estimating BBR.min_rtt</name>
          <t>BBR.min_rtt_stamp: The wall clock time at which the current BBR.min_rtt sample
was obtained.</t>
          <t>MinRTTFilterLen: A constant specifying the length of the BBR.min_rtt min
filter window, MinRTTFilterLen is 10 secs.</t>
        </section>
        <section anchor="parameters-for-scheduling-probertt">
          <name>Parameters for Scheduling ProbeRTT</name>
          <t>BBRProbeRTTCwndGain = A constant specifying the gain value for calculating the
cwnd during ProbeRTT: 0.5 (meaning that ProbeRTT attempts to reduce in-flight
data to 50% of the estimated BDP).</t>
          <t>ProbeRTTDuration: A constant specifying the minimum duration for which ProbeRTT
state holds inflight to BBRMinPipeCwnd or fewer packets: 200 ms.</t>
          <t>ProbeRTTInterval: A constant specifying the minimum time interval between
ProbeRTT states: 5 secs.</t>
          <t>BBR.probe_rtt_min_delay: The minimum RTT sample recorded in the last
ProbeRTTInterval.</t>
          <t>BBR.probe_rtt_min_stamp: The wall clock time at which the current
BBR.probe_rtt_min_delay sample was obtained.</t>
          <t>BBR.probe_rtt_expired: A boolean recording whether the BBR.probe_rtt_min_delay
has expired and is due for a refresh with an application idle period or a
transition into ProbeRTT state.</t>
          <t>The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to
be interpreted as described in <xref target="RFC2119"/>.</t>
        </section>
      </section>
    </section>
    <section anchor="design-overview">
      <name>Design Overview</name>
      <section anchor="high-level-design-goals">
        <name>High-Level Design Goals</name>
        <t>The high-level goal of BBR is to achieve both:</t>
        <ol spacing="normal" type="1"><li>
            <t>The full throughput (or approximate fair share thereof) available to a flow  </t>
            <ul spacing="normal">
              <li>
                <t>Achieved in a fast and scalable manner
(using bandwidth in O(log(BDP)) time).</t>
              </li>
              <li>
                <t>Achieved with average packet loss rates of up to 1%.</t>
              </li>
            </ul>
          </li>
          <li>
            <t>Low queue pressure (low queuing delay and low packet loss).</t>
          </li>
        </ol>
        <t>These goals are in tension: sending faster improves the odds of achieving
(1) but reduces the odds of achieving (2), while sending slower improves
the odds of achieving (2) but reduces the odds of achieving (1). Thus the
algorithm cannot maximize throughput or minimize queue pressure independently,
and must jointly optimize both.</t>
        <t>To try to achieve these goals, and seek an operating point with high throughput
and low delay <xref target="K79"/> <xref target="GK81"/>, BBR aims to adapt its sending process to
match the network delivery process, in two dimensions:</t>
        <ol spacing="normal" type="1"><li>
            <t>data rate: the rate at which the flow sends data should ideally match the
  rate at which the network delivers the flow's data (the available bottleneck
  bandwidth)</t>
          </li>
          <li>
            <t>data volume: the amount of unacknowledged data in flight in the network
  should ideally match the bandwidth-delay product (BDP) of the path</t>
          </li>
        </ol>
        <t>Both the control of the data rate (via the pacing rate) and data volume
(directly via the congestion window or cwnd; and indirectly via the pacing
rate) are important. A mismatch in either dimension can cause the sender to
fail to meet its high-level design goals:</t>
        <ol spacing="normal" type="1"><li>
            <t>volume mismatch: If a sender perfectly matches its sending rate to the
  available bandwidth, but its volume of in-flight data exceeds the BDP, then
  the sender can maintain a large standing queue, increasing network latency
  and risking packet loss.</t>
          </li>
          <li>
            <t>rate mismatch: If a sender's volume of in-flight data matches the BDP
  perfectly but its sending rate exceeds the available bottleneck bandwidth
  (e.g. the sender transmits a BDP of data in an unpaced fashion, at the
  sender's link rate), then up to a full BDP of data can burst into the
  bottleneck queue, causing high delay and/or high loss.</t>
          </li>
        </ol>
      </section>
      <section anchor="algorithm-overview">
        <name>Algorithm Overview</name>
        <t>Based on the rationale above, BBR tries to spend most of its time matching
its sending process (data rate and data volume) to the network path's delivery
process. To do this, it explores the 2-dimensional control parameter space
of (1) data rate ("bandwidth" or "throughput") and (2) data volume ("in-flight
data"), with a goal of finding the maximum values of each control parameter
that are consistent with its objective for queue pressure.</t>
        <t>Depending on what signals a given network path manifests at a given time,
the objective for queue pressure is measured in terms of the most strict
among:</t>
        <ul spacing="normal">
          <li>
            <t>the amount of data that is estimated to be queued in the bottleneck buffer
(data_in_flight - estimated_BDP): the objective is to maintain this amount
at or below 1.5 * estimated_BDP</t>
          </li>
          <li>
            <t>the packet loss rate: the objective is a maximum per-round-trip packet loss
rate of BBRLossThresh=2% (and an average packet loss rate considerably lower)</t>
          </li>
        </ul>
      </section>
      <section anchor="state-machine-overview">
        <name>State Machine Overview</name>
        <t>BBR varies its control parameters with a state machine that aims for high
throughput, low latency, low loss, and an approximately fair sharing of
bandwidth, while maintaining an up-to-date model of the network path.</t>
        <t>A BBR flow starts in the Startup state, and ramps up its sending rate quickly,
to rapidly estimate the maximum available bandwidth (BBR.max_bw). When it
estimates the bottleneck bandwidth has been fully utilized, it enters the
Drain state to drain the estimated queue. In steady state a BBR flow mostly
uses the ProbeBW states, to periodically briefly send faster to probe for
higher capacity and then briefly send slower to try to drain any resulting
queue. If needed, it briefly enters the ProbeRTT state, to lower the sending
rate to probe for lower BBR.min_rtt samples. The detailed behavior for each
state is described below.</t>
      </section>
      <section anchor="network-path-model-overview">
        <name>Network Path Model Overview</name>
        <section anchor="high-level-design-goals-for-the-network-path-model">
          <name>High-Level Design Goals for the Network Path Model</name>
          <t>At a high level, the BBR model is trying to reflect two aspects of the network
path:</t>
          <ul spacing="normal">
            <li>
              <t>Model what's required for achieving full throughput: Estimate the data rate
(BBR.max_bw) and data volume (BBR.max_inflight) required to fully utilize the
fair share of the bottleneck bandwidth available to the flow. This
incorporates estimates of the maximum available bandwidth, the BDP of the
path, and the requirements of any offload features on the end hosts or
mechanisms on the network path that produce aggregation effects.</t>
            </li>
            <li>
              <t>Model what's permitted for achieving low queue pressure: Estimate the maximum
data rate (BBR.bw) and data volume (cwnd) consistent with the queue pressure
objective, as measured by the estimated degree of queuing and packet loss.</t>
            </li>
          </ul>
          <t>Note that those two aspects are in tension: the highest throughput is available
to the flow when it sends as fast as possible and occupies as many bottleneck
buffer slots as possible; the lowest queue pressure is achieved by the flow
when it sends as slow as possible and occupies as few bottleneck buffer slots
as possible. To resolve the tension, the algorithm aims to achieve the maximum
throughput achievable while still meeting the queue pressure objective.</t>
        </section>
        <section anchor="time-scales-for-the-network-model">
          <name>Time Scales for the Network Model</name>
          <t>At a high level, the BBR model is trying to reflect the properties of the
network path on two different time scales:</t>
          <section anchor="long-term-model">
            <name>Long-term model</name>
            <t>One goal is for BBR to maintain high average utilization of the fair share
of the available bandwidth, over long time intervals. This requires estimates
of the path's data rate and volume capacities that are robust over long time
intervals. This means being robust to congestion signals that may be noisy
or may reflect short-term congestion that has already abated by the time
an ACK arrives. This also means providing a robust history of the best
recently-achievable performance on the path so that the flow can quickly and
robustly aim to re-probe that level of performance whenever it decides to probe
the capacity of the path.</t>
          </section>
          <section anchor="short-term-model">
            <name>Short-term model</name>
            <t>A second goal of BBR is to react to every congestion signal, including loss,
as if it may indicate a persistent/long-term increase in congestion and/or
decrease in the bandwidth available to the flow, because that may indeed
be the case.</t>
          </section>
          <section anchor="time-scale-strategy">
            <name>Time Scale Strategy</name>
            <t>BBR sequentially alternates between spending most of its time using short-term
models to conservatively respect all congestion signals in case they represent
persistent congestion, but periodically using its long-term model to robustly
probe the limits of the available path capacity in case the congestion has
abated and more capacity is available.</t>
          </section>
        </section>
      </section>
      <section anchor="control-parameter-overview">
        <name>Control Parameter Overview</name>
        <t>BBR uses its model to control the connection's sending behavior. Rather than
using a single control parameter, like the cwnd parameter that limits the
volume of in-flight data in the Reno and CUBIC congestion control algorithms,
BBR uses three distinct control parameters:</t>
        <ol spacing="normal" type="1"><li>
            <t>pacing rate: the maximum rate at which BBR sends data.</t>
          </li>
          <li>
            <t>send quantum: the maximum size of any aggregate that the transport sender
  implementation may need to transmit as a unit to amortize per-packet
  transmission overheads.</t>
          </li>
          <li>
            <t>cwnd: the maximum volume of data BBR allows in-flight in the network at any
  time.</t>
          </li>
        </ol>
      </section>
      <section anchor="environment-and-usage">
        <name>Environment and Usage</name>
        <t>BBR is a congestion control algorithm that is agnostic to transport-layer
and link-layer technologies, requires only sender-side changes, and does
not require changes in the network. Open source implementations of BBR are
available for the TCP <xref target="RFC9293"/> and QUIC <xref target="RFC9000"/> transport
protocols, and these implementations have been used in production
for a large volume of Internet traffic. An open source implementation of
BBR is also available for DCCP <xref target="RFC4340"/>  <xref target="draft-romo-iccrg-ccid5"/>.</t>
      </section>
    </section>
    <section anchor="detailed-algorithm">
      <name>Detailed Algorithm</name>
      <section anchor="state-machine">
        <name>State Machine</name>
        <t>BBR implements a state machine that uses the network path model to guide
its decisions, and the control parameters to enact its decisions.</t>
        <section anchor="state-transition-diagram">
          <name>State Transition Diagram</name>
          <t>The following state transition diagram summarizes the flow of control and
the relationship between the different states:</t>
          <artwork><![CDATA[
             |
             V
    +---> Startup  ------------+
    |        |                 |
    |        V                 |
    |     Drain  --------------+
    |        |                 |
    |        V                 |
    +---> ProbeBW_DOWN  -------+
    | ^      |                 |
    | |      V                 |
    | |   ProbeBW_CRUISE ------+
    | |      |                 |
    | |      V                 |
    | |   ProbeBW_REFILL  -----+
    | |      |                 |
    | |      V                 |
    | |   ProbeBW_UP  ---------+
    | |      |                 |
    | +------+                 |
    |                          |
    +---- ProbeRTT <-----------+
]]></artwork>
        </section>
        <section anchor="state-machine-operation-overview">
          <name>State Machine Operation Overview</name>
          <t>When starting up, BBR probes to try to quickly build a model of the network
path; to adapt to later changes to the path or its traffic, BBR must continue
to probe to update its model. If the available bottleneck bandwidth increases,
BBR must send faster to discover this. Likewise, if the round-trip propagation
delay changes, this changes the BDP, and thus BBR must send slower to get
inflight below the new BDP in order to measure the new BBR.min_rtt. Thus,
BBR's state machine runs periodic, sequential experiments, sending faster
to check for BBR.bw increases or sending slower to yield bandwidth, drain
the queue, and check for BBR.min_rtt decreases. The frequency, magnitude,
duration, and structure of these experiments differ depending on what's already
known (startup or steady-state) and application sending behavior (intermittent
or continuous).</t>
          <t>This state machine has several goals:</t>
          <ul spacing="normal">
            <li>
              <t>Achieve high throughput by efficiently utilizing available bandwidth.</t>
            </li>
            <li>
              <t>Achieve low latency and packet loss rates by keeping queues bounded and small.</t>
            </li>
            <li>
              <t>Share bandwidth with other flows in an approximately fair manner.</t>
            </li>
            <li>
              <t>Feed samples to the model estimators to refresh and update the model.</t>
            </li>
          </ul>
        </section>
        <section anchor="state-machine-tactics">
          <name>State Machine Tactics</name>
          <t>In the BBR framework, at any given time the sender can choose one of the
following tactics:</t>
          <ul spacing="normal">
            <li>
              <t>Acceleration: Send faster then the network is delivering data: to probe the
maximum bandwidth available to the flow</t>
            </li>
            <li>
              <t>Deceleration: Send slower than the network is delivering data: to reduce
the amount of data in flight, with a number of overlapping motivations:  </t>
              <ul spacing="normal">
                <li>
                  <t>Reducing queuing delay: to reduce queuing delay, to reduce latency for
request/response cross-traffic (e.g. RPC, web traffic).</t>
                </li>
                <li>
                  <t>Reducing packet loss: to reduce packet loss, to reduce tail latency for
request/response cross-traffic (e.g. RPC, web traffic) and improve
coexistence with Reno/CUBIC.</t>
                </li>
                <li>
                  <t>Probing BBR.min_rtt: to probe the path's BBR.min_rtt</t>
                </li>
                <li>
                  <t>Bandwidth convergence: to aid bandwidth fairness convergence, by leaving
unused capacity in the bottleneck link or bottleneck buffer, to allow other
flows that may have lower sending rates to discover and utilize the unused
capacity</t>
                </li>
                <li>
                  <t>Burst tolerance: to allow bursty arrivals of cross-traffic (e.g. short web
or RPC requests) to be able to share the bottleneck link without causing
excessive queuing delay or packet loss</t>
                </li>
              </ul>
            </li>
            <li>
              <t>Cruising: Send at the same rate the network is delivering data: try to match
the sending rate to the flow's current available bandwidth, to try to achieve
high utilization of the available bandwidth without increasing queue pressure</t>
            </li>
          </ul>
          <t>Throughout the lifetime of a BBR flow, it sequentially cycles through all
three tactics, to measure the network path and try to optimize its operating
point.</t>
          <t>BBR's state machine uses two control mechanisms: the pacing_gain and the
cwnd. Primarily, it uses the pacing_gain (see the "Pacing Rate" section), which
controls how fast packets are sent relative to BBR.bw. A pacing_gain &gt; 1
decreases inter-packet time and increases inflight. A pacing_gain &lt; 1 has the
opposite effect, increasing inter-packet time and while aiming to decrease
inflight. The cwnd is sufficiently larger than the BDP to allow the higher
pacing gain to accumulate more packets in flight. Only if the state machine
needs to quickly reduce inflight to a particular absolute value, it uses the
cwnd.</t>
        </section>
      </section>
      <section anchor="algorithm-organization">
        <name>Algorithm Organization</name>
        <t>The BBR algorithm is an event-driven algorithm that executes steps upon the
following events: connection initialization, upon each ACK, upon the
transmission of each quantum, and upon loss detection events. All of the
sub-steps invoked referenced below are described below.</t>
        <section anchor="initialization">
          <name>Initialization</name>
          <t>Upon transport connection initialization, BBR executes its initialization
steps:</t>
          <artwork><![CDATA[
  BBROnInit():
    InitWindowedMaxFilter(filter=BBR.MaxBwFilter, value=0, time=0)
    BBR.min_rtt = SRTT ? SRTT : Infinity
    BBR.min_rtt_stamp = Now()
    BBR.probe_rtt_done_stamp = 0
    BBR.probe_rtt_round_done = false
    BBR.prior_cwnd = 0
    BBR.idle_restart = false
    BBR.extra_acked_interval_start = Now()
    BBR.extra_acked_delivered = 0
    BBR.full_bw_reached = false
    BBRResetCongestionSignals()
    BBRResetLowerBounds()
    BBRInitRoundCounting()
    BBRResetFullBW()
    BBRInitPacingRate()
    BBREnterStartup()
]]></artwork>
        </section>
        <section anchor="per-transmit-steps">
          <name>Per-Transmit Steps</name>
          <t>When transmitting, BBR merely needs to check for the case where the flow
is restarting from idle:</t>
          <artwork><![CDATA[
  BBROnTransmit():
    BBRHandleRestartFromIdle()
]]></artwork>
        </section>
        <section anchor="per-ack-steps">
          <name>Per-ACK Steps</name>
          <t>On every ACK, the BBR algorithm executes the following BBRUpdateOnACK() steps
in order to update its network path model, update its state machine, and
adjust its control parameters to adapt to the updated model:</t>
          <artwork><![CDATA[
  BBRUpdateOnACK():
    BBRUpdateModelAndState()
    BBRUpdateControlParameters()

  BBRUpdateModelAndState():
    BBRUpdateLatestDeliverySignals()
    BBRUpdateCongestionSignals()
    BBRUpdateACKAggregation()
    BBRCheckFullBWReached()
    BBRCheckStartupDone()
    BBRCheckDrainDone()
    BBRUpdateProbeBWCyclePhase()
    BBRUpdateMinRTT()
    BBRCheckProbeRTT()
    BBRAdvanceLatestDeliverySignals()
    BBRBoundBWForModel()

  BBRUpdateControlParameters():
    BBRSetPacingRate()
    BBRSetSendQuantum()
    BBRSetCwnd()
]]></artwork>
        </section>
        <section anchor="per-loss-steps">
          <name>Per-Loss Steps</name>
          <t>On every packet loss event, where some sequence range "packet" is marked
lost, the BBR algorithm executes the following BBRUpdateOnLoss() steps in
order to update its network path model</t>
          <artwork><![CDATA[
  BBRUpdateOnLoss(packet):
    BBRHandleLostPacket(packet)
]]></artwork>
        </section>
      </section>
      <section anchor="state-machine-operation">
        <name>State Machine Operation</name>
        <section anchor="startup">
          <name>Startup</name>
          <section anchor="startup-dynamics">
            <name>Startup Dynamics</name>
            <t>When a BBR flow starts up, it performs its first (and most rapid) sequential
probe/drain process in the Startup and Drain states. Network link bandwidths
currently span a range of at least 11 orders of magnitude, from a few bps
to hundreds of Gbps. To quickly learn BBR.max_bw, given this huge range to
explore, BBR's Startup state does an exponential search of the rate space,
doubling the sending rate each round. This finds BBR.max_bw in O(log_2(BDP))
round trips.</t>
            <t>To achieve this rapid probing smoothly, in Startup BBR uses the minimum gain
values that will allow the sending rate to double each round: in Startup BBR
sets BBR.pacing_gain to BBRStartupPacingGain (2.77) <xref target="BBRStartupPacingGain"/>
and BBR.cwnd_gain to BBRDefaultCwndGain (2) <xref target="BBRStartupCwndGain"/>.</t>
            <t>When initializing a connection, or upon any later entry into Startup mode,
BBR executes the following BBREnterStartup() steps:</t>
            <artwork><![CDATA[
  BBREnterStartup():
    BBR.state = Startup
    BBR.pacing_gain = BBRStartupPacingGain
    BBR.cwnd_gain = BBRDefaultCwndGain
]]></artwork>
            <t>As BBR grows its sending rate rapidly, it obtains higher delivery rate
samples, BBR.max_bw increases, and the pacing rate and cwnd both adapt by
smoothly growing in proportion. Once the pipe is full, a queue typically
forms, but the cwnd_gain bounds any queue to (cwnd_gain - 1) * estimated_BDP,
which is approximately (2 - 1) * estimated_BDP = estimated_BDP.
The immediately following Drain state is designed to quickly drain that queue.</t>
            <t>During Startup, BBR estimates whether the pipe is full using two estimators.
The first looks for a plateau in the BBR.max_bw estimate. The second looks
for packet loss. The following subsections discuss these estimators.</t>
            <artwork><![CDATA[
  BBRCheckStartupDone():
    BBRCheckStartupHighLoss()
    if (BBR.state == Startup and BBR.full_bw_reached)
      BBREnterDrain()
]]></artwork>
          </section>
          <section anchor="exiting-acceleration-based-on-bandwidth-plateau">
            <name>Exiting Acceleration Based on Bandwidth Plateau</name>
            <t>In phases where BBR is accelerating to probe the available bandwidth -
Startup and ProbeBW_UP - BBR runs a state machine to estimate whether an
accelerating sending rate has saturated the available per-flow bandwidth
("filled the pipe") by looking for a plateau in the measured
rs.delivery_rate.</t>
            <t>BBR tracks the status of the current full-pipe estimation process in the
boolean BBR.full_bw_now, and uses BBR.full_bw_now to exit ProbeBW_UP. BBR
records in the boolean BBR.full_bw_reached whether BBR estimates that it
has ever fully utilized its available bandwidth (over the lifetime of the
connection), and uses BBR.full_bw_reached to decide when to exit Startup
and enter Drain.</t>
            <t>The full pipe estimator works as follows: if BBR counts several (three)
non-application-limited rounds where attempts to significantly increase the
delivery rate actually result in little increase (less than 25 percent),
then it estimates that it has fully utilized the per-flow available bandwidth,
and sets both BBR.full_bw_now and BBR.full_bw_reached to true.</t>
            <t>Upon starting a full pipe detection process (either on startup or when probing
for an increase in bandwidth), the following steps are taken:</t>
            <artwork><![CDATA[
  BBRResetFullBW():
    BBR.full_bw = 0
    BBR.full_bw_count = 0
    BBR.full_bw_now = 0
]]></artwork>
            <t>While running the full pipe detection process, upon an ACK that acknowledges
new data, and when the delivery rate sample is not application-limited
(see <xref target="delivery-rate-samples"/>), BBR runs the "full pipe" estimator:</t>
            <artwork><![CDATA[
  BBRCheckFullBWReached():
    if (BBR.full_bw_now or !BBR.round_start or rs.is_app_limited)
      return  /* no need to check for a full pipe now */
    if (rs.delivery_rate >= BBR.full_bw * 1.25)
      BBRResetFullBW()       /* bw is still growing, so reset */
      BBR.full_bw = rs.delivery_rate  /* record new baseline bw */
      return
    BBR.full_bw_count++   /* another round w/o much growth */
    BBR.full_bw_now = (BBR.full_bw_count >= 3)
    if (BBR.full_bw_now)
      BBR.full_bw_reached = true
]]></artwork>
            <t>BBR waits three packet-timed round trips to have reasonable evidence that the
sender is not detecting a delivery-rate plateau that was temporarily imposed by
congestion or receive-window auto-tuning. This three-round threshold was
validated by experimental data to allow the receiver the chance to grow its
receive window.</t>
          </section>
          <section anchor="exiting-startup-based-on-packet-loss">
            <name>Exiting Startup Based on Packet Loss</name>
            <t>A second method BBR uses for estimating the bottleneck is full in Startup
is by looking at packet losses. Specifically, BBRCheckStartupHighLoss() checks
whether all of the following criteria are all met:</t>
            <ul spacing="normal">
              <li>
                <t>The connection has been in fast recovery for at least one full packet-timed
round trip.</t>
              </li>
              <li>
                <t>The loss rate over the time scale of a single full round trip exceeds
BBRLossThresh (2%).</t>
              </li>
              <li>
                <t>There are at least BBRStartupFullLossCnt=6 discontiguous sequence ranges
lost in that round trip.</t>
              </li>
            </ul>
            <t>If these criteria are all met, then BBRCheckStartupHighLoss() takes the
following steps. First, it sets BBR.full_bw_reached = true. Then it sets
BBR.inflight_longterm to its estimate of a safe level of in-flight data suggested
by these losses, which is max(BBR.bdp, BBR.inflight_latest), where
BBR.inflight_latest is the max delivered volume of data (rs.delivered) over
the last round trip. Finally, it exits Startup and enters Drain.</t>
            <t>The algorithm waits until all three criteria are met to filter out noise
from burst losses, and to try to ensure the bottleneck is fully utilized
on a sustained basis, and the full bottleneck bandwidth has been measured,
before attempting to drain the level of in-flight data to the estimated BDP.</t>
          </section>
        </section>
        <section anchor="drain">
          <name>Drain</name>
          <t>Upon exiting Startup, BBR enters its Drain state. In Drain, BBR aims to quickly
drain any queue at the bottleneck link that was created in Startup by switching
to a pacing_gain well below 1.0, until any estimated queue has been drained. It
uses a pacing_gain of BBRDrainPacingGain = 0.35, chosen via analysis
<xref target="BBRDrainPacingGain"/> and experimentation to try to drain the queue in less
than one round-trip:</t>
          <artwork><![CDATA[
  BBREnterDrain():
    BBR.state = Drain
    BBR.pacing_gain = BBRDrainPacingGain    /* pace slowly */
    BBR.cwnd_gain = BBRDefaultCwndGain      /* maintain cwnd */
]]></artwork>
          <t>In Drain, when the amount of data in flight is less than or equal to the
estimated BDP, meaning BBR estimates that the queue at the bottleneck link
has been fully drained, then BBR exits Drain and enters ProbeBW. To implement
this, upon every ACK BBR executes:</t>
          <artwork><![CDATA[
  BBRCheckDrainDone():
    if (BBR.state == Drain and C.pipe <= BBRInflight(1.0))
      BBREnterProbeBW()  /* BBR estimates the queue was drained */
]]></artwork>
        </section>
        <section anchor="probebw">
          <name>ProbeBW</name>
          <t>Long-lived BBR flows tend to spend the vast majority of their time in the
ProbeBW states. In the ProbeBW states, a BBR flow sequentially accelerates,
decelerates, and cruises, to measure the network path, improve its operating
point (increase throughput and reduce queue pressure), and converge toward a
more fair allocation of bottleneck bandwidth. To do this, the flow sequentially
cycles through all three tactics: trying to send faster than, slower than, and
at the same rate as the network delivery process. To achieve this, a BBR flow
in ProbeBW mode cycles through the four Probe bw states (DOWN, CRUISE, REFILL,
and UP) described below in turn.</t>
          <section anchor="probebwdown">
            <name>ProbeBW_DOWN</name>
            <t>In the ProbeBW_DOWN phase of the cycle, a BBR flow pursues the deceleration
tactic, to try to send slower than the network is delivering data, to reduce
the amount of data in flight, with all of the standard motivations for the
deceleration tactic (discussed in "State Machine Tactics" in
<xref target="state-machine-tactics"/>). It does this by switching to a
BBR.pacing_gain of 0.90, sending at 90% of BBR.bw. The pacing_gain value
of 0.90 is derived based on the ProbeBW_UP pacing gain of 1.25, as the minimum
pacing_gain value that allows bandwidth-based convergence to approximate
fairness, and validated through experiments.</t>
            <t>Exit conditions: The flow exits the ProbeBW_DOWN phase and enters CRUISE
when the flow estimates that both of the following conditions have been
met:</t>
            <ul spacing="normal">
              <li>
                <t>There is free headroom: If inflight_longterm is set, then BBR remains in
ProbeBW_DOWN at least until the volume of in-flight data is less than or
equal to a target calculated based on (1 - BBRHeadroom)*BBR.inflight_longterm.
The goal of this constraint is to ensure that in cases where loss signals
suggest an upper limit on the volume of in-flight data, then the flow attempts
to leave some free headroom in the path (e.g. free space in the bottleneck
buffer or free time slots in the bottleneck link) that can be used by
cross traffic (both for convergence of bandwidth shares and for burst tolerance).</t>
              </li>
              <li>
                <t>The volume of in-flight data is less than or equal to BBR.bdp, i.e. the flow
estimates that it has drained any queue at the bottleneck.</t>
              </li>
            </ul>
          </section>
          <section anchor="probebwcruise">
            <name>ProbeBW_CRUISE</name>
            <t>In the ProbeBW_CRUISE phase of the cycle, a BBR flow pursues the "cruising"
tactic (discussed in "State Machine Tactics" in
<xref target="state-machine-tactics"/>), attempting to send at the same rate the
network is delivering data. It tries to match the sending rate to the flow's
current available bandwidth, to try to achieve high utilization of the
available bandwidth without increasing queue pressure. It does this by
switching to a pacing_gain of 1.0, sending at 100% of BBR.bw. Notably, while
in this state it responds to concrete congestion signals (loss) by reducing
BBR.bw_shortterm and BBR.inflight_shortterm, because these signals suggest that
the available bandwidth and deliverable volume of in-flight data have likely
reduced, and the flow needs to change to adapt, slowing down to match the
latest delivery process.</t>
            <t>Exit conditions: The connection adaptively holds this state until it decides
that it is time to probe for bandwidth (see "Time Scale for Bandwidth Probing",
in <xref target="time-scale-for-bandwidth-probing-"/>), at which time it enters
ProbeBW_REFILL.</t>
          </section>
          <section anchor="probebwrefill">
            <name>ProbeBW_REFILL</name>
            <t>The goal of the ProbeBW_REFILL state is to "refill the pipe", to try to fully
utilize the network bottleneck without creating any significant queue pressure.</t>
            <t>To do this, BBR first resets the short-term model parameters bw_shortterm and
inflight_shortterm, setting both to "Infinity". This is the key moment in the BBR
time scale strategy (see "Time Scale Strategy", <xref target="time-scale-strategy"/>)
where the flow pivots, discarding its conservative short-term bw_shortterm and
inflight_shortterm parameters and beginning to robustly probe the bottleneck's
long-term available bandwidth. During this time the estimated bandwidth and
inflight_longterm, if set, constrain the connection.</t>
            <t>During ProbeBW_REFILL BBR uses a BBR.pacing_gain of 1.0, to send at a rate
that matches the current estimated available bandwidth, for one packet-timed
round trip. The goal is to fully utilize the bottleneck link before
transitioning into ProbeBW_UP and significantly increasing the chances of
causing loss. The motivating insight is that, as soon as a flow starts
acceleration, sending faster than the available bandwidth, it will start
building a queue at the bottleneck. And if the buffer is shallow enough,
then the flow can cause loss signals very shortly after the first accelerating
packets arrive at the bottleneck. If the flow were to neglect to fill the
pipe before it causes this loss signal, then these very quick signals of excess
queue could cause the flow's estimate of the path's capacity (i.e. inflight_longterm)
to significantly underestimate. In particular, if the flow were to transition
directly from ProbeBW_CRUISE to ProbeBW_UP, the volume of in-flight data
(at the time the first accelerating packets were sent) may often be still very
close to the volume of in-flight data maintained in CRUISE, which may be
only (1 - BBRHeadroom)*inflight_longterm.</t>
            <t>Exit conditions: The flow exits ProbeBW_REFILL after one packet-timed round
trip, and enters ProbeBW_UP. This is because after one full round trip of
sending in ProbeBW_REFILL the flow (if not application-limited) has had an
opportunity to place as many packets in flight as its BBR.bw and inflight_longterm
permit. Correspondingly, at this point the flow starts to see bandwidth samples
reflecting its ProbeBW_REFILL behavior, which may be putting too much data
in flight.</t>
          </section>
          <section anchor="probebwup">
            <name>ProbeBW_UP</name>
            <t>After ProbeBW_REFILL refills the pipe, ProbeBW_UP probes for possible
increases in available bandwidth by raising the sending rate, using a
BBR.pacing_gain of 1.25, to send faster than the current estimated available
bandwidth. It also raises the cwnd_gain to 2.25, to ensure that the flow
can send faster than it had been, even if cwnd was previously limiting the
sending process.</t>
            <t>If the flow has not set BBR.inflight_longterm, it implicitly tries to raise the
volume of in-flight data to at least BBR.pacing_gain * BBR.bdp = 1.25 *
BBR.bdp.</t>
            <t>If the flow has set BBR.inflight_longterm and encounters that limit, it then
gradually increases the upper volume bound (BBR.inflight_longterm) using the
following approach:</t>
            <ul spacing="normal">
              <li>
                <t>inflight_longterm: The flow raises inflight_longterm in ProbeBW_UP in a manner
that is slow and cautious at first, but increasingly rapid and bold over time.
The initial caution is motivated by the fact that a given BBR flow may be sharing
a shallow buffer with thousands of other flows, so that the buffer space
available to the flow may be quite tight (even just a single packet or
less). The increasingly rapid growth over time is motivated by the fact that
in a high-speed WAN the increase in available bandwidth (and thus the estimated
BDP) may require the flow to grow the volume of its inflight data by up to
O(1,000,000) packets; even a high-speed WAN BDP like
10Gbps * 100ms is around 83,000 packets (with a 1500-byte MTU). The additive
increase to BBR.inflight_longterm exponentially doubles each round trip;
in each successive round trip, inflight_longterm grows by 1, 2, 4, 8, 16,
etc, with the increases spread uniformly across the entire round trip.
This helps allow BBR to utilize a larger BDP in O(log(BDP)) round trips,
meeting the design goal for scalable utilization of newly-available bandwidth.</t>
              </li>
            </ul>
            <t>Exit conditions: The BBR flow ends ProbeBW_UP bandwidth probing and
transitions to ProbeBW_DOWN to try to drain the bottleneck queue when either
of the following conditions are met:</t>
            <ol spacing="normal" type="1"><li>
                <t>Bandwidth saturation: BBRIsTimeToGoDown() (see below) uses the "full pipe"
  estimator (see <xref target="exiting-acceleration-based-on-bandwidth-plateau"/>) to
  estimate whether the flow has saturated the available per-flow bandwidth
  ("filled the pipe"), by looking for a plateau in the measured
  rs.delivery_rate. If, during this process, the volume of data is constrained
  by BBR.inflight_longterm (the flow becomes cwnd-limited while cwnd is limited by
  BBR.inflight_longterm), then the flow cannot fully explore the available bandwidth,
  and so it resets the "full pipe" estimator by calling BBRResetFullBW().</t>
              </li>
              <li>
                <t>Loss: The current loss rate, over the time scale of the last round trip,
  exceeds BBRLossThresh (2%).</t>
              </li>
            </ol>
          </section>
          <section anchor="time-scale-for-bandwidth-probing-">
            <name>Time Scale for Bandwidth Probing</name>
            <t>Choosing the time scale for probing bandwidth is tied to the question of
how to coexist with legacy Reno/CUBIC flows, since probing for bandwidth
runs a significant risk of causing packet loss, and causing packet loss can
significantly limit the throughput of such legacy Reno/CUBIC flows.</t>
            <section anchor="bandwidth-probing-and-coexistence-with-renocubic">
              <name>Bandwidth Probing and Coexistence with Reno/CUBIC</name>
              <t>BBR has an explicit strategy for coexistence with Reno/CUBIC: to try to behave
in a manner so that  Reno/CUBIC flows coexisting with BBR can continue to
work well in the primary contexts where they do today:</t>
              <ul spacing="normal">
                <li>
                  <t>Intra-datacenter/LAN traffic: the goal is to allow Reno/CUBIC to be able
to perform well in 100M through 40G enterprise and datacenter Ethernet:  </t>
                  <ul spacing="normal">
                    <li>
                      <t>BDP = 40 Gbps * 20 us / (1514 bytes) ~= 66 packets</t>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>Public Internet last mile traffic: the goal is to allow Reno/CUBIC to be
able to support up to 25Mbps (for 4K Video) at an RTT of 30ms, typical
parameters for common CDNs for large video services:  </t>
                  <ul spacing="normal">
                    <li>
                      <t>BDP = 25Mbps * 30 ms / (1514 bytes) ~= 62 packets</t>
                    </li>
                  </ul>
                </li>
              </ul>
              <t>The challenge in meeting these goals is that Reno/CUBIC need long periods
of no loss to utilize large BDPs. The good news is that in the environments
where Reno/CUBIC work well today (mentioned above), the BDPs are small, roughly
~100 packets or less.</t>
            </section>
            <section anchor="a-dual-time-scale-approach-for-coexistence">
              <name>A Dual-Time-Scale Approach for Coexistence</name>
              <t>The BBR strategy has several aspects:</t>
              <ol spacing="normal" type="1"><li>
                  <t>The highest priority is to estimate the bandwidth available to the BBR flow
  in question.</t>
                </li>
                <li>
                  <t>Secondarily, a given BBR flow adapts (within bounds) the frequency at which
  it probes bandwidth and knowingly risks packet loss, to allow Reno/CUBIC
  to reach a bandwidth at least as high as that given BBR flow.</t>
                </li>
              </ol>
              <t>To adapt the frequency of bandwidth probing, BBR considers two time scales:
a BBR-native time scale, and a bounded Reno-conscious time scale:</t>
              <ul spacing="normal">
                <li>
                  <t>T_bbr: BBR-native time-scale  </t>
                  <ul spacing="normal">
                    <li>
                      <t>T_bbr = uniformly randomly distributed between 2 and 3 secs</t>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>T_reno: Reno-coexistence time scale  </t>
                  <ul spacing="normal">
                    <li>
                      <t>T_reno_bound = pick_randomly_either({62, 63})</t>
                    </li>
                    <li>
                      <t>reno_bdp = min(BBR.bdp, cwnd)</t>
                    </li>
                    <li>
                      <t>T_reno = min(reno_bdp, T_reno_bound) round trips</t>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>T_probe: The time between bandwidth probe UP phases:  </t>
                  <ul spacing="normal">
                    <li>
                      <t>T_probe = min(T_bbr, T_reno)</t>
                    </li>
                  </ul>
                </li>
              </ul>
              <t>This dual-time-scale approach is similar to that used by CUBIC, which has
a CUBIC-native time scale given by a cubic curve, and a "Reno emulation"
module that estimates what cwnd would give the flow Reno-equivalent throughput.
At any given moment, CUBIC choose the cwnd implied by the more aggressive
strategy.</t>
              <t>We randomize both the T_bbr and T_reno parameters, for better mixing and
fairness convergence.</t>
            </section>
            <section anchor="design-considerations-for-choosing-constant-parameters">
              <name>Design Considerations for Choosing Constant Parameters</name>
              <t>We design the maximum wall-clock bounds of BBR-native inter-bandwidth-probe
wall clock time, T_bbr, to be:</t>
              <ul spacing="normal">
                <li>
                  <t>Higher than 2 sec to try to avoid causing loss for a long enough time to
allow Reno flow with RTT=30ms to get 25Mbps (4K video) throughput. For this
workload, given the Reno sawtooth that raises cwnd from roughly BDP to 2*BDP,
one SMSS per round trip,  the inter-bandwidth-probe time must be at least:
BDP * RTT = 25Mbps * .030 sec / (1514 bytes) * 0.030 sec = 1.9secs</t>
                </li>
                <li>
                  <t>Lower than 3 sec to ensure flows can start probing in a reasonable amount
of time to discover unutilized bw on human-scale interactive  time-scales
(e.g. perhaps traffic from a competing web page download is now complete).</t>
                </li>
              </ul>
              <t>The maximum round-trip bounds of the Reno-coexistence time scale, T_reno,
are chosen to be 62-63 with the following considerations in mind:</t>
              <ul spacing="normal">
                <li>
                  <t>Choosing a value smaller than roughly 60 would imply that when BBR flows
coexisted with Reno/CUBIC flows on public Internet broadband links, the
Reno/CUBIC flows would not be able to achieve enough bandwidth to show 4K
video.</t>
                </li>
                <li>
                  <t>Choosing a value that is too large would prevent BBR from reaching its goal
of tolerating 1% loss per round trip.
Given that the steady-state (non-bandwidth-probing) BBR response to
a non-application-limited round trip with X% packet loss is to
reduce the sending rate by X% (see "Updating the Model Upon Packet
Loss" in <xref target="updating-the-model-upon-packet-loss"/>), this means that the
BBR sending rate after N rounds of packet loss at a rate loss_rate
is reduced to (1 - loss_rate)^N.
A simplified model predicts that for a flow that encounters 1% loss
in N=137 round trips of ProbeBW_CRUISE, and then doubles its cwnd
(back to BBR.inflight_longterm) in ProbeBW_REFILL and ProbeBW_UP, we
expect that it will be able to restore and reprobe its original
sending rate, since: (1 - loss_rate)^N * 2^2 = (1 - .01)^137 * 2^2
~= 1.01.
That is, we expect the flow will be able to fully respond to packet
loss signals in ProbeBW_CRUISE while also fully re-measuring its
maximum achievable throughput in ProbeBW_UP.
However, with a larger number of round trips of ProbeBW_CRUISE, the
flow would not be able to sustain its achievable throughput.</t>
                </li>
              </ul>
              <t>The resulting behavior is that for BBR flows with small BDPs, the bandwidth
probing will be on roughly the same time scale as Reno/CUBIC; flows with
large BDPs will intentionally probe more rapidly/frequently than Reno/CUBIC
would (roughly every 62 round trips for low-RTT flows, or 2-3 secs for
high-RTT flows).</t>
              <t>The considerations above for timing bandwidth probing can be implemented
as follows:</t>
              <artwork><![CDATA[
  /* Is it time to transition from DOWN or CRUISE to REFILL? */
  BBRIsTimeToProbeBW():
    if (BBRHasElapsedInPhase(BBR.bw_probe_wait) ||
        BBRIsRenoCoexistenceProbeTime())
      BBRStartProbeBW_REFILL()
      return true
    return false

  /* Randomized decision about how long to wait until
   * probing for bandwidth, using round count and wall clock.
   */
  BBRPickProbeWait():
    /* Decide random round-trip bound for wait: */
    BBR.rounds_since_bw_probe =
      random_int_between(0, 1); /* 0 or 1 */
    /* Decide the random wall clock bound for wait: */
    BBR.bw_probe_wait =
      2 + random_float_between(0.0, 1.0) /* 0..1 sec */

  BBRIsRenoCoexistenceProbeTime():
    reno_rounds = BBRTargetInflight()
    rounds = min(reno_rounds, 63)
    return BBR.rounds_since_bw_probe >= rounds

  /* How much data do we want in flight?
   * Our estimated BDP, unless congestion cut cwnd. */
  BBRTargetInflight()
    return min(BBR.bdp, cwnd)
]]></artwork>
            </section>
          </section>
          <section anchor="probebw-algorithm-details">
            <name>ProbeBW Algorithm Details</name>
            <t>BBR's ProbeBW algorithm operates as follows.</t>
            <t>Upon entering ProbeBW, BBR executes:</t>
            <artwork><![CDATA[
  BBREnterProbeBW():
    BBR.cwnd_gain = BBRDefaultCwndGain
    BBRStartProbeBW_DOWN()
]]></artwork>
            <t>The core logic for entering each state:</t>
            <artwork><![CDATA[
  BBRStartProbeBW_DOWN():
    BBRResetCongestionSignals()
    BBR.probe_up_cnt = Infinity /* not growing inflight_longterm */
    BBRPickProbeWait()
    BBR.cycle_stamp = Now()  /* start wall clock */
    BBR.ack_phase  = ACKS_PROBE_STOPPING
    BBRStartRound()
    BBR.state = ProbeBW_DOWN

  BBRStartProbeBW_CRUISE():
    BBR.state = ProbeBW_CRUISE

  BBRStartProbeBW_REFILL():
    BBRResetLowerBounds()
    BBR.bw_probe_up_rounds = 0
    BBR.bw_probe_up_acks = 0
    BBR.ack_phase = ACKS_REFILLING
    BBRStartRound()
    BBR.state = ProbeBW_REFILL

  BBRStartProbeBW_UP():
    BBR.ack_phase = ACKS_PROBE_STARTING
    BBRStartRound()
    BBRResetFullBW()
    BBR.full_bw = rs.delivery_rate
    BBR.state = ProbeBW_UP
    BBRRaiseInflightLongtermSlope()
]]></artwork>
            <t>BBR executes the following BBRUpdateProbeBWCyclePhase() logic on each ACK
that acknowledges new data, to advance the ProbeBW state machine:</t>
            <artwork><![CDATA[
  /* The core state machine logic for ProbeBW: */
  BBRUpdateProbeBWCyclePhase():
    if (!BBR.full_bw_reached)
      return  /* only handling steady-state behavior here */
    BBRAdaptUpperBounds()
    if (!IsInAProbeBWState())
      return /* only handling ProbeBW states here: */

    switch (state)

    ProbeBW_DOWN:
      if (BBRIsTimeToProbeBW())
        return /* already decided state transition */
      if (BBRIsTimeToCruise())
        BBRStartProbeBW_CRUISE()

    ProbeBW_CRUISE:
      if (BBRIsTimeToProbeBW())
        return /* already decided state transition */

    ProbeBW_REFILL:
      /* After one round of REFILL, start UP */
      if (BBR.round_start)
        BBR.bw_probe_samples = 1
        BBRStartProbeBW_UP()

    ProbeBW_UP:
      if (BBRIsTimeToGoDown())
        BBRStartProbeBW_DOWN()
]]></artwork>
            <t>The ancillary logic to implement the ProbeBW state machine:</t>
            <artwork><![CDATA[
  IsInAProbeBWState()
    state = BBR.state
    return (state == ProbeBW_DOWN or
            state == ProbeBW_CRUISE or
            state == ProbeBW_REFILL or
            state == ProbeBW_UP)

  /* Time to transition from DOWN to CRUISE? */
  BBRIsTimeToCruise():
    if (inflight > BBRInflightWithHeadroom())
      return false /* not enough headroom */
    if (inflight <= BBRInflight(BBR.max_bw, 1.0))
      return true  /* inflight <= estimated BDP */

  /* Time to transition from UP to DOWN? */
  BBRIsTimeToGoDown():
    if (is_cwnd_limited and cwnd >= BBR.inflight_longterm)
      BBRResetFullBW()   /* bw is limited by inflight_longterm */
      BBR.full_bw = rs.delivery_rate
    else if (BBR.full_bw_now)
      return true  /* we estimate we've fully used path bw */
    return false

  BBRIsProbingBW():
    return (BBR.state == Startup or
            BBR.state == ProbeBW_REFILL or
            BBR.state == ProbeBW_UP)

  BBRHasElapsedInPhase(interval):
    return Now() > BBR.cycle_stamp + interval

  /* Return a volume of data that tries to leave free
   * headroom in the bottleneck buffer or link for
   * other flows, for fairness convergence and lower
   * RTTs and loss */
  BBRInflightWithHeadroom():
    if (BBR.inflight_longterm == Infinity)
      return Infinity
    headroom = max(1*SMSS, BBRHeadroom * BBR.inflight_longterm)
    return max(BBR.inflight_longterm - headroom,
               BBRMinPipeCwnd)

  /* Raise inflight_longterm slope if appropriate. */
  BBRRaiseInflightLongtermSlope():
    growth_this_round = 1*SMSS << BBR.bw_probe_up_rounds
    BBR.bw_probe_up_rounds = min(BBR.bw_probe_up_rounds + 1, 30)
    BBR.probe_up_cnt = max(cwnd / growth_this_round, 1)

  /* Increase inflight_longterm if appropriate. */
  BBRProbeInflightLongtermUpward():
    if (!is_cwnd_limited or cwnd < BBR.inflight_longterm)
      return  /* not fully using inflight_longterm, so don't grow it */
   BBR.bw_probe_up_acks += rs.newly_acked
   if (BBR.bw_probe_up_acks >= BBR.probe_up_cnt)
     delta = BBR.bw_probe_up_acks / BBR.probe_up_cnt
     BBR.bw_probe_up_acks -= delta * BBR.bw_probe_up_cnt
     BBR.inflight_longterm += delta
   if (BBR.round_start)
     BBRRaiseInflightLongtermSlope()

  /* Track ACK state and update BBR.max_bw window and
   * BBR.inflight_longterm. */
  BBRAdaptUpperBounds():
    if (BBR.ack_phase == ACKS_PROBE_STARTING and BBR.round_start)
      /* starting to get bw probing samples */
      BBR.ack_phase = ACKS_PROBE_FEEDBACK
    if (BBR.ack_phase == ACKS_PROBE_STOPPING and BBR.round_start)
      /* end of samples from bw probing phase */
      if (IsInAProbeBWState() and !rs.is_app_limited)
        BBRAdvanceMaxBwFilter()

    if (!IsInflightTooHigh())
      /* Loss rate is safe. Adjust upper bounds upward. */
      if (BBR.inflight_longterm == Infinity)
        return /* no upper bounds to raise */
      if (rs.tx_in_flight > BBR.inflight_longterm)
        BBR.inflight_longterm = rs.tx_in_flight
      if (BBR.state == ProbeBW_UP)
        BBRProbeInflightLongtermUpward()
]]></artwork>
          </section>
        </section>
        <section anchor="probertt">
          <name>ProbeRTT</name>
          <section anchor="probertt-overview">
            <name>ProbeRTT Overview</name>
            <t>To help probe for BBR.min_rtt, on an as-needed basis BBR flows enter the
ProbeRTT state to try to cooperate to periodically drain the bottleneck queue,
and thus improve their BBR.min_rtt estimate of the unloaded two-way propagation
delay.</t>
            <t>A critical point is that before BBR raises its BBR.min_rtt
estimate (which would in turn raise its maximum permissible cwnd), it first
enters ProbeRTT to try to make a concerted and coordinated effort to drain
the bottleneck queue and make a robust BBR.min_rtt measurement. This allows the
BBR.min_rtt estimates of ensembles of BBR flows to converge, avoiding feedback
loops of ever-increasing queues and RTT samples.</t>
            <t>The ProbeRTT state works in concert with BBR.min_rtt estimation. Up to once
every ProbeRTTInterval = 5 seconds, the flow enters ProbeRTT, decelerating
by setting its cwnd_gain to BBRProbeRTTCwndGain = 0.5 to reduce its volume of
inflight data to half of its estimated BDP, to try to measure the unloaded
two-way propagation delay.</t>
            <t>There are two main motivations for making the MinRTTFilterLen roughly twice
the ProbeRTTInterval. First, this ensures that during a ProbeRTT episode
the flow will "remember" the BBR.min_rtt value it measured during the previous
ProbeRTT episode, providing a robust BDP estimate for the cwnd = 0.5*BDP
calculation, increasing the likelihood of fully draining the bottleneck
queue. Second, this allows the flow's BBR.min_rtt filter window to generally
include RTT samples from two ProbeTT episodes, providing a more robust
estimate.</t>
            <t>The algorithm for ProbeRTT is as follows:</t>
            <t>Entry conditions: In any state other than ProbeRTT itself, if the
BBR.probe_rtt_min_delay estimate has not been updated (i.e., by getting a
lower RTT measurement) for more than ProbeRTTInterval = 5 seconds, then BBR
enters ProbeRTT and reduces the BBR.cwnd_gain to BBRProbeRTTCwndGain = 0.5.</t>
            <t>Exit conditions: After maintaining the volume of in-flight data at
BBRProbeRTTCwndGain*BBR.bdp for at least ProbeRTTDuration (200 ms) and at
least one packet-timed round trip, BBR leaves ProbeRTT and transitions to
ProbeBW if it estimates the pipe was filled already, or Startup otherwise.</t>
          </section>
          <section anchor="probertt-design-rationale">
            <name>ProbeRTT Design Rationale</name>
            <t>BBR is designed to have ProbeRTT sacrifice no more than roughly 2% of a flow's
available bandwidth. It is also designed to spend the vast majority of its
time (at least roughly 96 percent) in ProbeBW and the rest in ProbeRTT, based
on a set of tradeoffs. ProbeRTT lasts long enough (at least ProbeRTTDuration
= 200 ms) to allow diverse flows (e.g., flows with different RTTs or lower
rates and thus longer inter-packet gaps) to have overlapping ProbeRTT states,
while still being short enough to bound the throughput penalty of ProbeRTT's
cwnd capping to roughly 2%, with the average throughput targeted at:</t>
            <artwork><![CDATA[
  throughput = (200ms*0.5*BBR.bw + (5s - 200ms)*BBR.bw) / 5s
             = (.1s + 4.8s)/5s * BBR.bw = 0.98 * BBR.bw
]]></artwork>
            <t>As discussed above, BBR's BBR.min_rtt filter window, MinRTTFilterLen, and
time interval between ProbeRTT states, ProbeRTTInterval, work in concert.
BBR uses a MinRTTFilterLen equal to or longer than ProbeRTTInterval to allow
the filter window to include at least one ProbeRTT.</t>
            <t>To allow coordination with other BBR flows, each BBR flow MUST use the
standard ProbeRTTInterval of 5 secs.</t>
            <t>A ProbeRTTInterval of 5 secs is short enough to allow quick convergence if
traffic levels or routes change, but long enough so that interactive
applications (e.g., Web, remote procedure calls, video chunks) often have
natural silences or low-rate periods within the window where the flow's rate
is low enough for long enough to drain its queue in the bottleneck. Then the
BBR.probe_rtt_min_delay filter opportunistically picks up these measurements,
and the BBR.probe_rtt_min_delay estimate refreshes without requiring
ProbeRTT. This way, flows typically need only pay the 2 percent throughput
penalty if there are multiple bulk flows busy sending over the entire
ProbeRTTInterval window.</t>
            <t>As an optimization, when restarting from idle and finding that the
BBR.probe_rtt_min_delay has expired, BBR does not enter ProbeRTT; the idleness
is deemed a sufficient attempt to coordinate to drain the queue.</t>
          </section>
          <section anchor="calculating-the-rsrtt-rtt-sample">
            <name>Calculating the rs.rtt RTT Sample</name>
            <t>Upon transmitting each packet, BBR or the associated transport protocol
stores in per-packet data the wall-clock scheduled transmission time of the
packet in packet.departure_time (see "Pacing Rate: BBR.pacing_rate" in
<xref target="pacing-rate-bbrpacingrate"/> for how this is calculated).</t>
            <t>For every ACK that newly acknowledges data, the sender's BBR implementation
or the associated transport protocol implementation attempts to calculate an
RTT sample. The sender MUST consider any potential retransmission ambiguities
that can arise in some transport protocols. If some of the acknowledged data
was not retransmitted, or some of the data was retransmitted but the sender
can still unambiguously determine the RTT of the data (e.g. QUIC or TCP with
timestamps <xref target="RFC7323"/>), then the sender calculates an RTT sample, rs.rtt,
as follows:</t>
            <artwork><![CDATA[
  rs.rtt = Now() - packet.departure_time
]]></artwork>
          </section>
          <section anchor="probertt-logic">
            <name>ProbeRTT Logic</name>
            <t>On every ACK BBR executes BBRUpdateMinRTT() to update its ProbeRTT scheduling
state (BBR.probe_rtt_min_delay and BBR.probe_rtt_min_stamp) and its BBR.min_rtt
estimate:</t>
            <artwork><![CDATA[
  BBRUpdateMinRTT()
    BBR.probe_rtt_expired =
      Now() > BBR.probe_rtt_min_stamp + ProbeRTTInterval
    if (rs.rtt >= 0 and
        (rs.rtt < BBR.probe_rtt_min_delay or
         BBR.probe_rtt_expired))
       BBR.probe_rtt_min_delay = rs.rtt
       BBR.probe_rtt_min_stamp = Now()

    min_rtt_expired =
      Now() > BBR.min_rtt_stamp + MinRTTFilterLen
    if (BBR.probe_rtt_min_delay < BBR.min_rtt or
        min_rtt_expired)
      BBR.min_rtt       = BBR.probe_rtt_min_delay
      BBR.min_rtt_stamp = BBR.probe_rtt_min_stamp
]]></artwork>
            <t>Here BBR.probe_rtt_expired is a boolean recording whether the
BBR.probe_rtt_min_delay has expired and is due for a refresh, via either
an application idle period or a transition into ProbeRTT state.</t>
            <t>On every ACK BBR executes BBRCheckProbeRTT() to handle the steps related
to the ProbeRTT state as follows:</t>
            <artwork><![CDATA[
  BBRCheckProbeRTT():
    if (BBR.state != ProbeRTT and
        BBR.probe_rtt_expired and
        not BBR.idle_restart)
      BBREnterProbeRTT()
      BBRSaveCwnd()
      BBR.probe_rtt_done_stamp = 0
      BBR.ack_phase = ACKS_PROBE_STOPPING
      BBRStartRound()
    if (BBR.state == ProbeRTT)
      BBRHandleProbeRTT()
    if (rs.delivered > 0)
      BBR.idle_restart = false

  BBREnterProbeRTT():
    BBR.state = ProbeRTT
    BBR.pacing_gain = 1
    BBR.cwnd_gain = BBRProbeRTTCwndGain  /* 0.5 */

  BBRHandleProbeRTT():
    /* Ignore low rate samples during ProbeRTT: */
    MarkConnectionAppLimited()
    if (BBR.probe_rtt_done_stamp == 0 and
        C.pipe <= BBRProbeRTTCwnd())
      /* Wait for at least ProbeRTTDuration to elapse: */
      BBR.probe_rtt_done_stamp =
        Now() + ProbeRTTDuration
      /* Wait for at least one round to elapse: */
      BBR.probe_rtt_round_done = false
      BBRStartRound()
    else if (BBR.probe_rtt_done_stamp != 0)
      if (BBR.round_start)
        BBR.probe_rtt_round_done = true
      if (BBR.probe_rtt_round_done)
        BBRCheckProbeRTTDone()

  BBRCheckProbeRTTDone():
    if (BBR.probe_rtt_done_stamp != 0 and
        Now() > BBR.probe_rtt_done_stamp)
      /* schedule next ProbeRTT: */
      BBR.probe_rtt_min_stamp = Now()
      BBRRestoreCwnd()
      BBRExitProbeRTT()

  MarkConnectionAppLimited():
    C.app_limited =
      (C.delivered + C.pipe) ? : 1
]]></artwork>
          </section>
          <section anchor="exiting-probertt">
            <name>Exiting ProbeRTT</name>
            <t>When exiting ProbeRTT, BBR transitions to ProbeBW if it estimates the pipe
was filled already, or Startup otherwise.</t>
            <t>When transitioning out of ProbeRTT, BBR calls BBRResetLowerBounds() to reset
the lower bounds, since any congestion encountered in ProbeRTT may have pulled
the short-term model far below the capacity of the path.</t>
            <t>But the algorithm is cautious in timing the next bandwidth probe: raising
inflight after ProbeRTT may cause loss, so the algorithm resets the
bandwidth-probing clock by starting the cycle at ProbeBW_DOWN(). But then as an
optimization, since the connection is exiting ProbeRTT, we know that infligh is
already below the estimated BDP, so the connection can proceed immediately to
ProbeBW_CRUISE.</t>
            <t>To summarize, the logic for exiting ProbeRTT is as follows:</t>
            <artwork><![CDATA[
  BBRExitProbeRTT():
    BBRResetLowerBounds()
    if (BBR.full_bw_reached)
      BBRStartProbeBW_DOWN()
      BBRStartProbeBW_CRUISE()
    else
      BBREnterStartup()
]]></artwork>
          </section>
        </section>
      </section>
      <section anchor="restarting-from-idle">
        <name>Restarting From Idle</name>
        <section anchor="actions-when-restarting-from-idle">
          <name>Actions when Restarting from Idle</name>
          <t>When restarting from idle in ProbeBW states, BBR leaves its cwnd as-is and
paces packets at exactly BBR.bw, aiming to return as quickly as possible
to its target operating point of rate balance and a full pipe. Specifically, if
the flow's BBR.state is ProbeBW, and the flow is application-limited, and there
are no packets in flight currently, then before the flow sends one or more
packets BBR sets BBR.pacing_rate to exactly BBR.bw.</t>
          <t>Also, when restarting from idle BBR checks to see if the connection is in
ProbeRTT and has met the exit conditions for ProbeRTT. If a connection goes
idle during ProbeRTT then often it will have met those exit conditions by
the time it restarts, so that the connection can restore the cwnd to its full
value before it starts transmitting a new flight of data.</t>
          <t>More precisely, the BBR algorithm takes the following steps in
BBRHandleRestartFromIdle() before sending a packet for a flow:</t>
          <artwork><![CDATA[
  BBRHandleRestartFromIdle():
    if (C.pipe == 0 and C.app_limited)
      BBR.idle_restart = true
      BBR.extra_acked_interval_start = Now()
      if (IsInAProbeBWState())
        BBRSetPacingRateWithGain(1)
      else if (BBR.state == ProbeRTT)
        BBRCheckProbeRTTDone()
]]></artwork>
        </section>
        <section anchor="previous-idle-restart">
          <name>Comparison with Previous Approaches</name>
          <t>The "Restarting Idle Connections" section of <xref target="RFC5681"/> suggests restarting
from idle by slow-starting from the initial window. However, this approach was
assuming a congestion control algorithm that had no estimate of the bottleneck
bandwidth and no pacing, and thus resorted to relying on slow-starting driven
by an ACK clock. The long (log_2(BDP)*RTT) delays required to reach full
utilization with that "slow start after idle" approach caused many large
deployments to disable this mechanism, resulting in a "BDP-scale line-rate
burst" approach instead. Instead of these two approaches, BBR restarts by
pacing at BBR.bw, typically achieving approximate rate balance and a full pipe
after only one BBR.min_rtt has elapsed.</t>
        </section>
      </section>
      <section anchor="updating-network-path-model-parameters">
        <name>Updating Network Path Model Parameters</name>
        <t>BBR is a model-based congestion control algorithm: it is based on an explicit
model of the network path over which a transport flow travels. The following
is a summary of each parameter, including its meaning and how the algorithm
calculates and uses its value. We can group the parameter into three groups:</t>
        <ul spacing="normal">
          <li>
            <t>core state machine parameters</t>
          </li>
          <li>
            <t>parameters to model the data rate</t>
          </li>
          <li>
            <t>parameters to model the volume of in-flight data</t>
          </li>
        </ul>
        <section anchor="bbrroundcount-tracking-packet-timed-round-trips">
          <name>BBR.round_count: Tracking Packet-Timed Round Trips</name>
          <t>Several aspects of BBR depend on counting the progress of "packet-timed"
round trips, which start at the transmission of some segment, and then end
at the acknowledgement of that segment. BBR.round_count is a count of the number
of these "packet-timed" round trips elapsed so far. BBR uses this virtual
BBR.round_count because it is more robust than using wall clock time. In
particular, arbitrary intervals of wall clock time can elapse due to
application idleness, variations in RTTs, or timer delays for retransmission
timeouts, causing wall-clock-timed model parameter estimates to "time out"
or to be "forgotten" too quickly to provide robustness.</t>
          <t>BBR counts packet-timed round trips by recording state about a sentinel packet,
and waiting for an ACK of any data packet that was sent after that sentinel
packet, using the following pseudocode:</t>
          <t>Upon connection initialization:</t>
          <artwork><![CDATA[
  BBRInitRoundCounting():
    BBR.next_round_delivered = 0
    BBR.round_start = false
    BBR.round_count = 0
]]></artwork>
          <t>Upon sending each packet, the rate estimation algorithm in
<xref target="delivery-rate-samples"/> records the amount of data thus far
acknowledged as delivered:</t>
          <artwork><![CDATA[
  packet.delivered = C.delivered
]]></artwork>
          <t>Upon receiving an ACK for a given data packet, the rate estimation algorithm
in <xref target="delivery-rate-samples"/> updates the amount of data thus far
acknowledged as delivered:</t>
          <artwork><![CDATA[
    C.delivered += packet.size
]]></artwork>
          <t>Upon receiving an ACK for a given data packet, the BBR algorithm first executes
the following logic to see if a round trip has elapsed, and if so, increment
the count of such round trips elapsed:</t>
          <artwork><![CDATA[
  BBRUpdateRound():
    if (packet.delivered >= BBR.next_round_delivered)
      BBRStartRound()
      BBR.round_count++
      BBR.rounds_since_bw_probe++
      BBR.round_start = true
    else
      BBR.round_start = false

  BBRStartRound():
    BBR.next_round_delivered = C.delivered
]]></artwork>
        </section>
        <section anchor="bbrmaxbw-estimated-maximum-bandwidth">
          <name>BBR.max_bw: Estimated Maximum Bandwidth</name>
          <t>BBR.max_bw is BBR's estimate of the maximum bottleneck bandwidth available to
data transmissions for the transport flow. At any time, a transport
connection's data transmissions experience some slowest link or bottleneck. The
bottleneck's delivery rate determines the connection's maximum data-delivery
rate. BBR tries to closely match its sending rate to this bottleneck delivery
rate to help seek "rate balance", where the flow's packet arrival rate at the
bottleneck equals the departure rate. The bottleneck rate varies over the life
of a connection, so BBR continually estimates BBR.max_bw using recent signals.</t>
          <section anchor="delivery-rate-samples">
            <name>Delivery Rate Samples</name>
            <t>This section describes a generic algorithm for a transport protocol sender to
estimate the current delivery rate of its data on the fly. This technique is
used by BBR to get fresh, reliable, and inexpensive delivery rate information.</t>
            <t>At a high level, the algorithm estimates the rate at which the network
delivered the most recent flight of outbound data packets for a single flow. In
addition, it tracks whether the rate sample was application-limited, meaning
the transmission rate was limited by the sending application rather than the
congestion control algorithm.</t>
            <t>Each acknowledgment that cumulatively or selectively acknowledges that the
network has delivered new data produces a rate sample which records the amount
of data delivered over the time interval between the transmission of a data
packet and the acknowledgment of that packet. The samples reflect the recent
goodput through some bottleneck, which may reside either in the network or
on the end hosts (sender or receiver).</t>
          </section>
          <section anchor="delivery-rate-sampling-algorithm-overview">
            <name>Delivery Rate Sampling Algorithm Overview</name>
            <section anchor="requirements">
              <name>Requirements</name>
              <t>This algorithm can be implemented in any transport protocol that supports
packet-delivery acknowledgment (so far, implementations are available for TCP
<xref target="RFC9293"/> and QUIC <xref target="RFC9000"/>). This algorithm requires a small amount of
added logic on the sender, and requires that the sender maintain a small amount
of additional per-packet state for packets sent but not yet delivered. In the
most general case it requires high-precision (microsecond-granularity or
better) timestamps on the sender (though millisecond-granularity may suffice
for lower bandwidths).  It does not require any receiver or network
changes. While selective acknowledgments for out-of-order data (e.g.,
<xref target="RFC2018"/>) are not required, such a mechanism is highly recommended for
accurate estimation during reordering and loss recovery phases.</t>
            </section>
            <section anchor="estimating-delivery-rate">
              <name>Estimating Delivery Rate</name>
              <t>A delivery rate sample records the estimated rate at which the network delivered
packets for a single flow, calculated over the time interval between the
transmission of a data packet and the acknowledgment of that packet. Since
the rate samples only include packets actually cumulatively and/or selectively
acknowledged, the sender knows the exact octets that were delivered to the
receiver (not lost), and the sender can compute an estimate of a bottleneck
delivery rate over that time interval.</t>
              <t>The amount of data delivered MAY be tracked in units of either octets or
packets. Tracking data in units of octets is more accurate, since packet
sizes can vary. But for some purposes, including congestion control, tracking
data in units of packets may suffice.</t>
              <section anchor="ack-rate">
                <name>ACK Rate</name>
                <t>First, consider the rate at which data is acknowledged by the receiver. In
this algorithm, the computation of the ACK rate models the average slope
of a hypothetical "delivered" curve that tracks the cumulative quantity of
data delivered so far on the Y axis, and time elapsed on the X axis. Since
ACKs arrive in discrete events, this "delivered" curve forms a step function,
where each ACK causes a discrete increase in the "delivered" count that causes
a vertical upward step up in the curve. This "ack_rate" computation is the
average slope of the "delivered" step function, as measured from the "knee"
of the step (ACK) preceding the transmit to the "knee" of the step (ACK)
for packet P.</t>
                <t>Given this model, the ack rate sample "slope" is computed as the ratio between
the amount of data marked as delivered over this time interval, and the time
over which it is marked as delivered:</t>
                <artwork><![CDATA[
  ack_rate = data_acked / ack_elapsed
]]></artwork>
                <t>To calculate the amount of data ACKed over the interval, the sender records in
per-packet state "P.delivered", the amount of data that had been marked
delivered before transmitting packet P, and then records how much data had been
marked delivered by the time the ACK for the packet arrives (in "C.delivered"),
and computes the difference:</t>
                <artwork><![CDATA[
  data_acked = C.delivered - P.delivered
]]></artwork>
                <t>To compute the time interval, "ack_elapsed", one might imagine that it would
be feasible to use the round-trip time (RTT) of the packet. But it is not
safe to simply calculate a bandwidth estimate by using the time between the
transmit of a packet and the acknowledgment of that packet. Transmits and
ACKs can happen out of phase with each other, clocked in separate processes.
In general, transmissions often happen at some point later than the most
recent ACK, due to processing or pacing delays. Because of this effect, drastic
over-estimates can happen if a sender were to attempt to estimate bandwidth
by using the round-trip time.</t>
                <t>The following approach computes "ack_elapsed". The starting time is
"P.delivered_time", the time of the delivery curve "knee" from the ACK
preceding the transmit.  The ending time is "C.delivered_time", the time of the
delivery curve "knee" from the ACK for P. Then we compute "ack_elapsed" as:</t>
                <artwork><![CDATA[
  ack_elapsed = C.delivered_time - P.delivered_time
]]></artwork>
                <t>This yields our equation for computing the ACK rate, as the "slope" from
the "knee" preceding the transmit to the "knee" at ACK:</t>
                <artwork><![CDATA[
  ack_rate = data_acked / ack_elapsed
  ack_rate = (C.delivered - P.delivered) /
             (C.delivered_time - P.delivered_time)
]]></artwork>
              </section>
              <section anchor="compression-and-aggregation">
                <name>Compression and Aggregation</name>
                <t>For computing the delivery_rate, the sender prefers ack_rate, the rate at which
packets were acknowledged, since this usually the most reliable metric.
However, this approach of directly using "ack_rate" faces a challenge when used
with paths featuring aggregation, compression, or ACK decimation, which are
prevalent <xref target="A15"/>.  In such cases, ACK arrivals can temporarily make it appear
as if data packets were delivered much faster than the bottleneck rate. To
filter out such implausible ack_rate samples, we consider the send rate for
each flight of data, as follows.</t>
              </section>
              <section anchor="send-rate">
                <name>Send Rate</name>
                <t>The sender calculates the send rate, "send_rate", for a flight of data as
follows. Define "P.first_sent_time" as the time of the first send in a flight
of data, and "P.sent_time" as the time the final send in that flight of data
(the send that transmits packet "P"). The elapsed time for sending the flight
is:</t>
                <artwork><![CDATA[
  send_elapsed = (P.sent_time - P.first_sent_time)
]]></artwork>
                <t>Then we calculate the send_rate as:</t>
                <artwork><![CDATA[
  send_rate = data_acked / send_elapsed
]]></artwork>
                <t>Using our "delivery" curve model above, the send_rate can be viewed as the
average slope of a "send" curve that traces the amount of data sent on the Y
axis, and the time elapsed on the X axis: the average slope of the transmission
of this flight of data.</t>
              </section>
              <section anchor="delivery-rate">
                <name>Delivery Rate</name>
                <t>Since it is physically impossible to have data delivered faster than it is
sent in a sustained fashion, when the estimator notices that the ack_rate
for a flight is faster than the send rate for the flight, it filters out
the implausible ack_rate by capping the delivery rate sample to be no higher
than the send rate.</t>
                <t>More precisely, over the interval between each transmission and corresponding
ACK, the sender calculates a delivery rate sample, "delivery_rate", using
the minimum of the rate at which packets were acknowledged or the rate at
which they were sent:</t>
                <artwork><![CDATA[
  delivery_rate = min(send_rate, ack_rate)
]]></artwork>
                <t>Since ack_rate and send_rate both have data_acked as a numerator, this can
be computed more efficiently with a single division (instead of two), as
follows:</t>
                <artwork><![CDATA[
  delivery_elapsed = max(ack_elapsed, send_elapsed)
  delivery_rate = data_acked / delivery_elapsed
]]></artwork>
              </section>
            </section>
            <section anchor="tracking-application-limited-phases">
              <name>Tracking application-limited phases</name>
              <t>In application-limited phases the transmission rate is limited by the
sending application rather than the congestion control algorithm. Modern
transport protocol connections are often application-limited, either due
to request/response workloads (e.g., Web traffic, RPC traffic) or because the
sender transmits data in chunks (e.g., adaptive streaming video).</t>
              <t>Knowing whether a delivery rate sample was application-limited is crucial
for congestion control algorithms and applications to use the estimated delivery
rate samples properly. For example, congestion control algorithms likely
do not want to react to a delivery rate that is lower simply because the
sender is application-limited; for congestion control the key metric is the
rate at which the network path can deliver data, and not simply the rate
at which the application happens to be transmitting data at any moment.</t>
              <t>To track this, the estimator marks a bandwidth sample as application-limited
if there was some moment during the sampled flight of data packets when there
was no data ready to send.</t>
              <t>The algorithm detects that an application-limited phase has started when
the sending application requests to send new data, or the connection's
retransmission mechanisms decide to retransmit data, and the connection meets
all of the following conditions:</t>
              <ol spacing="normal" type="1"><li>
                  <t>The transport send buffer has less than one SMSS of unsent data available
  to send.</t>
                </li>
                <li>
                  <t>The sending flow is not currently in the process of transmitting a packet.</t>
                </li>
                <li>
                  <t>The amount of data considered in flight is less than the congestion window
  (cwnd).</t>
                </li>
                <li>
                  <t>All the packets considered lost have been retransmitted.</t>
                </li>
              </ol>
              <t>If these conditions are all met then the sender has run out of data to feed the
network. This would effectively create a "bubble" of idle time in the data
pipeline. This idle time means that any delivery rate sample obtained from this
data packet, and any rate sample from a packet that follows it in the next
round trip, is going to be an application-limited sample that potentially
underestimates the true available bandwidth. Thus, when the algorithm marks a
transport flow as application-limited, it marks all bandwidth samples for the
next round trip as application-limited (at which point, the "bubble" can be
said to have exited the data pipeline).</t>
              <section anchor="considerations-related-to-receiver-flow-control-limits">
                <name>Considerations Related to Receiver Flow Control Limits</name>
                <t>In some cases receiver flow control limits (such as the TCP <xref target="RFC9293"/>
advertised receive window, RCV.WND) are the factor limiting the
delivery rate. This algorithm treats cases where the delivery rate was constrained
by such conditions the same as it treats cases where the delivery rate is
constrained by in-network bottlenecks. That is, it treats receiver bottlenecks
the same as network bottlenecks. This has a conceptual symmetry and has worked
well in practice for congestion control and telemetry purposes.</t>
              </section>
            </section>
          </section>
          <section anchor="detailed-delivery-rate-sampling-algorithm">
            <name>Detailed Delivery Rate Sampling Algorithm</name>
            <section anchor="variables">
              <name>Variables</name>
              <section anchor="per-connection-c-state">
                <name>Per-connection (C) state</name>
                <t>This algorithm requires the following new state variables for each transport
connection:</t>
                <t>C.delivered: The total amount of data (measured in octets or in packets)
delivered so far over the lifetime of the transport connection. This does
not include pure ACK packets.</t>
                <t>C.delivered_time: The wall clock time when C.delivered was last updated.</t>
                <t>C.first_sent_time: If packets are in flight, then this holds the send time of
the packet that was most recently marked as delivered. Else, if the connection
was recently idle, then this holds the send time of most recently sent packet.</t>
                <t>C.app_limited: The index of the last transmitted packet marked as
application-limited, or 0 if the connection is not currently
application-limited.</t>
                <t>We also assume that the transport protocol sender implementation tracks the
following state per connection. If the following state variables are not
tracked by an existing implementation, all the following parameters MUST
be tracked to implement this algorithm:</t>
                <t>C.write_seq: The data sequence number one higher than that of the last octet
queued for transmission in the transport layer write buffer.</t>
                <t>C.pending_transmissions: The number of bytes queued for transmission on the
sending host at layers lower than the transport layer (i.e. network layer,
traffic shaping layer, network device layer).</t>
                <t>C.lost_out: The number of packets in the current outstanding window that
are marked as lost.</t>
                <t>C.retrans_out: The number of packets in the current outstanding window that
are being retransmitted.</t>
                <t>C.pipe: The sender's estimate of the amount of data outstanding in the network
(measured in octets or packets). This includes data packets in the current
outstanding window that are inflight and have not been acknowledged or marked lost
(e.g. "pipe" from <xref target="RFC6675"/> or "bytes_in_flight" from <xref target="RFC9002"/>).
This does not include pure ACK packets.</t>
              </section>
              <section anchor="per-packet-p-state">
                <name>Per-packet (P) state</name>
                <t>This algorithm requires the following new state variables for each packet
that has been transmitted but has not been acknowledged:</t>
                <t>P.delivered: C.delivered when the packet was sent from transport connection
C.</t>
                <t>P.delivered_time: C.delivered_time when the packet was sent.</t>
                <t>P.first_sent_time: C.first_sent_time when the packet was sent.</t>
                <t>P.is_app_limited: true if C.app_limited was non-zero when the packet was
sent, else false.</t>
                <t>P.sent_time: The time when the packet was sent.</t>
              </section>
              <section anchor="rate-sample-rs-output">
                <name>Rate Sample (rs) Output</name>
                <t>This algorithm provides its output in a RateSample structure rs, containing
the following fields:</t>
                <t>rs.delivery_rate: The delivery rate sample (in most cases rs.delivered /
rs.interval).</t>
                <t>rs.is_app_limited: The P.is_app_limited from the most recent packet delivered;
indicates whether the rate sample is application-limited.</t>
                <t>rs.interval: The length of the sampling interval.</t>
                <t>rs.delivered: The amount of data marked as delivered over the sampling interval.</t>
                <t>rs.prior_delivered: The P.delivered count from the most recent packet delivered.</t>
                <t>rs.prior_time: The P.delivered_time from the most recent packet delivered.</t>
                <t>rs.send_elapsed: Send time interval calculated from the most recent packet
delivered (see the "Send Rate" section above).</t>
                <t>rs.ack_elapsed: ACK time interval calculated from the most recent packet
delivered (see the "ACK Rate" section above).</t>
              </section>
            </section>
            <section anchor="transmitting-a-data-packet">
              <name>Transmitting a data packet</name>
              <t>Upon transmitting a data packet, the sender snapshots the current delivery
information in per-packet state. This will allow the sender
to generate a rate sample later, in the UpdateRateSample() step, when the
packet is (S)ACKed.</t>
              <t>If there are packets already in flight, then we need to start delivery rate
samples from the time we received the most recent ACK, to try to ensure that
we include the full time the network needs to deliver all in-flight packets.
If there are no packets in flight yet, then we can start the delivery rate
interval at the current time, since we know that any ACKs after now indicate
that the network was able to deliver those  packets completely in the sampling
interval between now and the next ACK.</t>
              <t>After each packet transmission, the sender executes the following steps:</t>
              <artwork><![CDATA[
  SendPacket(Packet P):
    if (SND.NXT == SND.UNA)  /* no packets in flight yet? */
      C.first_sent_time  = C.delivered_time = P.sent_time

    P.first_sent_time = C.first_sent_time
    P.delivered_time  = C.delivered_time
    P.delivered       = C.delivered
    P.is_app_limited  = (C.app_limited != 0)
]]></artwork>
            </section>
            <section anchor="upon-receiving-an-ack">
              <name>Upon receiving an ACK</name>
              <t>When an ACK arrives, the sender invokes GenerateRateSample() to fill in a
rate sample. For each  packet that was newly acknowledged, UpdateRateSample()
updates the rate sample based on a snapshot of connection delivery information
from the time at which the packet was last transmitted. UpdateRateSample()
is invoked multiple times when a stretched ACK acknowledges multiple data
packets. In this case we use the information from the most recently sent
packet, i.e., the packet with the highest "P.delivered" value.</t>
              <artwork><![CDATA[
  /* Upon receiving ACK, fill in delivery rate sample rs. */
  GenerateRateSample(RateSample rs):
    for each newly acknowledged packet P
      UpdateRateSample(P, rs)

    /* Clear app-limited field if bubble is ACKed and gone. */
    if (C.app_limited and C.delivered > C.app_limited)
      C.app_limited = 0

    if (rs.prior_time == 0)
      return false  /* nothing delivered on this ACK */

    /* Use the longer of the send_elapsed and ack_elapsed */
    rs.interval = max(rs.send_elapsed, rs.ack_elapsed)

    rs.delivered = C.delivered - rs.prior_delivered

    /* Normally we expect interval >= MinRTT.
     * Note that rate may still be overestimated when a spuriously
     * retransmitted skb was first (s)acked because "interval"
     * is under-estimated (up to an RTT). However, continuously
     * measuring the delivery rate during loss recovery is crucial
     * for connections that suffer heavy or prolonged losses.
     */
    if (rs.interval <  MinRTT(tp))
      rs.interval = -1
      return false  /* no reliable sample */

    if (rs.interval != 0)
      rs.delivery_rate = rs.delivered / rs.interval

    return true;  /* we filled in rs with a rate sample */

  /* Update rs when a packet is acknowledged. */
  UpdateRateSample(Packet P, RateSample rs):
    if (P.delivered_time == 0)
      return /* P already acknowledged */

    C.delivered += P.data_length
    C.delivered_time = Now()

    /* Update info using the newest packet: */
    if (!rs.has_data or IsNewestPacket(P, rs))
      rs.has_data         = true
      rs.prior_delivered  = P.delivered
      rs.prior_time       = P.delivered_time
      rs.is_app_limited   = P.is_app_limited
      rs.send_elapsed     = P.sent_time - P.first_sent_time
      rs.ack_elapsed      = C.delivered_time - P.delivered_time
      rs.last_end_seq     = P.end_seq
      C.first_sent_time   = P.sent_time

    /* Mark the packet as delivered once it's acknowleged. */
    P.delivered_time = 0

  /* Is the given Packet the most recently sent packet
   * that has been delivered? */
  IsNewestPacket(Packet P, RateSample rs):
    return (P.sent_time > C.first_sent_time or
            (P.sent_time == C.first_sent_time and
             after(P.end_seq, rs.last_end_seq))
]]></artwork>
            </section>
            <section anchor="detecting-application-limited-phases">
              <name>Detecting application-limited phases</name>
              <t>An application-limited phase starts when the connection decides to send more
data, at a point in time when the connection had previously run out of data.
Some decisions to send more data are triggered by the application writing
more data to the connection, and some are triggered by loss detection (during
ACK processing or upon the triggering of a timer) estimating that some sequence
ranges need to be retransmitted. To detect all such cases, the algorithm
calls CheckIfApplicationLimited() to check for application-limited behavior in
the following situations:</t>
              <ul spacing="normal">
                <li>
                  <t>The sending application asks the transport layer to send more data; i.e.,
upon each write from the application, before new application data is enqueued
in the transport send buffer or transmitted.</t>
                </li>
                <li>
                  <t>At the beginning of ACK processing, before updating the estimated number
of packets in flight, and before congestion control modifies the cwnd or
pacing rate.</t>
                </li>
                <li>
                  <t>At the beginning of connection timer processing, for all timers that might
result in the transmission of one or more data segments. For example: RTO
timers, TLP timers, RACK reordering timers, or Zero Window Probe timers.</t>
                </li>
              </ul>
              <t>When checking for application-limited behavior, the connection checks all the
conditions previously described in the "Tracking application-limited phases"
section, and if all are met then it marks the connection as
application-limited:</t>
              <artwork><![CDATA[
  CheckIfApplicationLimited():
    if (C.write_seq - SND.NXT < SND.MSS and
        C.pending_transmissions == 0 and
        C.pipe < cwnd and
        C.lost_out <= C.retrans_out)
      C.app_limited = (C.delivered + C.pipe) ? : 1
]]></artwork>
            </section>
          </section>
          <section anchor="delivery-rate-sampling-discussion">
            <name>Delivery Rate Sampling Discussion</name>
            <section anchor="offload-mechanisms">
              <name>Offload Mechanisms</name>
              <t>If a transport sender implementation uses an offload mechanism (such as TSO,
GSO, etc.) to combine multiple SMSS of data into a single packet "aggregate"
for the purposes of scheduling transmissions, then it is RECOMMENDED that
the per-packet state be tracked for each packet "aggregate" rather than each
SMSS. For simplicity this document refers to such state as "per-packet",
whether it is per "aggregate" or per SMSS.</t>
            </section>
            <section anchor="impact-of-ack-losses">
              <name>Impact of ACK losses</name>
              <t>Delivery rate samples are generated upon receiving each ACK; ACKs may contain
both cumulative and selective acknowledgment information. Losing an ACK results
in losing the delivery rate sample corresponding to that ACK, and generating a
delivery rate sample at later a time (upon the arrival of the next ACK). This
can underestimate the delivery rate due the artificially inflated
"rs.interval". The impact of this effect is mitigated using the BBR.max_bw
filter.</t>
            </section>
            <section anchor="impact-of-packet-reordering">
              <name>Impact of packet reordering</name>
              <t>This algorithm is robust to packet reordering; it makes no assumptions about
the order in which packets are delivered or ACKed. In particular, for a
particular packet P, it does not matter which packets are delivered between the
transmission of P and the ACK of packet P, since C.delivered will be
incremented appropriately in any case.</t>
            </section>
            <section anchor="impact-of-packet-loss-and-retransmissions">
              <name>Impact of packet loss and retransmissions</name>
              <t>There are several possible approaches for handling cases where a delivery
rate sample is based on a retransmitted packet.</t>
              <t>If the transport protocol supports unambiguous ACKs for retransmitted data
(as in QUIC <xref target="RFC9000"/>) then the algorithm is perfectly robust to retransmissions,
because the starting packet, P, for the sample can be unambiguously retrieved.</t>
              <t>If the transport protocol, like TCP <xref target="RFC9293"/>, has ambiguous ACKs for
retransmitted sequence ranges, then the following approaches MAY be used:</t>
              <ol spacing="normal" type="1"><li>
                  <t>The sender MAY choose to filter out implausible delivery rate samples, as
  described in the GenerateRateSample() step in the "Upon receiving an ACK"
  section, by discarding samples whose rs.interval is lower than the minimum
  RTT seen on the connection.</t>
                </li>
                <li>
                  <t>The sender MAY choose to skip the generation of a delivery rate sample for
  a retransmitted sequence range.</t>
                </li>
              </ol>
              <section anchor="connections-without-sack">
                <name>TCP Connections without SACK</name>
                <t>Whenever possibile, TCP connections using BBR as a congestion controller SHOULD
use both SACK and timestamps. Failure to do so will cause BBR's RTT and
bandwidth measurements to be much less accurate.</t>
                <t>When using TCP without SACK (i.e., either or both ends of the connections do
not accept SACK), this algorithm can be extended to estimate approximate
delivery rates using duplicate ACKs (much like Reno and <xref target="RFC5681"/> estimates
that each duplicate ACK indicates that a data packet has been delivered).</t>
              </section>
            </section>
          </section>
        </section>
        <section anchor="bbrmaxbw-max-filter">
          <name>BBR.max_bw Max Filter</name>
          <t>Delivery rate samples are often below the typical bottleneck bandwidth
available to the flow, due to "noise" introduced by random variation in
physical transmission processes (e.g. radio link layer noise) or queues or
along the network path.  To filter these effects BBR uses a max filter: BBR
estimates BBR.max_bw using the windowed maximum recent delivery rate sample
seen by the connection over recent history.</t>
          <t>The BBR.max_bw max filter window covers a time period extending over the
past two ProbeBW cycles. The BBR.max_bw max filter window length is driven
by trade-offs among several considerations:</t>
          <ul spacing="normal">
            <li>
              <t>It is long enough to cover at least one entire ProbeBW cycle (see the
"ProbeBW" section). This ensures that the window contains at least some
delivery rate samples that are the result of data transmitted with a
super-unity pacing_gain (a pacing_gain larger than 1.0). Such super-unity
delivery rate samples are instrumental in revealing the path's underlying
available bandwidth even when there is noise from delivery rate shortfalls
due to aggregation delays, queuing delays from variable cross-traffic, lossy
link layers with uncorrected losses, or short-term buffer exhaustion (e.g.,
brief coincident bursts in a shallow buffer).</t>
            </li>
            <li>
              <t>It aims to be long enough to cover short-term fluctuations in the network's
delivery rate due to the aforementioned sources of noise. In particular, the
delivery rate for radio link layers (e.g., wifi and cellular technologies)
can be highly variable, and the filter window needs to be long enough to
remember "good" delivery rate samples in order to be robust to such
variations.</t>
            </li>
            <li>
              <t>It aims to be short enough to respond in a timely manner to sustained
reductions in the bandwidth available to a flow, whether this is because
other flows are using a larger share of the bottleneck, or the bottleneck
link service rate has reduced due to layer 1 or layer 2 changes, policy
changes, or routing changes. In any of these cases, existing BBR flows
traversing the bottleneck should, in a timely manner, reduce their BBR.max_bw
estimates and thus pacing rate and in-flight data, in order to match the
sending behavior to the new available bandwidth.</t>
            </li>
          </ul>
        </section>
        <section anchor="bbrmaxbw-and-application-limited-delivery-rate-samples">
          <name>BBR.max_bw and Application-limited Delivery Rate Samples</name>
          <t>Transmissions can be application-limited, meaning the transmission rate is
limited by the application rather than the congestion control algorithm.  This
is quite common because of request/response traffic. When there is a
transmission opportunity but no data to send, the delivery rate sampler marks
the corresponding bandwidth sample(s) as application-limited
<xref target="delivery-rate-samples"/>.  The BBR.max_bw estimator carefully decides which
samples to include in the bandwidth model to ensure that BBR.max_bw reflects
network limits, not application limits. By default, the estimator discards
application-limited samples, since by definition they reflect application
limits. However, the estimator does use application-limited samples if the
measured delivery rate happens to be larger than the current BBR.max_bw
estimate, since this indicates the current BBR.Max_bw estimate is too low.</t>
        </section>
        <section anchor="updating-the-bbrmaxbw-max-filter">
          <name>Updating the BBR.max_bw Max Filter</name>
          <t>For every ACK that acknowledges some data packets as delivered, BBR invokes
BBRUpdateMaxBw() to update the BBR.max_bw estimator as follows (here
rs.delivery_rate is the delivery rate sample obtained from the ACK that is
being processed, as specified in <xref target="delivery-rate-samples"/>):</t>
          <artwork><![CDATA[
  BBRUpdateMaxBw()
    BBRUpdateRound()
    if (rs.delivery_rate >= BBR.max_bw || !rs.is_app_limited)
        BBR.max_bw = UpdateWindowedMaxFilter(
                      filter=BBR.MaxBwFilter,
                      value=rs.delivery_rate,
                      time=BBR.cycle_count,
                      window_length=MaxBwFilterLen)
]]></artwork>
        </section>
        <section anchor="tracking-time-for-the-bbrmaxbw-max-filter">
          <name>Tracking Time for the BBR.max_bw Max Filter</name>
          <t>BBR tracks time for the BBR.max_bw filter window using a virtual
(non-wall-clock) time tracked by counting the cyclical progression through
ProbeBW cycles.  Each time through the Probe bw cycle, one round trip after
exiting ProbeBW_UP (the point at which the flow has its best chance to measure
the highest throughput of the cycle), BBR increments BBR.cycle_count, the
virtual time used by the BBR.max_bw filter window. Note that BBR.cycle_count
only needs to be tracked with a single bit, since the BBR.max_bw filter only
needs to track samples from two time slots: the previous ProbeBW cycle and the
current ProbeBW cycle:</t>
          <artwork><![CDATA[
  BBRAdvanceMaxBwFilter():
    BBR.cycle_count++
]]></artwork>
        </section>
        <section anchor="bbrminrtt-estimated-minimum-round-trip-time">
          <name>BBR.min_rtt: Estimated Minimum Round-Trip Time</name>
          <t>BBR.min_rtt is BBR's estimate of the round-trip propagation delay of the path
over which a transport connection is sending. The path's round-trip propagation
delay determines the minimum amount of time over which the connection must be
willing to sustain transmissions at the BBR.bw rate, and thus the minimum
amount of data needed in-flight, for the connection to reach full utilization
(a "Full Pipe"). The round-trip propagation delay can vary over the life of a
connection, so BBR continually estimates BBR.min_rtt using recent round-trip
delay samples.</t>
          <section anchor="round-trip-time-samples-for-estimating-bbrminrtt">
            <name>Round-Trip Time Samples for Estimating BBR.min_rtt</name>
            <t>For every data packet a connection sends, BBR calculates an RTT sample that
measures the time interval from sending a data packet until that packet is
acknowledged.</t>
            <t>The only divergence from RTT estimation for retransmission timeouts is in the
case where a given acknowledgment ACKs more than one data packet. In order to
be conservative and schedule long timeouts to avoid spurious retransmissions,
the maximum among such potential RTT samples is typically used for computing
retransmission timeouts; i.e., SRTT is typically calculated using the data
packet with the earliest transmission time. By contrast, in order for BBR to
try to reach the minimum amount of data in flight to fill the pipe, BBR uses
the minimum among such potential RTT samples; i.e., BBR calculates the RTT
using the data packet with the latest transmission time.</t>
          </section>
          <section anchor="bbrminrtt-min-filter">
            <name>BBR.min_rtt Min Filter</name>
            <t>RTT samples tend to be above the round-trip propagation delay of the path,
due to "noise" introduced by random variation in physical transmission processes
(e.g. radio link layer noise), queues along the network path, the receiver's
delayed ack strategy, ack aggregation, etc. Thus to filter out these effects
BBR uses a min filter: BBR estimates BBR.min_rtt using the minimum recent
RTT sample seen by the connection over that past MinRTTFilterLen seconds.
(Many of the same network effects that can decrease delivery rate measurements
can increase RTT samples, which is why BBR's min-filtering approach for RTTs
is the complement of its max-filtering approach for delivery rates.)</t>
            <t>The length of the BBR.min_rtt min filter window is MinRTTFilterLen = 10 secs.
This is driven by trade-offs among several considerations:</t>
            <ul spacing="normal">
              <li>
                <t>The MinRTTFilterLen is longer than ProbeRTTInterval, so that it covers an
entire ProbeRTT cycle (see the "ProbeRTT" section below). This helps ensure
that the window can contain RTT samples that are the result of data
transmitted with inflight below the estimated BDP of the flow. Such RTT
samples are important for helping to reveal the path's underlying two-way
propagation delay even when the aforementioned "noise" effects can often
obscure it.</t>
              </li>
              <li>
                <t>The MinRTTFilterLen aims to be long enough to avoid needing to cut in-flight
and throughput often. Measuring two-way propagation delay requires in-flight
to be at or below BDP, which risks  some amount of underutilization, so BBR
uses a filter window long enough that such underutilization events can be
rare.</t>
              </li>
              <li>
                <t>The MinRTTFilterLen aims to be long enough that many applications have a
"natural" moment of silence or low utilization that can cut in-flight below
BDP and naturally serve to refresh the BBR.min_rtt, without requiring BBR to
force an artificial cut in in-flight. This applies to many popular
applications, including Web, RPC, chunked audio or video traffic.</t>
              </li>
              <li>
                <t>The MinRTTFilterLen aims to be short enough to respond in a timely manner to
real increases in the two-way propagation delay of the path, e.g. due to
route changes, which are expected to typically happen on longer time scales.</t>
              </li>
            </ul>
            <t>A BBR implementation MAY use a generic windowed min filter to track BBR.min_rtt.
However, a significant savings in space and improvement in freshness can
be achieved by integrating the BBR.min_rtt estimation into the ProbeRTT state
machine, so this document discusses that approach in the ProbeRTT section.</t>
          </section>
        </section>
        <section anchor="bbroffloadbudget">
          <name>BBR.offload_budget</name>
          <t>BBR.offload_budget is the estimate of the minimum volume of data necessary
to achieve full throughput using sender (TSO/GSO) and receiver (LRO, GRO)
host offload mechanisms.  This varies based on the transport protocol and
operating environment.</t>
          <t>For TCP, offload_budget can be computed as follows:</t>
          <artwork><![CDATA[
    BBRUpdateOffloadBudget():
      BBR.offload_budget = 3 * BBR.send_quantum
]]></artwork>
          <t>The factor of 3 is chosen to allow maintaining at least:</t>
          <ul spacing="normal">
            <li>
              <t>1 quantum in the sending host's queuing discipline layer</t>
            </li>
            <li>
              <t>1 quantum being segmented in the sending host TSO/GSO engine</t>
            </li>
            <li>
              <t>1 quantum being reassembled or otherwise remaining unacknowledged due to
the receiver host's LRO/GRO/delayed-ACK engine</t>
            </li>
          </ul>
        </section>
        <section anchor="bbrextraacked">
          <name>BBR.extra_acked</name>
          <t>BBR.extra_acked is a volume of data that is the estimate of the recent degree
of aggregation in the network path. For each ACK, the algorithm computes
a sample of the estimated extra ACKed data beyond the amount of data that
the sender expected to be ACKed over the timescale of a round-trip, given
the BBR.bw. Then it computes BBR.extra_acked as the windowed maximum sample
over the last BBRExtraAckedFilterLen=10 packet-timed round-trips. If the
ACK rate falls below the expected bandwidth, then the algorithm estimates
an aggregation episode has terminated, and resets the sampling interval to
start from the current time.</t>
          <t>The BBR.extra_acked thus reflects the recently-measured magnitude of data
and ACK aggregation effects such as batching and slotting at shared-medium
L2 hops (wifi, cellular, DOCSIS), as well as end-host offload mechanisms
(TSO, GSO, LRO, GRO), and end host or middlebox ACK decimation/thinning.</t>
          <t>BBR augments its cwnd by BBR.extra_acked to allow the connection to keep
sending during inter-ACK silences, to an extent that matches the recently
measured degree of aggregation.</t>
          <t>More precisely, this is computed as:</t>
          <artwork><![CDATA[
  BBRUpdateACKAggregation():
    /* Find excess ACKed beyond expected amount over this interval */
    interval = (Now() - BBR.extra_acked_interval_start)
    expected_delivered = BBR.bw * interval
    /* Reset interval if ACK rate is below expected rate: */
    if (BBR.extra_acked_delivered <= expected_delivered)
        BBR.extra_acked_delivered = 0
        BBR.extra_acked_interval_start = Now()
        expected_delivered = 0
    BBR.extra_acked_delivered += rs.newly_acked
    extra = BBR.extra_acked_delivered - expected_delivered
    extra = min(extra, cwnd)
    if (BBR.full_bw_reached)
      filter_len = BBRExtraAckedFilterLen
    else
      filter_len = 1  /* in Startup, just remember 1 round */
    BBR.extra_acked =
      UpdateWindowedMaxFilter(
        filter=BBR.ExtraACKedFilter,
        value=extra,
        time=BBR.round_count,
        window_length=filter_len)
]]></artwork>
        </section>
        <section anchor="updating-the-model-upon-packet-loss">
          <name>Updating the Model Upon Packet Loss</name>
          <t>In every state, BBR responds to (filtered) congestion signals, including
loss. The response to those congestion signals depends on the flow's current
state, since the information that the flow can infer depends on what the
flow was doing when the flow experienced the signal.</t>
          <section anchor="probing-for-bandwidth-in-startup">
            <name>Probing for Bandwidth In Startup</name>
            <t>In Startup, if the congestion signals meet the Startup exit criteria, the flow
exits Startup and enters Drain (see <xref target="exiting-startup-based-on-packet-loss"/>).</t>
          </section>
          <section anchor="probing-for-bandwidth-in-probebw">
            <name>Probing for Bandwidth In ProbeBW</name>
            <t>BBR searches for the maximum volume of data that can be sensibly placed
in-flight in the network. A key precondition is that the flow is actually
trying robustly to find that operating point. To implement this, when a flow is
in ProbeBW, and an ACK covers data sent in one of the accelerating phases
(REFILL or UP), and the ACK indicates that the loss rate over the past round
trip exceeds the queue pressure objective, and the flow is not application
limited, and has not yet responded to congestion signals from the most recent
REFILL or UP phase, then the flow estimates that the volume of data it allowed
in flight exceeded what matches the current delivery process on the path, and
reduces BBR.inflight_longterm:</t>
            <artwork><![CDATA[
  /* Do loss signals suggest inflight is too high?
   * If so, react. */
  IsInflightTooHigh():
    if (IsInflightTooHigh(rs))
      if (BBR.bw_probe_samples)
        BBRHandleInflightTooHigh()
      return true  /* inflight too high */
    else
      return false /* inflight not too high */

  IsInflightTooHigh():
    return (rs.lost > rs.tx_in_flight * BBRLossThresh)

  BBRHandleInflightTooHigh():
    BBR.bw_probe_samples = 0;  /* only react once per bw probe */
    if (!rs.is_app_limited)
      BBR.inflight_longterm = max(rs.tx_in_flight,
                            BBRTargetInflight() * BBRBeta))
    If (BBR.state == ProbeBW_UP)
      BBRStartProbeBW_DOWN()
]]></artwork>
            <t>Here rs.tx_in_flight is the amount of data that was estimated to be in flight
when the most recently ACKed packet was sent. And the BBRBeta (0.7x) bound
is to try to ensure that BBR does not react more dramatically than CUBIC's
0.7x multiplicative decrease factor.</t>
            <t>Some loss detection algorithms, including RACK <xref target="RFC8985"/> or QUIC loss
detection <xref target="RFC9002"/>, delay loss marking to wait for potential
reordering, so packets can be declared lost long after the loss itself.
happened. In such cases, the tx_in_flight for the delivered sequence range
that allowed the loss to be detected may be considerably smaller than the
tx_in_flight of the lost packet itself. In such cases using the former
tx_in_flight rather than the latter can cause BBR.inflight_longterm to be
significantly underestimated. To avoid such issues, BBR processes each loss
detection event to more precisely estimate the volume of in-flight data at
which loss rates cross BBRLossThresh, noting that this may have happened
mid-way through some TSO/GSO offload burst (represented as a "packet" in
the pseudocode in this document). To estimate this threshold volume of data,
we can solve for "lost_prefix" in the following way, where inflight_prev
represents the volume of in-flight data preceding this packet, and lost_prev
represents the data lost among that previous in-flight data.</t>
            <t>First we start with:</t>
            <artwork><![CDATA[
  lost / inflight >= BBRLossThresh
]]></artwork>
            <t>Expanding this, we get:</t>
            <artwork><![CDATA[
  (lost_prev + lost_prefix) /    >= BBRLossThresh
  (inflight_prev + lost_prefix)
]]></artwork>
            <t>Solving for lost_prefix, we arrive at:</t>
            <artwork><![CDATA[
  lost_prefix >= (BBRLossThresh * inflight_prev - lost_prev) /
                    (1 - BBRLossThresh)
]]></artwork>
            <t>In pseudocode:</t>
            <artwork><![CDATA[
  BBRNoteLoss()
    if (!BBR.loss_in_round)   /* first loss in this round trip? */
      BBR.loss_round_delivered = C.delivered
    BBR.loss_in_round = 1

  BBRHandleLostPacket(packet):
    BBRNoteLoss()
    if (!BBR.bw_probe_samples)
      return /* not a packet sent while probing bandwidth */
    rs.tx_in_flight = packet.tx_in_flight /* inflight at transmit */
    rs.lost = C.lost - packet.lost /* data lost since transmit */
    rs.is_app_limited = packet.is_app_limited;
    if (IsInflightTooHigh(rs))
      rs.tx_in_flight = BBRInflightLongtermFromLostPacket(rs, packet)
      BBRHandleInflightTooHigh(rs)

  /* At what prefix of packet did losses exceed BBRLossThresh? */
  BBRInflightLongtermFromLostPacket(rs, packet):
    size = packet.size
    /* What was in flight before this packet? */
    inflight_prev = rs.tx_in_flight - size
    /* What was lost before this packet? */
    lost_prev = rs.lost - size
    lost_prefix = (BBRLossThresh * inflight_prev - lost_prev) /
                  (1 - BBRLossThresh)
    /* At what inflight value did losses cross BBRLossThresh? */
    inflight = inflight_prev + lost_prefix
    return inflight
]]></artwork>
          </section>
          <section anchor="when-not-probing-for-bandwidth">
            <name>When not Probing for Bandwidth</name>
            <t>When not explicitly accelerating to probe for bandwidth (Drain, ProbeRTT,
ProbeBW_DOWN, ProbeBW_CRUISE), BBR  responds to loss by slowing down to some
extent. This is because loss suggests that the available bandwidth and safe
volume of in-flight data may have decreased recently, and the flow needs
to adapt, slowing down toward the latest delivery process. BBR flows implement
this response by reducing the short-term model parameters, BBR.bw_shortterm and
BBR.inflight_shortterm.</t>
            <t>When encountering packet loss when the flow is not probing for bandwidth,
the strategy is to gradually adapt to the current measured delivery process
(the rate and volume of data that is delivered through the network path over
the last round trip). This applies generally: whether in fast recovery, RTO
recovery, TLP recovery; whether application-limited or not.</t>
            <t>There are two key parameters the algorithm tracks, to measure the current
delivery process:</t>
            <t>BBR.bw_latest: a 1-round-trip max of delivered bandwidth (rs.delivery_rate).</t>
            <t>BBR.inflight_latest: a 1-round-trip max of delivered volume of data
(rs.delivered).</t>
            <t>Upon the ACK at the end of each round that encountered a newly-marked loss,
the flow updates its model (bw_shortterm and inflight_shortterm) as follows:</t>
            <artwork><![CDATA[
      bw_shortterm = max(       bw_latest, BBRBeta *       bw_shortterm )
inflight_shortterm = max( inflight_latest, BBRBeta * inflight_shortterm )
]]></artwork>
            <t>This logic can be represented as follows:</t>
            <artwork><![CDATA[
  /* Near start of ACK processing: */
  BBRUpdateLatestDeliverySignals():
    BBR.loss_round_start = 0
    BBR.bw_latest       = max(BBR.bw_latest,       rs.delivery_rate)
    BBR.inflight_latest = max(BBR.inflight_latest, rs.delivered)
    if (rs.prior_delivered >= BBR.loss_round_delivered)
      BBR.loss_round_delivered = C.delivered
      BBR.loss_round_start = 1

  /* Near end of ACK processing: */
  BBRAdvanceLatestDeliverySignals():
    if (BBR.loss_round_start)
      BBR.bw_latest       = rs.delivery_rate
      BBR.inflight_latest = rs.delivered

  BBRResetCongestionSignals():
    BBR.loss_in_round = 0
    BBR.bw_latest = 0
    BBR.inflight_latest = 0

  /* Update congestion state on every ACK */
  BBRUpdateCongestionSignals():
    BBRUpdateMaxBw()
    if (!BBR.loss_round_start)
      return  /* wait until end of round trip */
    BBRAdaptLowerBoundsFromCongestion()  /* once per round, adapt */
    BBR.loss_in_round = 0

  /* Once per round-trip respond to congestion */
  BBRAdaptLowerBoundsFromCongestion():
    if (BBRIsProbingBW())
      return
    if (BBR.loss_in_round)
      BBRInitLowerBounds()
      BBRLossLowerBounds()

  /* Handle the first congestion episode in this cycle */
  BBRInitLowerBounds():
    if (BBR.bw_shortterm == Infinity)
      BBR.bw_shortterm = BBR.max_bw
    if (BBR.inflight_shortterm == Infinity)
      BBR.inflight_shortterm = cwnd

  /* Adjust model once per round based on loss */
  BBRLossLowerBounds()
    BBR.bw_shortterm       = max(BBR.bw_latest,
                          BBRBeta * BBR.bw_shortterm)
    BBR.inflight_shortterm = max(BBR.inflight_latest,
                          BBRBeta * BBR.inflight_shortterm)

  BBRResetLowerBounds():
    BBR.bw_shortterm       = Infinity
    BBR.inflight_shortterm = Infinity

  BBRBoundBWForModel():
    BBR.bw = min(BBR.max_bw, BBR.bw_shortterm)

]]></artwork>
          </section>
        </section>
      </section>
      <section anchor="updating-control-parameters">
        <name>Updating Control Parameters</name>
        <t>BBR uses three distinct but interrelated control parameters: pacing rate,
send quantum, and congestion window (cwnd).</t>
        <section anchor="summary-of-control-behavior-in-the-state-machine">
          <name>Summary of Control Behavior in the State Machine</name>
          <t>The following table summarizes how BBR modulates the control parameters in
each state. In the table below, the semantics of the columns are as follows:</t>
          <ul spacing="normal">
            <li>
              <t>State: the state in the BBR state machine, as depicted in the "State
Transition Diagram" section above.</t>
            </li>
            <li>
              <t>Tactic: The tactic chosen from the "State Machine Tactics" in
<xref target="state-machine-tactics"/>: "accel" refers to acceleration, "decel" to
deceleration, and "cruise" to cruising.</t>
            </li>
            <li>
              <t>Pacing Gain: the value used for BBR.pacing_gain in the given state.</t>
            </li>
            <li>
              <t>Cwnd Gain: the value used for BBR.cwnd_gain in the given state.</t>
            </li>
            <li>
              <t>Rate Cap: the rate values applied as bounds on the BBR.max_bw value applied
to compute BBR.bw.</t>
            </li>
            <li>
              <t>Volume Cap: the volume values applied as bounds on the BBR.max_inflight value
to compute cwnd.</t>
            </li>
          </ul>
          <t>The control behavior can be summarized as follows. Upon processing each ACK,
BBR uses the values in the table below to compute BBR.bw in
BBRBoundBWForModel(), and the cwnd in BBRBoundCwndForModel():</t>
          <artwork><![CDATA[
---------------+--------+--------+------+--------------+-----------------
State          | Tactic | Pacing | Cwnd | Rate         | Volume
               |        | Gain   | Gain | Cap          | Cap
---------------+--------+--------+------+--------------+-----------------
Startup        | accel  | 2.77   | 2    | N/A          | N/A
               |        |        |      |              |
---------------+--------+--------+------+--------------+-----------------
Drain          | decel  | 0.5    | 2    | bw_shortterm | inflight_longterm,
               |        |        |      |              | inflight_shortterm
---------------+--------+--------+------+--------------+-----------------
ProbeBW_DOWN   | decel  | 0.90   | 2    | bw_shortterm | inflight_longterm,
               |        |        |      |              | inflight_shortterm
---------------+--------+--------+------+--------------+-----------------
ProbeBW_CRUISE | cruise | 1.0    | 2    | bw_shortterm | 0.85*inflight_longterm
               |        |        |      |              | inflight_shortterm
---------------+--------+--------+------+--------------+-----------------
ProbeBW_REFILL | accel  | 1.0    | 2    |              | inflight_longterm
               |        |        |      |              |
---------------+--------+--------+------+--------------+-----------------
ProbeBW_UP     | accel  | 1.25   | 2.25 |              | inflight_longterm
               |        |        |      |              |
---------------+--------+--------+------+--------------+-----------------
ProbeRTT       | decel  | 1.0    | 0.5  | bw_shortterm | 0.85*inflight_longterm
               |        |        |      |              | inflight_shortterm
---------------+--------+--------+------+--------------+-----------------
]]></artwork>
        </section>
        <section anchor="pacing-rate-bbrpacingrate">
          <name>Pacing Rate: BBR.pacing_rate</name>
          <t>To help match the packet-arrival rate to the bottleneck bandwidth available
to the flow, BBR paces data packets. Pacing enforces a maximum rate at which
BBR schedules quanta of packets for transmission.</t>
          <t>The sending host implements pacing by maintaining inter-quantum spacing at
the time each packet is scheduled for departure, calculating the next departure
time for a packet for a given flow (BBR.next_departure_time) as a function
of the most recent packet size and the current pacing rate, as follows:</t>
          <artwork><![CDATA[
  BBR.next_departure_time = max(Now(), BBR.next_departure_time)
  packet.departure_time = BBR.next_departure_time
  pacing_delay = packet.size / BBR.pacing_rate
  BBR.next_departure_time = BBR.next_departure_time + pacing_delay
]]></artwork>
          <t>To adapt to the bottleneck, in general BBR sets the pacing rate to be
proportional to bw, with a dynamic gain, or scaling factor of proportionality,
called pacing_gain.</t>
          <t>When a BBR flow starts it has no bw estimate (bw is 0). So in this case it
sets an initial pacing rate based on the transport sender implementation's
initial congestion window ("InitialCwnd", e.g. from <xref target="RFC6928"/>), the
initial SRTT (smoothed round-trip time) after the first non-zero RTT
sample, and the initial pacing_gain:</t>
          <artwork><![CDATA[
  BBRInitPacingRate():
    nominal_bandwidth = InitialCwnd / (SRTT ? SRTT : 1ms)
    BBR.pacing_rate =  BBRStartupPacingGain * nominal_bandwidth
]]></artwork>
          <t>After initialization, on each data ACK BBR updates its pacing rate to be
proportional to bw, as long as it estimates that it has filled the pipe
(BBR.full_bw_reached is true; see the "Startup" section for details), or
doing so increases the pacing rate. Limiting the pacing rate updates in this way
helps the connection probe robustly for bandwidth until it estimates it has
reached its full available bandwidth ("filled the pipe"). In particular,
this prevents the pacing rate from being reduced when the connection has only
seen application-limited bandwidth samples. BBR updates the pacing rate on each
ACK by executing the BBRSetPacingRate() step as follows:</t>
          <artwork><![CDATA[
  BBRSetPacingRateWithGain(pacing_gain):
    rate = pacing_gain * bw * (100 - BBRPacingMarginPercent) / 100
    if (BBR.full_bw_reached || rate > BBR.pacing_rate)
      BBR.pacing_rate = rate

  BBRSetPacingRate():
    BBRSetPacingRateWithGain(BBR.pacing_gain)
]]></artwork>
          <t>To help drive the network toward lower queues and low latency while maintaining
high utilization, the BBRPacingMarginPercent constant of 1 aims to cause
BBR to pace at 1% below the bw, on average.</t>
        </section>
        <section anchor="send-quantum-bbrsendquantum">
          <name>Send Quantum: BBR.send_quantum</name>
          <t>In order to amortize per-packet overheads involved in the sending process (host
CPU, NIC processing, and interrupt processing delays), high-performance
transport sender implementations (e.g., Linux TCP) often schedule an aggregate
containing multiple packets (multiple SMSS) worth of data as a single quantum
(using TSO, GSO, or other offload mechanisms). The BBR congestion control
algorithm makes this control decision explicitly, dynamically calculating a
quantum control parameter that specifies the maximum size of these transmission
aggregates. This decision is based on a trade-off:</t>
          <ul spacing="normal">
            <li>
              <t>A smaller quantum is preferred at lower data rates because it results in
shorter packet bursts, shorter queues, lower queueing delays, and lower rates
of packet loss.</t>
            </li>
            <li>
              <t>A bigger quantum can be required at higher data rates because it results
in lower CPU overheads at the sending and receiving hosts, who can ship larger
amounts of data with a single trip through the networking stack.</t>
            </li>
          </ul>
          <t>On each ACK, BBR runs BBRSetSendQuantum() to update BBR.send_quantum  as
follows:</t>
          <artwork><![CDATA[
  BBRSetSendQuantum():
    BBR.send_quantum = BBR.pacing_rate * 1ms
    BBR.send_quantum = min(BBR.send_quantum, 64 KBytes)
    BBR.send_quantum = max(BBR.send_quantum, 2 * SMSS)
]]></artwork>
          <t>A BBR implementation MAY use alternate approaches to select a BBR.send_quantum,
as appropriate for the CPU overheads anticipated for senders and receivers,
and buffering considerations anticipated in the network path. However, for
the sake of the network and other users, a BBR implementation SHOULD attempt
to use the smallest feasible quanta.</t>
        </section>
        <section anchor="congestion-window">
          <name>Congestion Window</name>
          <t>The congestion window, or cwnd, controls the maximum volume of data BBR allows
in flight in the network at any time. It is the maximum volume of in-flight
data that the algorithm estimates is appropriate for matching the current
network path delivery process, given all available signals in the model,
at any time scale. BBR adapts the cwnd based on its model of the network
path and the state machine's decisions about how to probe that path.</t>
          <t>By default, BBR grows its cwnd to meet its BBR.max_inflight, which models
what's required for achieving full throughput, and as such is scaled to adapt
to the estimated BDP computed from its path model. But BBR's selection of cwnd
is designed to explicitly trade off among competing considerations that
dynamically adapt to various conditions. So in loss recovery BBR more
conservatively adjusts its sending behavior based on more recent delivery
samples, and if BBR needs to re-probe the current BBR.min_rtt of the path then
it cuts its cwnd accordingly. The following sections describe the various
considerations that impact cwnd.</t>
          <section anchor="initial-cwnd">
            <name>Initial cwnd</name>
            <t>BBR generally uses measurements to build a model of the network path and
then adapts control decisions to the path based on that model. As such, the
selection of the initial cwnd is considered to be outside the scope of the
BBR algorithm, since at initialization there are no measurements yet upon
which BBR can operate. Thus, at initialization, BBR uses the transport sender
implementation's initial congestion window (e.g. from <xref target="RFC6298"/> for TCP).</t>
          </section>
          <section anchor="computing-bbrmaxinflight">
            <name>Computing BBR.max_inflight</name>
            <t>The BBR BBR.max_inflight is the upper bound on the volume of data BBR allows in
flight. This bound is always in place, and dominates when all other
considerations have been satisfied: the flow is not in loss recovery, does not
need to probe BBR.min_rtt, and has accumulated confidence in its model
parameters by receiving enough ACKs to gradually grow the current cwnd to meet
the BBR.max_inflight.</t>
            <t>On each ACK, BBR calculates the BBR.max_inflight in BBRUpdateMaxInflight()
as follows:</t>
            <artwork><![CDATA[
  BBRBDPMultiple(gain):
    if (BBR.min_rtt == Infinity)
      return InitialCwnd /* no valid RTT samples yet */
    BBR.bdp = BBR.bw * BBR.min_rtt
    return gain * BBR.bdp

  BBRQuantizationBudget(inflight)
    BBRUpdateOffloadBudget()
    inflight = max(inflight, BBR.offload_budget)
    inflight = max(inflight, BBRMinPipeCwnd)
      if (BBR.state == ProbeBW_UP)
      inflight += 2*SMSS
    return inflight

  BBRInflight(gain):
    inflight = BBRBDPMultiple(gain)
    return BBRQuantizationBudget(inflight)

  BBRUpdateMaxInflight():
    BBRUpdateAggregationBudget()
    inflight = BBRBDPMultiple(BBR.cwnd_gain)
    inflight += BBR.extra_acked
    BBR.max_inflight = BBRQuantizationBudget(inflight)
]]></artwork>
            <t>The "estimated_bdp" term tries to allow enough packets in flight to fully
utilize the estimated BDP of the path, by allowing the flow to send at BBR.bw
for a duration of BBR.min_rtt. Scaling up the BDP by BBR.cwnd_gain bounds
in-flight data to a small multiple of the BDP, to handle common network and
receiver behavior, such as delayed, stretched, or aggregated ACKs <xref target="A15"/>.
The "quanta" term allows enough quanta in flight on the sending and
receiving hosts to reach high throughput even in environments using
offload mechanisms.</t>
          </section>
          <section anchor="minimum-cwnd-for-pipelining">
            <name>Minimum cwnd for Pipelining</name>
            <t>For BBR.max_inflight, BBR imposes a floor of BBRMinPipeCwnd (4 packets, i.e.
4 * SMSS). This floor helps ensure that even at very low BDPs, and with
a transport like TCP where a receiver may ACK only every alternate SMSS of
data, there are enough packets in flight to maintain full pipelining. In
particular BBR tries to allow at least 2 data packets in flight and ACKs
for at least 2 data packets on the path from receiver to sender.</t>
          </section>
          <section anchor="modulating-cwnd-in-loss-recovery">
            <name>Modulating cwnd in Loss Recovery</name>
            <t>BBR interprets loss as a hint that there may be recent changes in path behavior
that are not yet fully reflected in its model of the path, and thus it needs
to be more conservative.</t>
            <t>Upon a retransmission timeout (RTO), BBR conservatively reduces cwnd to a
value that will allow 1 SMSS to be transmitted. Then BBR gradually increases
cwnd using the normal approach outlined below in "cwnd Adjustment Mechanism"
in <xref target="cwnd-adjustment-mechanism"/>.</t>
            <t>When a BBR sender is in Fast Recovery it uses the response described in
"Updating the Model Upon Packet Loss" in
<xref target="updating-the-model-upon-packet-loss"/>.</t>
            <t>When BBR exits loss recovery it restores the cwnd to the "last known good"
value that cwnd held before entering recovery. This applies equally whether
the flow exits loss recovery because it finishes repairing all losses or
because it executes an "undo" event after inferring that a loss recovery
event was spurious.</t>
            <t>The high-level design for updating cwnd in loss recovery is as follows:</t>
            <t>Upon retransmission timeout (RTO):</t>
            <artwork><![CDATA[
  BBROnEnterRTO():
    BBRSaveCwnd()
    cwnd = C.pipe + 1
]]></artwork>
            <t>Upon entering Fast Recovery:</t>
            <artwork><![CDATA[
  BBROnEnterFastRecovery():
    BBRSaveCwnd()
]]></artwork>
            <t>Upon exiting loss recovery (RTO recovery or Fast Recovery), either by repairing
all losses or undoing recovery, BBR restores the best-known cwnd value we
had upon entering loss recovery:</t>
            <artwork><![CDATA[
  BBRRestoreCwnd()
]]></artwork>
            <t>Note that exiting loss recovery happens during ACK processing, and at the
end of ACK processing BBRBoundCwndForModel() will bound the cwnd based on
the current model parameters. Thus the cwnd and pacing rate after loss recovery
will generally be smaller than the values entering loss recovery.</t>
            <t>The BBRSaveCwnd() and BBRRestoreCwnd() helpers help remember and restore
the last-known good cwnd (the latest cwnd unmodulated by loss recovery or
ProbeRTT), and is defined as follows:</t>
            <artwork><![CDATA[
  BBRSaveCwnd():
    if (!InLossRecovery() and BBR.state != ProbeRTT)
      BBR.prior_cwnd = cwnd
    else
      BBR.prior_cwnd = max(BBR.prior_cwnd, cwnd)

  BBRRestoreCwnd():
    cwnd = max(cwnd, BBR.prior_cwnd)
]]></artwork>
          </section>
          <section anchor="modulating-cwnd-in-probertt">
            <name>Modulating cwnd in ProbeRTT</name>
            <t>If BBR decides it needs to enter the ProbeRTT state (see the "ProbeRTT" section
below), its goal is to quickly reduce the volume of in-flight data and drain
the bottleneck queue, thereby allowing measurement of BBR.min_rtt. To implement
this mode, BBR bounds the cwnd to BBRMinPipeCwnd, the minimal value that
allows pipelining (see the "Minimum cwnd for Pipelining" section, above):</t>
            <artwork><![CDATA[
  BBRProbeRTTCwnd():
    probe_rtt_cwnd = BBRBDPMultiple(BBR.bw, BBRProbeRTTCwndGain)
    probe_rtt_cwnd = max(probe_rtt_cwnd, BBRMinPipeCwnd)
    return probe_rtt_cwnd

  BBRBoundCwndForProbeRTT():
    if (BBR.state == ProbeRTT)
      cwnd = min(cwnd, BBRProbeRTTCwnd())
]]></artwork>
          </section>
          <section anchor="cwnd-adjustment-mechanism">
            <name>cwnd Adjustment Mechanism</name>
            <t>The network path and traffic traveling over it can make sudden dramatic
changes.  To adapt to these changes smoothly and robustly, and reduce packet
losses in such cases, BBR uses a conservative strategy. When cwnd is above the
BBR.max_inflight derived from BBR's path model, BBR cuts the cwnd immediately
to the BBR.max_inflight.  When cwnd is below BBR.max_inflight, BBR raises the
cwnd gradually and cautiously, increasing cwnd by no more than the amount of
data acknowledged (cumulatively or selectively) upon each ACK.</t>
            <t>Specifically, on each ACK that acknowledges "rs.newly_acked" packets as newly
acknowledged, BBR runs the following BBRSetCwnd() steps to update cwnd:</t>
            <artwork><![CDATA[
  BBRSetCwnd():
    BBRUpdateMaxInflight()
    if (BBR.full_bw_reached)
      cwnd = min(cwnd + rs.newly_acked, BBR.max_inflight)
    else if (cwnd < BBR.max_inflight || C.delivered < InitialCwnd)
      cwnd = cwnd + rs.newly_acked
    cwnd = max(cwnd, BBRMinPipeCwnd)
    BBRBoundCwndForProbeRTT()
    BBRBoundCwndForModel()
]]></artwork>
            <t>There are several considerations embodied in the logic above. If BBR has
measured enough samples to achieve confidence that it has filled the pipe
(see the description of BBR.full_bw_reached in the "Startup" section below), then
it increases its cwnd based on the number of packets delivered, while bounding
its cwnd to be no larger than the BBR.max_inflight adapted to the estimated
BDP. Otherwise, if the cwnd is below the BBR.max_inflight, or the sender
has marked so little data delivered (less than InitialCwnd) that it does not
yet judge its BBR.max_bw estimate and BBR.max_inflight as useful, then it increases
cwnd without bounding it to be below BBR.max_inflight. Finally, BBR imposes
a floor of BBRMinPipeCwnd in order to allow pipelining even with small BDPs
(see the "Minimum cwnd for Pipelining" section, above).</t>
          </section>
          <section anchor="bounding-cwnd-based-on-recent-congestion">
            <name>Bounding cwnd Based on Recent Congestion</name>
            <t>Finally, BBR bounds the cwnd based on recent congestion, as outlined in the
"Volume Cap" column of the table in the "Summary of Control Behavior in the
State Machine" section:</t>
            <artwork><![CDATA[
  BBRBoundCwndForModel():
    cap = Infinity
    if (IsInAProbeBWState() and
        BBR.state != ProbeBW_CRUISE)
      cap = BBR.inflight_longterm
    else if (BBR.state == ProbeRTT or
             BBR.state == ProbeBW_CRUISE)
      cap = BBRInflightWithHeadroom()

    /* apply inflight_shortterm (possibly infinite): */
    cap = min(cap, BBR.inflight_shortterm)
    cap = max(cap, BBRMinPipeCwnd)
    cwnd = min(cwnd, cap)
]]></artwork>
          </section>
        </section>
      </section>
    </section>
    <section anchor="implementation-status">
      <name>Implementation Status</name>
      <t>This section records the status of known implementations of the algorithm
defined by this specification at the time of posting of this Internet-Draft,
and is based on a proposal described in <xref target="RFC7942"/>.
The description of implementations in this section is intended to assist
the IETF in its decision processes in progressing drafts to RFCs. Please
note that the listing of any individual implementation here does not imply
endorsement by the IETF. Furthermore, no effort has been spent to verify
the information presented here that was supplied by IETF contributors. This
is not intended as, and must not be construed to be, a catalog of available
implementations or their features.  Readers are advised to note that other
implementations may exist.</t>
      <t>According to <xref target="RFC7942"/>, "this will allow reviewers and working groups to
assign due consideration to documents that have the benefit of running code,
which may serve as evidence of valuable experimentation and feedback that have
made the implemented protocols more mature.  It is up to the individual working
groups to use this information as they see fit".</t>
      <t>As of the time of writing, the following implementations of BBRv3 have been
publicly released:</t>
      <ul spacing="normal">
        <li>
          <t>Linux TCP
          </t>
          <ul spacing="normal">
            <li>
              <t>Source code URL:
              </t>
              <ul spacing="normal">
                <li>
                  <t>https://github.com/google/bbr/blob/v3/README.md</t>
                </li>
                <li>
                  <t>https://github.com/google/bbr/blob/v3/net/ipv4/tcp_bbr.c</t>
                </li>
              </ul>
            </li>
            <li>
              <t>Source: Google</t>
            </li>
            <li>
              <t>Maturity: production</t>
            </li>
            <li>
              <t>License: dual-licensed: GPLv2 / BSD</t>
            </li>
            <li>
              <t>Contact: https://groups.google.com/d/forum/bbr-dev</t>
            </li>
            <li>
              <t>Last updated: November 22, 2023</t>
            </li>
          </ul>
        </li>
        <li>
          <t>QUIC
          </t>
          <ul spacing="normal">
            <li>
              <t>Source code URLs:
              </t>
              <ul spacing="normal">
                <li>
                  <t>https://cs.chromium.org/chromium/src/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc</t>
                </li>
                <li>
                  <t>https://cs.chromium.org/chromium/src/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.h</t>
                </li>
              </ul>
            </li>
            <li>
              <t>Source: Google</t>
            </li>
            <li>
              <t>Maturity: production</t>
            </li>
            <li>
              <t>License: BSD-style</t>
            </li>
            <li>
              <t>Contact: https://groups.google.com/d/forum/bbr-dev</t>
            </li>
            <li>
              <t>Last updated: October 21, 2021</t>
            </li>
          </ul>
        </li>
      </ul>
      <t>As of the time of writing, the following implementations of the delivery
rate sampling algorithm have been publicly released:</t>
      <ul spacing="normal">
        <li>
          <t>Linux TCP
          </t>
          <ul spacing="normal">
            <li>
              <t>Source code URL:
              </t>
              <ul spacing="normal">
                <li>
                  <t>GPLv2 license: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/tcp_rate.c</t>
                </li>
                <li>
                  <t>BSD-style license: https://groups.google.com/d/msg/bbr-dev/X0LbDptlOzo/EVgkRjVHBQAJ</t>
                </li>
              </ul>
            </li>
            <li>
              <t>Source: Google</t>
            </li>
            <li>
              <t>Maturity: production</t>
            </li>
            <li>
              <t>License: dual-licensed: GPLv2 / BSD-style</t>
            </li>
            <li>
              <t>Contact: https://groups.google.com/d/forum/bbr-dev</t>
            </li>
            <li>
              <t>Last updated: September 24, 2021</t>
            </li>
          </ul>
        </li>
        <li>
          <t>QUIC
          </t>
          <ul spacing="normal">
            <li>
              <t>Source code URLs:
              </t>
              <ul spacing="normal">
                <li>
                  <t>https://github.com/google/quiche/blob/main/quiche/quic/core/congestion_control/bandwidth_sampler.cc</t>
                </li>
                <li>
                  <t>https://github.com/google/quiche/blob/main/quiche/quic/core/congestion_control/bandwidth_sampler.h</t>
                </li>
              </ul>
            </li>
            <li>
              <t>Source: Google</t>
            </li>
            <li>
              <t>Maturity: production</t>
            </li>
            <li>
              <t>License: BSD-style</t>
            </li>
            <li>
              <t>Contact: https://groups.google.com/d/forum/bbr-dev</t>
            </li>
            <li>
              <t>Last updated: October 5, 2021</t>
            </li>
          </ul>
        </li>
      </ul>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>This proposal makes no changes to the underlying security of transport protocols
or congestion control algorithms. BBR shares the same security considerations
as the existing standard congestion control algorithm <xref target="RFC5681"/>.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions. Here we are using that phrase, suggested
by <xref target="RFC8126"/>, because BBR does not modify or extend the wire format of
any network protocol, nor does it add new dependencies on assigned numbers.
BBR involves only a change to the congestion control algorithm of a transport
sender, and does not involve changes in the network, the receiver, or any network
protocol.</t>
      <t>Note to RFC Editor: this section may be removed on publication as an RFC.</t>
    </section>
    <section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors are grateful to Len Kleinrock for his work on the theory underlying
congestion control. We are indebted to Larry Brakmo for pioneering work on
the Vegas <xref target="BP95"/> and New Vegas <xref target="B15"/> congestion control algorithms,
which presaged many elements of BBR, and for Larry's advice and guidance during
BBR's early development. The authors would also like to thank Kevin Yang,
Priyaranjan Jha, Yousuk Seung, Luke Hsiao for their work on TCP BBR; Jana Iyengar,
Victor Vasiliev, Bin Wu for their work on QUIC BBR; and Matt Mathis for his
research work on the BBR algorithm and its implications <xref target="MM19"/>. We would also
like to thank C. Stephen Gunn, Eric Dumazet, Nandita Dukkipati, Pawel Jurczyk,
Biren Roy, David Wetherall, Amin Vahdat, Leonidas Kontothanassis,
and the YouTube, google.com, Bandwidth Enforcer, and Google SRE teams for
their invaluable help and support. We would like to thank Randall R. Stewart,
Jim Warner, Loganaden Velvindron, Hiren Panchasara, Adrian Zapletal, Christian
Huitema, Bao Zheng, Jonathan Morton, Matt Olson, Junho Choi, Carsten Bormann,
Pouria Mousavizadeh Tehrani, Amanda Baber and Frédéric Lécaille
for feedback, suggestions, and edits on earlier versions of this document.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC793">
          <front>
            <title>Transmission Control Protocol</title>
            <author fullname="J. Postel" initials="J." surname="Postel"/>
            <date month="September" year="1981"/>
          </front>
          <seriesInfo name="RFC" value="793"/>
          <seriesInfo name="DOI" value="10.17487/RFC0793"/>
        </reference>
        <reference anchor="RFC9293">
          <front>
            <title>Transmission Control Protocol (TCP)</title>
            <author fullname="W. Eddy" initials="W." role="editor" surname="Eddy"/>
            <date month="August" year="2022"/>
            <abstract>
              <t>This document specifies the Transmission Control Protocol (TCP). TCP is an important transport-layer protocol in the Internet protocol stack, and it has continuously evolved over decades of use and growth of the Internet. Over this time, a number of changes have been made to TCP as it was specified in RFC 793, though these have only been documented in a piecemeal fashion. This document collects and brings those changes together with the protocol specification from RFC 793. This document obsoletes RFC 793, as well as RFCs 879, 2873, 6093, 6429, 6528, and 6691 that updated parts of RFC 793. It updates RFCs 1011 and 1122, and it should be considered as a replacement for the portions of those documents dealing with TCP requirements. It also updates RFC 5961 by adding a small clarification in reset handling while in the SYN-RECEIVED state. The TCP header control bits from RFC 793 have also been updated based on RFC 3168.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="7"/>
          <seriesInfo name="RFC" value="9293"/>
          <seriesInfo name="DOI" value="10.17487/RFC9293"/>
        </reference>
        <reference anchor="RFC2018">
          <front>
            <title>TCP Selective Acknowledgment Options</title>
            <author fullname="M. Mathis" initials="M." surname="Mathis"/>
            <author fullname="J. Mahdavi" initials="J." surname="Mahdavi"/>
            <author fullname="S. Floyd" initials="S." surname="Floyd"/>
            <author fullname="A. Romanow" initials="A." surname="Romanow"/>
            <date month="October" year="1996"/>
            <abstract>
              <t>This memo proposes an implementation of SACK and discusses its performance and related issues. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2018"/>
          <seriesInfo name="DOI" value="10.17487/RFC2018"/>
        </reference>
        <reference anchor="RFC7323">
          <front>
            <title>TCP Extensions for High Performance</title>
            <author fullname="D. Borman" initials="D." surname="Borman"/>
            <author fullname="B. Braden" initials="B." surname="Braden"/>
            <author fullname="V. Jacobson" initials="V." surname="Jacobson"/>
            <author fullname="R. Scheffenegger" initials="R." role="editor" surname="Scheffenegger"/>
            <date month="September" year="2014"/>
            <abstract>
              <t>This document specifies a set of TCP extensions to improve performance over paths with a large bandwidth * delay product and to provide reliable operation over very high-speed paths. It defines the TCP Window Scale (WS) option and the TCP Timestamps (TS) option and their semantics. The Window Scale option is used to support larger receive windows, while the Timestamps option can be used for at least two distinct mechanisms, Protection Against Wrapped Sequences (PAWS) and Round-Trip Time Measurement (RTTM), that are also described herein.</t>
              <t>This document obsoletes RFC 1323 and describes changes from it.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7323"/>
          <seriesInfo name="DOI" value="10.17487/RFC7323"/>
        </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="RFC8126">
          <front>
            <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
            <author fullname="M. Cotton" initials="M." surname="Cotton"/>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <author fullname="T. Narten" initials="T." surname="Narten"/>
            <date month="June" year="2017"/>
            <abstract>
              <t>Many protocols make use of points of extensibility that use constants to identify various protocol parameters. To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations are often coordinated by a central record keeper. For IETF protocols, that role is filled by the Internet Assigned Numbers Authority (IANA).</t>
              <t>To make assignments in a given registry prudently, guidance describing the conditions under which new values should be assigned, as well as when and how modifications to existing values can be made, is needed. This document defines a framework for the documentation of these guidelines by specification authors, in order to assure that the provided guidance for the IANA Considerations is clear and addresses the various issues that are likely in the operation of a registry.</t>
              <t>This is the third edition of this document; it obsoletes RFC 5226.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="26"/>
          <seriesInfo name="RFC" value="8126"/>
          <seriesInfo name="DOI" value="10.17487/RFC8126"/>
        </reference>
        <reference anchor="RFC6298">
          <front>
            <title>Computing TCP's Retransmission Timer</title>
            <author fullname="V. Paxson" initials="V." surname="Paxson"/>
            <author fullname="M. Allman" initials="M." surname="Allman"/>
            <author fullname="J. Chu" initials="J." surname="Chu"/>
            <author fullname="M. Sargent" initials="M." surname="Sargent"/>
            <date month="June" year="2011"/>
            <abstract>
              <t>This document defines the standard algorithm that Transmission Control Protocol (TCP) senders are required to use to compute and manage their retransmission timer. It expands on the discussion in Section 4.2.3.1 of RFC 1122 and upgrades the requirement of supporting the algorithm from a SHOULD to a MUST. This document obsoletes RFC 2988. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6298"/>
          <seriesInfo name="DOI" value="10.17487/RFC6298"/>
        </reference>
        <reference anchor="RFC5681">
          <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="RFC7942">
          <front>
            <title>Improving Awareness of Running Code: The Implementation Status Section</title>
            <author fullname="Y. Sheffer" initials="Y." surname="Sheffer"/>
            <author fullname="A. Farrel" initials="A." surname="Farrel"/>
            <date month="July" year="2016"/>
            <abstract>
              <t>This document describes a simple process that allows authors of Internet-Drafts to record the status of known implementations by including an Implementation Status section. This will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature.</t>
              <t>This process is not mandatory. Authors of Internet-Drafts are encouraged to consider using the process for their documents, and working groups are invited to think about applying the process to all of their protocol specifications. This document obsoletes RFC 6982, advancing it to a Best Current Practice.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="205"/>
          <seriesInfo name="RFC" value="7942"/>
          <seriesInfo name="DOI" value="10.17487/RFC7942"/>
        </reference>
        <reference anchor="RFC9438">
          <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="RFC8985">
          <front>
            <title>The RACK-TLP Loss Detection Algorithm for TCP</title>
            <author fullname="Y. Cheng" initials="Y." surname="Cheng"/>
            <author fullname="N. Cardwell" initials="N." surname="Cardwell"/>
            <author fullname="N. Dukkipati" initials="N." surname="Dukkipati"/>
            <author fullname="P. Jha" initials="P." surname="Jha"/>
            <date month="February" year="2021"/>
            <abstract>
              <t>This document presents the RACK-TLP loss detection algorithm for TCP. RACK-TLP uses per-segment transmit timestamps and selective acknowledgments (SACKs) and has two parts. Recent Acknowledgment (RACK) starts fast recovery quickly using time-based inferences derived from acknowledgment (ACK) feedback, and Tail Loss Probe (TLP) leverages RACK and sends a probe packet to trigger ACK feedback to avoid retransmission timeout (RTO) events. Compared to the widely used duplicate acknowledgment (DupAck) threshold approach, RACK-TLP detects losses more efficiently when there are application-limited flights of data, lost retransmissions, or data packet reordering events. It is intended to be an alternative to the DupAck threshold approach.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8985"/>
          <seriesInfo name="DOI" value="10.17487/RFC8985"/>
        </reference>
        <reference anchor="RFC9000">
          <front>
            <title>QUIC: A UDP-Based Multiplexed and Secure Transport</title>
            <author fullname="J. Iyengar" initials="J." role="editor" surname="Iyengar"/>
            <author fullname="M. Thomson" initials="M." role="editor" surname="Thomson"/>
            <date month="May" year="2021"/>
            <abstract>
              <t>This document defines the core of the QUIC transport protocol. QUIC provides applications with flow-controlled streams for structured communication, low-latency connection establishment, and network path migration. QUIC includes security measures that ensure confidentiality, integrity, and availability in a range of deployment circumstances. Accompanying documents describe the integration of TLS for key negotiation, loss detection, and an exemplary congestion control algorithm.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9000"/>
          <seriesInfo name="DOI" value="10.17487/RFC9000"/>
        </reference>
        <reference anchor="RFC4340">
          <front>
            <title>Datagram Congestion Control Protocol (DCCP)</title>
            <author fullname="E. Kohler" initials="E." surname="Kohler"/>
            <author fullname="M. Handley" initials="M." surname="Handley"/>
            <author fullname="S. Floyd" initials="S." surname="Floyd"/>
            <date month="March" year="2006"/>
            <abstract>
              <t>The Datagram Congestion Control Protocol (DCCP) is a transport protocol that provides bidirectional unicast connections of congestion-controlled unreliable datagrams. DCCP is suitable for applications that transfer fairly large amounts of data and that can benefit from control over the tradeoff between timeliness and reliability. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4340"/>
          <seriesInfo name="DOI" value="10.17487/RFC4340"/>
        </reference>
        <reference anchor="RFC6928">
          <front>
            <title>Increasing TCP's Initial Window</title>
            <author fullname="J. Chu" initials="J." surname="Chu"/>
            <author fullname="N. Dukkipati" initials="N." surname="Dukkipati"/>
            <author fullname="Y. Cheng" initials="Y." surname="Cheng"/>
            <author fullname="M. Mathis" initials="M." surname="Mathis"/>
            <date month="April" year="2013"/>
            <abstract>
              <t>This document proposes an experiment to increase the permitted TCP initial window (IW) from between 2 and 4 segments, as specified in RFC 3390, to 10 segments with a fallback to the existing recommendation when performance issues are detected. It discusses the motivation behind the increase, the advantages and disadvantages of the higher initial window, and presents results from several large-scale experiments showing that the higher initial window improves the overall performance of many web services without resulting in a congestion collapse. The document closes with a discussion of usage and deployment for further experimental purposes recommended by the IETF TCP Maintenance and Minor Extensions (TCPM) working group.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6928"/>
          <seriesInfo name="DOI" value="10.17487/RFC6928"/>
        </reference>
        <reference anchor="RFC6675">
          <front>
            <title>A Conservative Loss Recovery Algorithm Based on Selective Acknowledgment (SACK) for TCP</title>
            <author fullname="E. Blanton" initials="E." surname="Blanton"/>
            <author fullname="M. Allman" initials="M." surname="Allman"/>
            <author fullname="L. Wang" initials="L." surname="Wang"/>
            <author fullname="I. Jarvinen" initials="I." surname="Jarvinen"/>
            <author fullname="M. Kojo" initials="M." surname="Kojo"/>
            <author fullname="Y. Nishida" initials="Y." surname="Nishida"/>
            <date month="August" year="2012"/>
            <abstract>
              <t>This document presents a conservative loss recovery algorithm for TCP that is based on the use of the selective acknowledgment (SACK) TCP option. The algorithm presented in this document conforms to the spirit of the current congestion control specification (RFC 5681), but allows TCP senders to recover more effectively when multiple segments are lost from a single flight of data. This document obsoletes RFC 3517 and describes changes from it. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6675"/>
          <seriesInfo name="DOI" value="10.17487/RFC6675"/>
        </reference>
        <reference anchor="RFC6937">
          <front>
            <title>Proportional Rate Reduction for TCP</title>
            <author fullname="M. Mathis" initials="M." surname="Mathis"/>
            <author fullname="N. Dukkipati" initials="N." surname="Dukkipati"/>
            <author fullname="Y. Cheng" initials="Y." surname="Cheng"/>
            <date month="May" year="2013"/>
            <abstract>
              <t>This document describes an experimental Proportional Rate Reduction (PRR) algorithm as an alternative to the widely deployed Fast Recovery and Rate-Halving algorithms. These algorithms determine the amount of data sent by TCP during loss recovery. PRR minimizes excess window adjustments, and the actual window size at the end of recovery will be as close as possible to the ssthresh, as determined by the congestion control algorithm.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6937"/>
          <seriesInfo name="DOI" value="10.17487/RFC6937"/>
        </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 anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="CCGHJ16" target="http://queue.acm.org/detail.cfm?id=3022184">
          <front>
            <title>BBR: Congestion-Based Congestion Control</title>
            <author initials="N." surname="Cardwell" fullname="Neal Cardwell">
              <organization/>
            </author>
            <author initials="Y." surname="Cheng" fullname="Yuchung Cheng">
              <organization/>
            </author>
            <author initials="C." surname="Gunn" fullname="C. Stephen Gunn">
              <organization/>
            </author>
            <author initials="S." surname="Hassas Yeganeh" fullname="Soheil Hassas Yeganeh">
              <organization/>
            </author>
            <author initials="V." surname="Jacobson" fullname="Van Jacobson">
              <organization/>
            </author>
            <date year="2016" month="October"/>
          </front>
          <seriesInfo name="ACM Queue" value="Oct 2016"/>
        </reference>
        <reference anchor="CCGHJ17" target="https://cacm.acm.org/magazines/2017/2/212428-bbr-congestion-based-congestion-control/pdf">
          <front>
            <title>BBR: Congestion-Based Congestion Control</title>
            <author initials="N." surname="Cardwell" fullname="Neal Cardwell">
              <organization/>
            </author>
            <author initials="Y." surname="Cheng" fullname="Yuchung Cheng">
              <organization/>
            </author>
            <author initials="C." surname="Gunn" fullname="C. Stephen Gunn">
              <organization/>
            </author>
            <author initials="S." surname="Hassas Yeganeh" fullname="Soheil Hassas Yeganeh">
              <organization/>
            </author>
            <author initials="V." surname="Jacobson" fullname="Van Jacobson">
              <organization/>
            </author>
            <date year="2017" month="February"/>
          </front>
          <seriesInfo name="Communications of the ACM" value="Feb 2017"/>
        </reference>
        <reference anchor="MM19">
          <front>
            <title>Deprecating The TCP Macroscopic Model</title>
            <author initials="M." surname="Mathis" fullname="M. Mathis">
              <organization/>
            </author>
            <author initials="J." surname="Mahdavi" fullname="J. Mahdavi">
              <organization/>
            </author>
            <date year="2019" month="October"/>
          </front>
          <seriesInfo name="Computer Communication Review, vol. 49, no. 5, pp. 63-68" value=""/>
        </reference>
        <reference anchor="BBRStartupCwndGain" target="https://github.com/google/bbr/blob/master/Documentation/startup/gain/analysis/bbr_startup_cwnd_gain.pdf">
          <front>
            <title>BBR Startup cwnd  Gain: a Derivation</title>
            <author initials="I." surname="Swett" fullname="Ian Swett">
              <organization/>
            </author>
            <author initials="N." surname="Cardwell" fullname="Neal Cardwell">
              <organization/>
            </author>
            <author initials="Y." surname="Cheng" fullname="Yuchung Cheng">
              <organization/>
            </author>
            <author initials="S." surname="Hassas Yeganeh" fullname="Soheil Hassas Yeganeh">
              <organization/>
            </author>
            <author initials="V." surname="Jacobson" fullname="Van Jacobson">
              <organization/>
            </author>
            <date year="2018" month="July"/>
          </front>
        </reference>
        <reference anchor="BBRStartupPacingGain" target="https://github.com/google/bbr/blob/master/Documentation/startup/gain/analysis/bbr_startup_gain.pdf">
          <front>
            <title>BBR Startup Pacing Gain: a Derivation</title>
            <author initials="N." surname="Cardwell" fullname="Neal Cardwell">
              <organization/>
            </author>
            <author initials="Y." surname="Cheng" fullname="Yuchung Cheng">
              <organization/>
            </author>
            <author initials="S." surname="Hassas Yeganeh" fullname="Soheil Hassas Yeganeh">
              <organization/>
            </author>
            <author initials="V." surname="Jacobson" fullname="Van Jacobson">
              <organization/>
            </author>
            <date year="2018" month="June"/>
          </front>
        </reference>
        <reference anchor="BBRDrainPacingGain" target="https://github.com/google/bbr/blob/master/Documentation/startup/gain/analysis/bbr_drain_gain.pdf">
          <front>
            <title>BBR Drain Pacing Gain: a Derivation</title>
            <author initials="N." surname="Cardwell" fullname="Neal Cardwell">
              <organization/>
            </author>
            <author initials="Y." surname="Cheng" fullname="Yuchung Cheng">
              <organization/>
            </author>
            <author initials="S." surname="Hassas Yeganeh" fullname="Soheil Hassas Yeganeh">
              <organization/>
            </author>
            <author initials="V." surname="Jacobson" fullname="Van Jacobson">
              <organization/>
            </author>
            <date year="2021" month="September"/>
          </front>
        </reference>
        <reference anchor="draft-romo-iccrg-ccid5">
          <front>
            <title>Profile for Datagram Congestion Control Protocol (DCCP) Congestion Control ID 5</title>
            <author fullname="Nathalie Romo Moreno" initials="N. R." surname="Moreno">
              <organization>Deutsche Telekom</organization>
            </author>
            <author fullname="Juhoon Kim" initials="J." surname="Kim">
              <organization>Deutsche Telekom</organization>
            </author>
            <author fullname="Markus Amend" initials="M." surname="Amend">
              <organization>Deutsche Telekom</organization>
            </author>
            <date day="25" month="October" year="2021"/>
            <abstract>
              <t>   This document contains the profile for Congestion Control Identifier
   5 (CCID 5), BBR-like Congestion Control, in the Datagram Congestion
   Control Protocol (DCCP).  CCID 5 is meant to be used by senders who
   have a strong demand on low latency and require a steady throughput
   behavior.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-romo-iccrg-ccid5-00"/>
        </reference>
        <reference anchor="A15" target="https://www.ietf.org/mail-archive/web/aqm/current/msg01480.html">
          <front>
            <title>TCP ACK suppression</title>
            <author initials="M." surname="Abrahamsson" fullname="Mikael Abrahamsson">
              <organization/>
            </author>
            <date year="2015" month="November"/>
          </front>
          <refcontent>IETF AQM mailing list</refcontent>
        </reference>
        <reference anchor="Jac88" target="http://ee.lbl.gov/papers/congavoid.pdf">
          <front>
            <title>Congestion Avoidance and Control</title>
            <author initials="V." surname="Jacobson" fullname="Van Jacobson">
              <organization/>
            </author>
            <date year="1988" month="August"/>
          </front>
          <seriesInfo name="SIGCOMM 1988, Computer Communication Review, vol. 18, no. 4, pp. 314-329" value=""/>
        </reference>
        <reference anchor="Jac90" target="ftp://ftp.isi.edu/end2end/end2end-interest-1990.mail">
          <front>
            <title>Modified TCP Congestion Avoidance Algorithm</title>
            <author initials="V." surname="Jacobson" fullname="Van Jacobson">
              <organization/>
            </author>
            <date year="1990" month="April"/>
          </front>
          <seriesInfo name="end2end-interest mailing list" value=""/>
        </reference>
        <reference anchor="BP95">
          <front>
            <title>TCP Vegas: end-to-end congestion avoidance on a global Internet</title>
            <author initials="L." surname="Brakmo" fullname="Lawrence S. Brakmo">
              <organization/>
            </author>
            <author initials="L." surname="Peterson" fullname="Larry L. Peterson">
              <organization/>
            </author>
            <date year="1995" month="October"/>
          </front>
          <seriesInfo name="IEEE Journal on Selected Areas in Communications 13(8): 1465-1480" value=""/>
        </reference>
        <reference anchor="B15" target="https://docs.google.com/document/d/1o-53jbO_xH-m9g2YCgjaf5bK8vePjWP6Mk0rYiRLK-U/edit">
          <front>
            <title>TCP-NV: An Update to TCP-Vegas</title>
            <author initials="L." surname="Brakmo" fullname="Lawrence S. Brakmo">
              <organization/>
            </author>
            <date year="2015" month="August"/>
          </front>
          <seriesInfo name="" value=""/>
        </reference>
        <reference anchor="WS95">
          <front>
            <title>TCP/IP Illustrated, Volume 2: The Implementation</title>
            <author initials="G." surname="Wright" fullname="Gary R. Wright">
              <organization/>
            </author>
            <author initials="W." surname="Stevens" fullname="W. Richard Stevens">
              <organization/>
            </author>
            <date year="1995"/>
          </front>
          <seriesInfo name="Addison-Wesley" value=""/>
        </reference>
        <reference anchor="HRX08">
          <front>
            <title>CUBIC: A New TCP-Friendly High-Speed TCP Variant</title>
            <author initials="S." surname="Ha">
              <organization/>
            </author>
            <author initials="I." surname="Rhee">
              <organization/>
            </author>
            <author initials="L." surname="Xu">
              <organization/>
            </author>
            <date year="2008"/>
          </front>
          <seriesInfo name="ACM SIGOPS Operating System Review" value=""/>
        </reference>
        <reference anchor="GK81" target="http://www.lk.cs.ucla.edu/data/files/Gail/power.pdf">
          <front>
            <title>An Invariant Property of Computer Network Power</title>
            <author initials="R." surname="Gail">
              <organization/>
            </author>
            <author initials="L." surname="Kleinrock">
              <organization/>
            </author>
            <date/>
          </front>
          <seriesInfo name="Proceedings of the International Conference on Communications" value="June, 1981"/>
        </reference>
        <reference anchor="K79">
          <front>
            <title>Power and deterministic rules of thumb for probabilistic problems in computer communications</title>
            <author initials="L." surname="Kleinrock">
              <organization/>
            </author>
            <date/>
          </front>
          <seriesInfo name="Proceedings of the International Conference on Communications" value="1979"/>
        </reference>
      </references>
    </references>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+S9eXPbWJIv+j8+BUYVFUW6SGrxUraq3XNluRZPeVFbctV0
RMcoQBKS0CYJNgBKVrs9n/3lL5ezAKDs6un75kW8iju3ZQI4a548uf5yPB4n
14fp/WRezlbZMj9M51V20YyLvLkYz2Y3l+PptBrvHSSzrDlM8w/rpN5Ml0Vd
F+WquV3T+y9+OPsxWReHSZo25eww/aapNvk39K/6dlnlF3X4S1k10U9N0Syo
iWfP3qbH5eoyrxtqFn82VblIMuo6v+bHSVblmfZ1c3mYHh//9lPy/uaw77N5
1lCbB3sHD8b7e+P9R0m2aa7K6jAZp/SYHuXzoikrGo9M+HWeLdLjrJrf5IsF
/VpW1MFPZXm5yOlf+TIrFofpaqYv/J9LfjKZlcttDb7IVunpTd402xorslWN
51/Q1n+Udb6+Sp/l9VV2a+29ypvMt/bXKT/8P0v6lZtaldUya4rrHHvy9sfj
757c17+eHLg/D/b2H9vz+wfu1/39J/rn4/2DR/rno4Mn9u7DR4/3XbMPDqzd
B/fthcdPHj+0X/f29vTPB/cf2J+PnhzYu48efffQ/Xr/O/8ZtVusLsJpHB//
9PN/7POAiM6y6jIncrxqmvXh7u7fNvkmn2Sz5YRWZ3dOy1AsJrOL5b8X86f3
9w4O9h8/kM+E2r4hegoJZ/wsq/N5DyV9w18Z9eDv8RaS8U/+vJldbVaX6fFV
vrrUJ8WKKP54kv60Wa34J9tc+u20oe3NV/6ZNXRaXuXFIv1H+nNW11md/jm/
zFb5VfTOr0Ro/5HNymldysdG+vuPiPT5lzqvirzGYh5q10fHr9I/YcUO0zez
hl926/tdd31rWuAZ1tbWd5ldZn8vVnm9S59+t3uwe7B/8ODgMfOJmV/UKRY1
/GEmi7q7nl/8/203vgMD7d+N43K53KwK4q401TotL9LmKsceHaY/5lP+mN58
9UqOpVu15/m6yvERTe6MPjg7PklfZbOqrGflupilr8p5vti6YK8m9HJzVdTR
r/+BX6/m2XURj/7Jdlqi0a83TV7F00jf5tdFfjNKr8vFJH3wZJSuykn6cJSu
15P00f3xo8e07dhO2vpTorVmsz6+Wc1/yorVYZs0Un0hndEbacrvpBnNvyqu
ubNvein2smiuNlNww13hsbtEnrvTRTkl+q1pxLvPy9lmma8abmS3ll52L6n9
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

-->

</rfc>
