<?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.24 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-welzl-iccrg-pacing-02" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.28.0 -->
  <front>
    <title abbrev="Pacing in Transport Protocols">Pacing in Transport Protocols</title>
    <seriesInfo name="Internet-Draft" value="draft-welzl-iccrg-pacing-02"/>
    <author initials="M." surname="Welzl" fullname="Michael Welzl">
      <organization>University of Oslo</organization>
      <address>
        <postal>
          <street>PO Box 1080 Blindern</street>
          <city>0316  Oslo</city>
          <country>Norway</country>
        </postal>
        <email>michawe@ifi.uio.no</email>
        <uri>http://welzl.at/</uri>
      </address>
    </author>
    <author initials="W." surname="Eddy" fullname="Wesley Eddy">
      <organization>MTI Systems</organization>
      <address>
        <postal>
          <street>25111 Country Club Blvd, Suite 295</street>
          <city>North Olmsted, OH 44070</city>
          <country>United States of America</country>
        </postal>
        <email>wes@mti-systems.com</email>
      </address>
    </author>
    <author initials="V." surname="Goel" fullname="Vidhi Goel">
      <organization>Apple Inc.</organization>
      <address>
        <postal>
          <street>One Apple Park Way</street>
          <city>Cupertino, California 95014</city>
          <country>United States of America</country>
        </postal>
        <email>vidhi_goel@apple.com</email>
      </address>
    </author>
    <author initials="M." surname="Tüxen" fullname="Michael Tüxen">
      <organization>Münster University of Applied Sciences</organization>
      <address>
        <postal>
          <street>Stegerwaldstrasse 39</street>
          <city>48565 Steinfurt</city>
          <country>Germany</country>
        </postal>
        <email>tuexen@fh-muenster.de</email>
      </address>
    </author>
    <date year="2025" month="March" day="03"/>
    <area>IRTF</area>
    <workgroup>Internet Congestion Control</workgroup>
    <keyword>next generation</keyword>
    <keyword>unicorn</keyword>
    <keyword>sparkling distributed ledger</keyword>
    <abstract>
      <?line 149?>

