<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<!-- <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> -->


<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<!-- If further character entities are required then they should be added to the DOCTYPE above.
     Use of an external entity file is not recommended. -->

<rfc
  xmlns:xi="http://www.w3.org/2001/XInclude"
  category="std"
  docName="draft-soni-http-dynamic-backpressure-00"
  ipr="trust200902"
  obsoletes=""
  updates=""
  submissionType="IETF"
  xml:lang="en"
  version="3">

  <front>
    <title abbrev="HTTP Backpressure">Dynamic Backpressure for HTTP-based systems</title>

    <seriesInfo name="Internet-Draft" value="draft-soni-http-dynamic-backpressure-00"/>
   
    <author fullname="Soni Lasso Terense" initials="S." surname="Lasso">
      <address>
        <email>fakedme@gmail.com</email>
        <uri>https://soniex2.autistic.space/</uri>
      </address>
    </author>
   
    <date year="2024"/>

    <area>wit</area>
    <workgroup>Internet Engineering Task Force</workgroup>

    <abstract>
      <t>This document describes a mechanism for introducing dynamic backpressure
        into an HTTP-based system, to aid in controlling server resources while
    minimizing tradeoffs.</t>
    </abstract>
 
  </front>

  <middle>
    
    <section>
      <name>Introduction</name>
      <t>Operating an HTTP service can get expensive.  One of the ways services
      can manage the costs is by providing backpressure.  Traditionally, HTTP
      backpressure is implemented variously by refusing connections after a
      limit, holding a connection open and slowly trickling data into it, among
      other techniques.  This document describes a simple and widely-deployed
        mechanism for implementing backpressure by telling the client when to
        make new requests.</t>
      
      <section>
        <name>Requirements Language</name>
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
          "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT
          RECOMMENDED", "MAY", and "OPTIONAL" 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>
      </section>
    </section>
    
    <section>
      <name>Background: Why use dynamic backpressure</name>
      <t>Consider the scenario: a service that is billed by requests,
      and an Atom feed that gains new entries every 5 minutes.  This service is
      composed of app servers and caching load balancers, with a cache policy of 5
        minutes.  Yet, the service doesn't want Atom clients to send a request
        every 5 minutes.  This scenario is exactly where dynamic backpressure
        would shine: it doesn't try to slow down or throttle the connections (not
        that it would be able to, due to the caches) or anything like that, it
        simply tells the client "hey, I would appreciate it if you waited N
    seconds before sending another request, thanks!".</t>
    </section>

    <section>
      <name>Solution: The Refresh HTTP header</name>
      <t>The Refresh header is composed of a non-negative integer number of seconds
        to wait until the next request, and an optional URI to move future requests to,
        according to the following syntax described in Augmented BNF <xref target="RFC5234"/>,
          borrowing 'URI-reference' from <xref target="RFC3986"/>:</t>
        <sourcecode type="abnf" markers="false">
          <![CDATA[
refresh-value = wait-seconds [ ";url=" future-URI ]
wait-seconds = 1*DIGIT
future-URI = URI-reference
          ]]>
        </sourcecode>
        <t>The value of 'wait-seconds' SHOULD NOT be shorter than the value of
        any caching policy applied to the document.  The client SHOULD wait at
          least 'wait-seconds' before making new requests.</t>
        <t>This syntax is in alignment with <xref target="WHATWG-HTML" relative="document-lifecycle.html#the-refresh-header" section="7.7" />.</t>
        <t>Below is a diagram of how the Refresh header can be used in a generic
          control loop, with requests per second as input and wait-seconds as
          output.</t>
      <figure>
        <name>Control loop</name>
          <artwork type="ascii-art" name="control-loop.txt" alt="A generic closed-loop negative feedback control loop, titled 'Control Loop', with 'req/s' (requests per second) going into the summing input of the loop, the output of the sum going into the control function, the output of the control function going to 'wait-seconds' and into the feedback function, and the output of the feedback function going back into the subtracting input of the loop.">
            <![CDATA[
                      Control Loop

     req/s  +     +-------------------+   wait-seconds
         -->(+)-->| Control  function |----+------->
             ^-   +-------------------+    |
             |    +-------------------+    |
             +----| Feedback function |<---+
                  +-------------------+     

            ]]>
          </artwork>
      </figure>
      </section>

      <section>
        <name>Rejected alternatives</name>
        <t>The Refresh header is strongly disliked by basically everyone, but
        it may well be the only mechanism that provides the desired
        properties.  One may argue the Retry-After header would be a better
        substitute, but the Retry-After header isn't really specified for
          successful content requests such as those used by Atom
          feeds, nor is it as widely deployed as the Refresh header.</t>
      </section>
    
    <section anchor="IANA">
      <name>IANA Considerations</name>
      <t>This document requests that the IANA update the registration for the
        Refresh header to also point to this document.</t>
    </section>
    
    <section anchor="Security">
      <name>Security Considerations</name>
      <t>This document should not affect the security of the Internet.  After
    all, the Refresh header is already widely deployed.</t>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml"/>
        
      </references>
 
      <references>
        <name>Informative References</name>
       
        <reference anchor="WHATWG-HTML" target="https://html.spec.whatwg.org/multipage/">
          <front>
            <title>HTML Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>WHATWG</organization>
            </author>
            <date day="7" month="August" year="2024">Living Standard</date>
          </front>
        </reference>       
      </references>
    </references>
    
    <section anchor="Acknowledgements" numbered="false">
      <name>Acknowledgements</name>
      <t>The authors would like to acknowledge the true power of the Refresh header.  It had to be very powerful to survive this long.</t>
    </section>
 </back>
</rfc>