<t>Applications or congestion control mechanisms can produce bursty traffic which can cause unnecessary queuing and packet loss. To reduce the burstiness of traffic, the concept of evenly spacing out the traffic from a data sender over a round-trip time known as "pacing" has been used in many transport protocol implementations. This document gives an overview of pacing and how some known pacing implementations work.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://mwelzl.github.io/draft-iccrg-pacing/draft-welzl-iccrg-pacing.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-welzl-iccrg-pacing/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Internet Congestion Control Research Group mailing list (<eref target="mailto:iccrg@irtf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/iccrg"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/iccrg/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/mwelzl/draft-iccrg-pacing"/>.</t>
    </note>
  </front>
  <middle>
    <?line 154?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Applications commonly generate either bulk data (e.g. files) or bursts of data (e.g. segments of media) that transport protocols deliver into the network based on congestion control algorithms.</t>
      <t>RFCs describing congestion control generally refer to a congestion window (cwnd) state variable as an upper limit for either the number of unacknowledged packets or bytes that a sender is allowed to emit. This limits the sender's transmission rate at the granularity of a round-trip time (RTT). If the sender transmits the entire cwnd sized data in an instant, this can result in unnecessarily high queuing and eventually packet losses at the bottleneck. Such consequences are detrimental to users' applications in terms of both responsiveness and goodput. To solve this problem, the concept of pacing was introduced. Pacing allows to send the same cwnd sized data but spread it across a round-trip time more evenly.</t>
      <t>Congestion control specifications always allow to send less than the cwnd, or temporarily emit packets at a lower rate. Accordingly, it is in line with these specifications to pace packets. Pacing is known to have advantages -- if some packets arrive at a bottleneck as a burst (all packets being back-to-back), loss can be more likely to happen than in a case where there are time gaps between packets (e.g., when they are spread out over the RTT). It also means that pacing is less likely to cause any sudden, ephemeral increases in queuing delay. Since keeping the queues short reduces packet losses, pacing can also yield higher goodput by reducing the time lost in loss recovery.</t>
      <t>Because of its known advantages, pacing has become common in implementations of congestion controlled transports. It is also an integral element of the "BBR" congestion control mechanism <xref target="I-D.cardwell-iccrg-bbr-congestion-control"/>.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="pacing-general-considerations-and-consequences">
      <name>Pacing: general considerations and consequences</name>
      <section anchor="losstypes">
        <name>More likely to saturate a bottleneck</name>
        <t>We can distinguish between two reasons for packet losses that are due to congestion at a bottleneck with a DropTail (FIFO) queue:</t>
        <ol spacing="normal" type="1"><li>
            <t>A flight of N packets arrives. The amount of data in this flight exceeds the amount of data that can be transmitted by the bottleneck during the flight's arrival plus the queue length, i.e. some data do not fit into the queue.</t>
          </li>
          <li>
            <t>The bottleneck is fully saturated. The queue is full, and packets drain from it more slowly than new packets arrive.</t>
          </li>
        </ol>
        <t>The second type of loss matches the typical expectation of a congestion control algorithm: the cwnd value when loss happens is indicative of the bottleneck being fully saturated. When the first type of loss happens, however, a sender's cwnd can be much smaller than the Bandwidth*Delay Product (BDP) of the path (the amount of data that can be in flight, ignoring the queue). In the absence of other traffic, the probability for the first type of loss to happen depends on the queue length and the ratio between the departure and the arrival rate during the flight's arrival. By introducing time gaps between the packets of a burst, this ratio is increased, i.e. the difference between the departure and the arrival rate becomes smaller, and the second type of loss is more likely.</t>
        <t>For example, consider a network path with a bottleneck capacity of 50 Mbit/s, a queue length of 15000 bytes (or 10 packets of size 1500 bytes) and an RTT of 30 ms. Assume that all packets emitted by the sender have a size of 1500 bytes. Then, the BDP equals 125 packets. The bottleneck of this network path is fully saturated when a (BDP + queue length) amount of bytes are in flight: 135 packets.</t>
        <t>In this network, the first type of loss can happen as follows: say, N=40 packets arrive at this bottleneck at a rate of 100 Mbit/s. In an otherwise empty network and assuming an initial window of 10 packets and no delayed ACKs, this occurs in the third round of slow start without pacing, provided that the capacities of all links before the bottleneck are at least 100 Mbit/s.
In this case, an overshoot will occur: packets are forwarded with half their arrival rate, i.e. less than 20 packets can be forwarded during the burst's arrival. The remaining 20 (or more) packets cannot fit into the 10-packet queue. A cwnd of 40 packets is much smaller than the (BDP + queue) limit of 135 packets, and the bottleneck is not fully saturated.</t>
        <t>Let us now assume that the flight of 40 packets is instead paced, such that the arrival rate only mildly exceeds the departure rate -- e.g., they arrive at a rate of 60 Mbit/s. When the last packet of this flight arrives at the bottleneck, the bottleneck should already have forwarded 5/6 * 39 = 32.5 packets. Since only complete packets can be sent, the bottleneck has really forwarded 32 packets, and the remaining 40-32 = 8 packets fit in the queue. No loss occurs.</t>
        <t>This example explains how pacing can enable a rate increase to last longer than without pacing. This makes it more likely that a bottleneck is saturated, such that cwnd reflects the BDP plus the queue length (loss type 2).</t>
        <section anchor="backing-off-after-the-increase">
          <name>Backing off after the increase</name>
          <t>The two loss types explained in <xref target="losstypes"/> require a different back-off factor to allow the queue to drain and congestion to dissipate. Specifically, in the single-sender single-bottleneck example above, when a slow start overshoot occurs as loss type 2, a back-off function such as: ssthresh = cwnd * beta with beta &gt;= 0.5 is guaranteed to cause a second loss after the end of loss recovery. This is because, when cwnd exceeds a fully saturated bottleneck (i.e., cwnd &gt; BDP + queue length), cwnd will have grown further by another (BDP + queue length) by the time the sender learns about the loss. In this case, beta = 0.5 will cause ssthresh to exceed (BDP + queue length) again.</t>
          <t>Since pacing makes loss type 2 more likely, beta &lt; 0.5 may be a better choice after slow start overshoot when pacing is used.</t>
        </section>
        <section anchor="able-to-work-with-smaller-queues">
          <name>Able to work with smaller queues</name>
          <t>The probability of loss type 1 in <xref target="losstypes"/> is indirectly proportional to the queue length. Pacing therefore enables a rate increase to continue with a smaller queue at the bottleneck than in the case without pacing.</t>
        </section>
      </section>
      <section anchor="queue-dynamics">
        <name>Queue dynamics</name>
        <t>When it enters the queue at a network bottleneck, unpaced traffic causes more sudden, drastic delay growth than paced traffic, and has a higher risk of packet loss, as discussed in <xref target="losstypes"/>. Paced traffic, on the other hand, can cause a bottleneck queue to grow more slowly and steadily, incuring delay growth over a longer time interval. Aside from the direct problems that delay can cause, such sustained queue and delay growth is also more likely to provoke an Active Queue Management (AQM) algorithm to drop packets or mark them using Explicit Congestion Notification (ECN). This is because AQM algorithms are commonly designed to allow short, transient traffic bursts to pass unharmed, but react upon longer-term average queue growth.</t>
      </section>
      <section anchor="getting-good-rtt-estimates">
        <name>Getting good RTT estimates</name>
        <t>Since pacing algorithms generally attempt to spread out packets evenly across an RTT, it is important to have a good RTT estimate. Especially in the beginning of a transfer, when sending the initial window, the only RTT estimate available may be from the connection establishment handshake. Being based on only one sample, this is a very unreliable estimate. Moreover, a new transport connection may be preceded by a longer period of quiescence on the path between two endpoints than there  might normally occur when a connection is active. Such a silence period can provoke behavior of lower layers that increases the RTT. For example, idle periods commonly cause a handshake procedure on 5G links before communication can continue, inflating the RTT.</t>
        <t>Thus, using this sample to pace the initial window can cause the pacing rate to become unnecessarily low. This may be the reason why the Linux TCP implementation does not pace the first 10 packets (see <xref target="linux"/>). As a possible improvement, the initial RTT estimate could also be based on a previous connection (temporal sharing) or on another ongoing connection (ensemble sharing) <xref target="RFC9040"/>.</t>
      </section>
      <section anchor="mini-bursts-and-their-trade-offs">
        <name>Mini-bursts and their trade-offs</name>
        <t>Generally, hardware can perform better on large blocks of data than on multiple small data blocks (fewer copy operations). This plays a role for mechanisms such as TCP Segment Offload (TSO), which, however, only matter at high data rates. A strategy to work with this is to avoid pacing every single packet, but instead pace such that a pause is introduced between batches of some packets that are sent as a mini-burst. Such a strategy is implemented in Linux, for example.</t>
        <t>Clearly, the size of mini-bursts embeds some trade-offs. Even mini-bursts that are very short in terms of time when they leave the sender may cause significant delay further away on an Internet path, where the link capacity is smaller. For example, consider a server that is connected to a 100 Gbps link, serving a client that is behind a 15 Mbps bottleneck link. If that server emits bursts that are 50 kbyte long, the duration of these bursts at the server-side link is negligible (4.1 microseconds). When they reach the bottleneck, however, their duration becomes as large as 27.3 milliseconds. This is an argument for minimizing the size of mini-bursts. On the other hand, wireless link layers such as WiFi can benefit from having more than one packet available at the local send buffer, to make use of frame aggregation methods. This can significantly reduce overhead, and allow a wireless sender to make better use of its transmission opportunity; eliminating these benefits with pacing may in some cases be counter-productive. This is an argument for making the size of mini-bursts larger.</t>
      </section>
    </section>
    <section anchor="implementation-examples">
      <name>Implementation examples</name>
      <section anchor="linux">
        <name>Linux TCP</name>
        <t>The following description is based on Linux kernel version 6.8.9.</t>
        <t>There are two ways to enable pacing in Linux: 1) via a socket option, 2) by configuring the FQ queue discipline. We describe case 1.</t>
        <t>Independent of the value of the Initial Window (IW), the first 10 (hardcoded) packets are not paced. Later, 10 packets will generally be sent without pacing every 2^32 packets.</t>
        <t>Every time an ACK arrives, a pacing rate is calculated, as: factor * MSS * cwnd / SRTT, where "factor" is a configurable value that, by default, is 2 in slow start and 1.2 in congestion avoidance. MSS is the sender maximum segment size <xref target="RFC5681"/>, and SRTT is the smoothed round-trip time <xref target="RFC6298"/>.
The sender transmits data in line with the calculated pacing rate; this is approximated by calculating the rate per millisecond, and generally sending the resulting amount of data per millisecond as a small burst, every millisecond. As an exception, the per-millisecond amount of data can be a little larger when the peer is very close, depending on a configurable value (per default, when the minimum RTT is less than 3 milliseconds).</t>
        <t>If the pacing rate is smaller than 2 packets per millisecond, these bursts will become 2 packets in size, and they will not be sent every millisecond but with a varying time delay (depending on the pacing rate).
If the pacing rate is larger than 64 Kbyte per millisecond, these bursts will be 64 Kbyte in size, and they will not be sent every millisecond but with a varying time delay (depending on the pacing rate).
Bursts can always be smaller than described above, or be "nothing", if a limiting factor such as the receiver window (rwnd) <xref target="RFC5681"/> or the current cwnd disallows transmission.
If the previous packet was not sent when expected by the pacing logic, but more than half of a pacing gap ago (e.g., due to a cwnd limitation), the pacing gap is halved.</t>
        <t>This description is based on the longer Linux pacing analysis text in <xref target="LinuxPacing"/>.</t>
      </section>
      <section anchor="apple-oses">
        <name>Apple OSes</name>
        <t>Pacing was added to Apple OS as a private API in iOS 17 and macOS 14. In its current form, an application or transport protocol computes and sets the desired transmit timestamp on a per packet basis and sends it to the pacing module in AQM. The packets are queued in the AQM until the current time becomes greater than or equal to corresponding packet's transmit timestamp. There is an upper limit of 3 seconds for how long the AQM will hold a queued packet before sending it.</t>
        <t>The above simplicity in the kernel allows upper layer protocols or applications to set a transmit timestamp in a manner that is suitable for them. For example, a stream based protocol like TCP might pace packets differently than a video conferencing app.</t>
      </section>
      <section anchor="freebsd">
        <name>FreeBSD</name>
        <t>FreeBSD has the infrastructure to support multiple TCP stacks.
Each TCP stack has a tcp_output() function, which handles most of the sending of TCP segments.
The default stack does not support pacing and its tcp_output() may be called whenever</t>
        <ol spacing="normal" type="1"><li>
            <t>a TCP segment is received or</t>
          </li>
          <li>
            <t>a TCP timer (like the retransmission or delayed ACK timer) runs off or</t>
          </li>
          <li>
            <t>the application provides new data to be sent</t>
          </li>
        </ol>
        <t>and sends as many TCP segments as is allowed by the congestion and flow control resulting in burst of TCP segments.
However, this also allows to make use of TCP Segment Offload (TSO), which reduces the CPU load.</t>
        <t>The RACK <xref target="RACK"/> and BBR stacks both support pacing by leveraging the TCP High Precision Timer System (HPTS) <xref target="HPTS"/>, which is a kernel loadable module available in FreeBSD 14 and higher.
The tcp_output() function of a TCP stack which supports pacing will not send as much as is allowed by congestion and flow control, but may only send a micro burst and schedule itself for being called after the inter-burst send time using the HPTS.
The RACK stack supports an application setting a pacing rate and a maximum burst size using TCP socket options.
The RACK stack then uses these values to compute the actual micro burst size and the inter-burst send time.</t>
        <t>The HPTS is optimized for handling a large number of TCP connections and the tcp_output() function of the RACK stack is also optimized for being called more often than the tcp_output() function of the default stack.
This allows to use TSO in combination with TCP pacing.</t>
        <t>This subsystem underpins recently published research by Netflix and Stanford into application-informed pacing at scale <xref target="Sammy"/>.</t>
      </section>
      <section anchor="quic-bbr-implementations">
        <name>QUIC BBR implementations</name>
        <t>Pacing capability is expected in QUIC senders.  While standard QUIC congestion control <xref target="RFC9002"/> is based on TCP Reno, which is not defined to include pacing (but also does not prohibit it), QUIC congestion control requires either pacing or some other burst limitation (<xref section="7.7" sectionFormat="of" target="RFC9002"/>).  BBR congestion control implementations are common in QUIC stacks, and pacing is integral to BBR, so this document focuses on it.</t>
        <t>Pacing in QUIC stacks commonly involves:</t>
        <ol spacing="normal" type="1"><li>
            <t>Access to lower-level (e.g. OS and hardware) capabilities needed for effective pacing.</t>
          </li>
          <li>
            <t>Managing additional timers related to pacing, along with those already needed for retransmission, and other events.</t>
          </li>
          <li>
            <t>Details of the actual pacing algorithm (e.g. granularity of bursts allowed, etc.).</t>
          </li>
        </ol>
        <t>Examples of different approaches to dealing with these challenges in ways that work on multiple operating systems and hardware platforms can be found in open source QUIC stacks, such as Google's QUIC implementation and Meta's "mvfst". These provide examples for some of the concepts discussed below.</t>
        <t>Unlike TCP implementations that typically run within the operating system kernel, QUIC implementations more typically run in user space and are thus faced with more challenges regarding timing and coupling with the underlying protocol stack and hardware needed to achieve pacing.  For instance, if an application trying to do pacing is running on a highly loaded system, it may often "wake up late" and miss the times that it intends to pace packets.</t>
        <t>When a large amount of data needs to be sent, pacing naively could result in an excessive number of timers to be managed and adjusted along with all of the other timers that the QUIC stack and rest of the application require.  The Hashed Hierarchical Timing Wheel <xref target="VL87"/> provides one approach for such cases, but implementations may also simply schedule the next send event based on the current pacing rate, and then schedule subsequent events as needed, rather than adjusting timers for them.  In any case, typically a pacing algorithm should allow for some amount of burstiness, in order to efficiently use the hardware as well as to be responsive for bursty (but low overall rate) applications, and to avoid excessive timer management.</t>
        <t>Pacing can be done based on different approaches such as a token-based or tokenless algorithm.  For instance, a tokenless algorithm (e.g. as used in mvfst) might compute a regular interval time and batch size (number of packets) to be released every interval and achieve the pacing rate.  This allows specific future transmissions to be scheduled.  In contrast, a token-based algorithm accumulates tokens to permit transmission based on the pacing rate, using a "leaky bucket" to control bursts.  In this case the size of bursts may be more granular, depending on how much time has elapsed between evaluations.</t>
        <t>The additional notion of "burst tokens" (or other burst allowance) may be present in order to rapidly transmit data if coming out of a quiescent period (e.g. when a flow has been application-limited without data to send, e.g. as used in Google's implementation).  A number of burst tokens, representing packets that can be sent unpaced, is initialized to some value (e.g. 10) when a flow starts or becomes quiescent.  If burst tokens are available, outgoing packets are sent immediately, without pacing, up to the limit permitted by the congestion window, and the burst tokens are depleted by each packet sent.  The number of burst tokens is reduced to zero on congestion events.  When coming out of quiescence, it is set to the minimum of the initial burst size, or the amount of packets that the congestion window (in bytes) represents.</t>
        <t>There may be additional "lumpy tokens" that further allow unpaced packets after the burst tokens have been consumed, and the congestion window does not limit sending.  The amount of lumpy tokens that might be present is determined using heuristics, generally limiting to a small number of packets (e.g. 1 or 2).</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>While congestion control designs, including aspects such as pacing, could result in unwanted competing traffic, they do not directly result in new security considerations.</t>
      <t>Transport protocols that provide authentication (including those using encryption), or are carried over protocols that provide authentication, can protect their congestion control algorithm from network attack. This is orthogonal to the congestion control rules.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="I-D.cardwell-iccrg-bbr-congestion-control">
          <front>
            <title>BBR Congestion Control</title>
            <author fullname="Neal Cardwell" initials="N." surname="Cardwell">
              <organization>Google</organization>
            </author>
            <author fullname="Yuchung Cheng" initials="Y." surname="Cheng">
              <organization>Google</organization>
            </author>
            <author fullname="Soheil Hassas Yeganeh" initials="S. H." surname="Yeganeh">
              <organization>Google</organization>
            </author>
            <author fullname="Ian Swett" initials="I." surname="Swett">
              <organization>Google</organization>
            </author>
            <author fullname="Van Jacobson" initials="V." surname="Jacobson">
              <organization>Google</organization>
            </author>
            <date day="7" month="March" year="2022"/>
            <abstract>
              <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 [RFC5681] or CUBIC [RFC8312], 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 [RFC793] and QUIC [RFC9000].  This document specifies version
   2 of the BBR algorithm, also sometimes referred to as BBRv2 or bbr2.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-cardwell-iccrg-bbr-congestion-control-02"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="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>
        <reference anchor="VL87">
          <front>
            <title>Hashed and hierarchical timing wheels: data structures for the efficient implementation of a timer facility</title>
            <author initials="G." surname="Varghese">
              <organization/>
            </author>
            <author initials="T." surname="Tauck">
              <organization/>
            </author>
            <date year="1987" month="November" day="01"/>
          </front>
          <seriesInfo name="DOI" value="10.1145/37499.37504"/>
        </reference>
        <reference anchor="Sammy" target="https://doi.org/10.1145/3603269.3604839">
          <front>
            <title>Sammy: Smoothing Video Traffic to be a Friendly Internet Neighbor</title>
            <author initials="B." surname="Spang" fullname="Bruce Spang">
              <organization/>
            </author>
            <author initials="S." surname="Kunamalla" fullname="Shravya Kunamalla">
              <organization/>
            </author>
            <author initials="R." surname="Teixeira" fullname="Renata Teixeira">
              <organization/>
            </author>
            <author initials="T." surname="Huang" fullname="Te-Yuan Huang">
              <organization/>
            </author>
            <author initials="G." surname="Armitage" fullname="Grenville Armitage">
              <organization/>
            </author>
            <author initials="R." surname="Johari" fullname="Ramesh Johari">
              <organization/>
            </author>
            <author initials="N." surname="McKeown" fullname="Nick McKeown">
              <organization/>
            </author>
            <date year="2023" month="September" day="01"/>
          </front>
          <seriesInfo name="ACM SIGCOMM '23: Proceedings of the ACM SIGCOMM 2023 Conference" value=""/>
        </reference>
        <reference anchor="RACK" target="https://freebsdfoundation.org/our-work/journal/browser-based-edition/networking-10th-anniversary/rack-and-alternate-tcp-stacks-for-freebsd/">
          <front>
            <title>RACK and Alternate TCP Stacks for FreeBSD</title>
            <author initials="R." surname="Stewart" fullname="Randall Stewart">
              <organization/>
            </author>
            <author initials="M." surname="Tüxen" fullname="Michael Tüxen">
              <organization/>
            </author>
            <date year="2024" month="February"/>
          </front>
          <seriesInfo name="FreeBSD Journal (January/February 2024)" value=""/>
        </reference>
        <reference anchor="HPTS">
          <front>
            <title>Pacing in the FreeBSD TCP Stack</title>
            <author initials="R." surname="Stewart" fullname="Randall Stewart">
              <organization/>
            </author>
            <author initials="M." surname="Tüxen" fullname="Michael Tüxen">
              <organization/>
            </author>
            <date year="2024" month="October"/>
          </front>
          <seriesInfo name="Upcoming in FreeBSD Journal (September/October 2024)" value=""/>
        </reference>
        <reference anchor="HPTSCode" target="https://github.com/freebsd/freebsd-src/blob/main/sys/netinet/tcp_hpts.c#L31-L99">
          <front>
            <title>tcp_hpts.c</title>
            <author>
              <organization/>
            </author>
            <date year="2024" month="October"/>
          </front>
        </reference>
        <reference anchor="LinuxPacing" target="https://folk.universitetetioslo.no/michawe/research/publications/icnc2025-pacing.pdf">
          <front>
            <title>TCP Pacing in the Linux Kernel</title>
            <author initials="M." surname="Welzl" fullname="Michael Welzl">
              <organization/>
            </author>
            <date year="2025" month="February" day="17"/>
          </front>
          <seriesInfo name="IEEE ICNC 2025" value=""/>
        </reference>
        <reference anchor="RFC9040">
          <front>
            <title>TCP Control Block Interdependence</title>
            <author fullname="J. Touch" initials="J." surname="Touch"/>
            <author fullname="M. Welzl" initials="M." surname="Welzl"/>
            <author fullname="S. Islam" initials="S." surname="Islam"/>
            <date month="July" year="2021"/>
            <abstract>
              <t>This memo provides guidance to TCP implementers that is intended to help improve connection convergence to steady-state operation without affecting interoperability. It updates and replaces RFC 2140's description of sharing TCP state, as typically represented in TCP Control Blocks, among similar concurrent or consecutive connections.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9040"/>
          <seriesInfo name="DOI" value="10.17487/RFC9040"/>
        </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="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>
      </references>
    </references>
    <?line 329?>

<!-- # Acknowledgments
{:numbered="false"}

TODO acknowledge. Note, numbered sections shouldn't appear
after an unnumbered one - so either move this last, or take
the numbering rule out. -->

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors would like to thank Grenville Armitage, Ingemar Johannson and Eduard Vasilenko for suggesting improvements to this document.</t>
    </section>
    <section numbered="false" anchor="change-log">
      <name>Change Log</name>
      <ul spacing="normal">
        <li>
          <t>-00 was the first individual submission for feedback by ICCRG.</t>
        </li>
        <li>
          <t>-01 adds Michael Tuexen as new co-author, and adds the following new descriptions:
          </t>
          <ul spacing="normal">
            <li>
              <t>a first version of text for Apple OSes</t>
            </li>
            <li>
              <t>a first version of text for FreeBSD</t>
            </li>
          </ul>
        </li>
        <li>
          <t>-02 adds a reference for Linux pacing, removes a comment on Linux SRTT calculation ("TODO check": it was checked, nothing to change), adds more discussion text:
          </t>
          <ul spacing="normal">
            <li>
              <t>queue dynamics / AQM interactions</t>
            </li>
            <li>
              <t>initial RTT calculation, thanks to Ingemar Johannson</t>
            </li>
            <li>
              <t>mini-bursts and their trade-offs, thanks to Eduard Vasilenko</t>
            </li>
            <li>
              <t>... and now we also have an ACK section for such thanks</t>
            </li>
          </ul>
        </li>
      </ul>
    </section>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
