[httpapi] other algorithms and ratelimit headers
Tony Finch <dot@dotat.at> Mon, 19 January 2026 20:46 UTC
Return-Path: <dot@dotat.at>
X-Original-To: httpapi@mail2.ietf.org
Delivered-To: httpapi@mail2.ietf.org
Received: from localhost (localhost [127.0.0.1]) by mail2.ietf.org (Postfix) with ESMTP id B24B7AA1274E for <httpapi@mail2.ietf.org>; Mon, 19 Jan 2026 12:46:10 -0800 (PST)
X-Virus-Scanned: amavisd-new at ietf.org
X-Spam-Flag: NO
X-Spam-Score: -2.799
X-Spam-Level:
X-Spam-Status: No, score=-2.799 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=pass (2048-bit key) header.d=dotat.at header.b="MLwF6kgH"; dkim=pass (2048-bit key) header.d=messagingengine.com header.b="WuuIS2ug"
Received: from mail2.ietf.org ([166.84.6.31]) by localhost (mail2.ietf.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2sjJPTEzgTMG for <httpapi@mail2.ietf.org>; Mon, 19 Jan 2026 12:46:09 -0800 (PST)
Received: from fhigh-b8-smtp.messagingengine.com (fhigh-b8-smtp.messagingengine.com [202.12.124.159]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mail2.ietf.org (Postfix) with ESMTPS id A3424AA12749 for <httpapi@ietf.org>; Mon, 19 Jan 2026 12:46:09 -0800 (PST)
Received: from phl-compute-10.internal (phl-compute-10.internal [10.202.2.50]) by mailfhigh.stl.internal (Postfix) with ESMTP id 6425E7A03DF; Mon, 19 Jan 2026 15:46:03 -0500 (EST)
Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-10.internal (MEProxy); Mon, 19 Jan 2026 15:46:03 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dotat.at; h=cc :content-type:content-type:date:date:from:from:in-reply-to :message-id:mime-version:reply-to:subject:subject:to:to; s=fm3; t=1768855563; x=1768941963; bh=eGP1Q93gtpWHFa5zcOhSsl3Q6zbiAgr4 n6yoyIXdZTg=; b=MLwF6kgHp1nejHsjXFiNVaYFuyVtnkf80W2NmLQ+b5T2TvxI DqMSz0NOJH4mdAdWk5iQ0eb49NaVOqfnUM5sFZAPtEQu2shfS2l8UpvGgDXwRGiJ Uxx8jDAO8DyxjpDthZor1p0s7/n/aYDiwpq5CLkYuBdYtm+pE6UcpnF5bpSwGRpU kHbo1RgdLtIQ3PuDii9QanYh6JdXyB19JXXIyXuAZjqVLdM+TS/TddSzQTj95aqc +6cFj39Ihc/9RR1v4uK7xKAnmYG6n/9w56ESGvDEyo3+gqoq3vdnKSGhgaMm+LSr DfO6Bw6vFuJF3iCAvrRWrO601i2rle+qGTpzmA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:message-id :mime-version:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1768855563; x= 1768941963; bh=eGP1Q93gtpWHFa5zcOhSsl3Q6zbiAgr4n6yoyIXdZTg=; b=W uuIS2ugfy9INLK248J9r2Grxz5eUt9WCZSzTOKHROhYd4zxM6T5pL8EWSBBEyi6v PYmTMBYW20WjA+KBtCkNA/+uGOxVorfOugg5HHvif7Y2gl4qBcPC/DxcYRPVOx0j kqZBeRXI0mf91TQnFo6/VVh9gqkjT5CJ/1llr+iJ5Vl9PQDNT+rDhzTcGSSVNmnW uyZpmeY6MvR3xA/IjXi512XnYl+HY5aUobkFFljCwCeh4ylHEFrPBofjbj5MuQQn SLc47OJLYcFYIcf2MciJTBTTHtzxgYRzrzzt9cYujBktjIxDygUEfEZG3bIxKjqM sV6B9mnw4P+EJhkn0FaZg==
X-ME-Sender: <xms:C5huaalb7jXRwdxe--sB_y6Q2bFvR7e70yHn_CIcTIdZgqQMPuxcxg> <xme:C5huaR9eNDV-OfS8VwGSU2Cnwn2V6vLSNa8UEQrssZnGZR6Mw1zClmS4VxwtkiEBI no6ibbTHJ0AU82-3hMNwS8EZ6Y89VVD9QrJAhk90DqHEYKcCko>
X-ME-Received: <xmr:C5huaQn3Qsj7hxbdEf_fQj1tpYb6D3ZyjX8haykBSF2CPj8HU-80YAOw8DR_RDTfGcM04RgLET5QMdRoabxrgVd2z1nIPDUv>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddufeekheeiucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpeffhffvuffkgggtsehttdertddttddvne cuhfhrohhmpefvohhnhicuhfhinhgthhcuoeguohhtseguohhtrghtrdgrtheqnecuggft rfgrthhtvghrnhepuefgkeeigeeiueetgeetjefguddvvdeghfeuteehheegjeeuteehfe ektddtiedvnecuffhomhgrihhnpeguohhtrghtrdgrthenucevlhhushhtvghrufhiiigv pedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpeguohhtseguohhtrghtrdgrthdpnhgspg hrtghpthhtohepgedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohephhhtthhprghp ihesihgvthhfrdhorhhgpdhrtghpthhtoheprhhosghiphholhhlihesghhmrghilhdrtg homhdprhgtphhtthhopegrlhgvgiesfhhlrgifvggutghouggvrdhorhhgpdhrtghpthht ohepuggrrhhrvghlsehtrghvihhsrdgtrg
X-ME-Proxy: <xmx:C5huaW0F8FvE5nuM78qA8_y_q5-CkA8VMDcmnj8NgMqemBs3KQMqpg> <xmx:C5huaTpLeL77UdgfE34VwlsZxD9rRmSUaQUoptU-7NvMyHHi180_hg> <xmx:C5huabcxZqtdIEAgXFxq63X4ohcmm8pI312gWXwsbAauNQy-aMkHkA> <xmx:C5huaarKIv_Vhpf-LRI5m_g1jxopYjCvldURBr4FHp7mX-b_yVHbQg> <xmx:C5huaUEKqbZ2mlHjhESYrW0-st5r6CrVZJmpAttZl11eMsBFz6-N3DwJ>
Feedback-ID: i7158435c:Fastmail
Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 19 Jan 2026 15:46:02 -0500 (EST)
Date: Mon, 19 Jan 2026 20:46:01 +0000
From: Tony Finch <dot@dotat.at>
To: httpapi@ietf.org, robipolli@gmail.com, alex@flawedcode.org, darrel@tavis.ca
Message-ID: <7f2dc1cc-1585-f602-7a49-60a716487cfd@dotat.at>
MIME-Version: 1.0
Content-Type: text/plain; charset="US-ASCII"
Message-ID-Hash: AOFKWB2AQYEY4UNJJQPJEHKYUNIB3KCJ
X-Message-ID-Hash: AOFKWB2AQYEY4UNJJQPJEHKYUNIB3KCJ
X-MailFrom: dot@dotat.at
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
X-Mailman-Version: 3.3.9rc6
Precedence: list
Subject: [httpapi] other algorithms and ratelimit headers
List-Id: Building Blocks for HTTP APIs <httpapi.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/httpapi/prI-_67g4TdQJOnAP39lkU0mAyY>
List-Archive: <https://mailarchive.ietf.org/arch/browse/httpapi>
List-Help: <mailto:httpapi-request@ietf.org?subject=help>
List-Owner: <mailto:httpapi-owner@ietf.org>
List-Post: <mailto:httpapi@ietf.org>
List-Subscribe: <mailto:httpapi-join@ietf.org>
List-Unsubscribe: <mailto:httpapi-leave@ietf.org>
I've been experimenting with the RateLimit header and a few different rate
limiting algorithms. The current spec seems reasonably adaptable, but I
had to read it in a creative manner to make it work with other algorithms.
There are a number of places in the draft that seem to exclude rate
limiting algorithms that incrementally adjust a quota or a measured rate.
This is most obvious in the "reset parameter" whose name doesn't make
sense for rate limit algorithms such as GCRA that do not reset quotas.
It's true there are also a number of places in the draft that say the
reset parameter doesn't necessarily behave as a reset time, but that seems
like an obtuse way to specify it.
I suggest rephrasing the semantics in terms of how the server is
asking the client to behave, in general terms.
In section 4, the term "reset time" implies far too much about how the
server might behave, and "remaining quota" implies the quota goes
down. (Some rate limit algorithms such as GCRA can gradually increase
`r` when the client's rate is below its limit.)
I suggest calling `r` and `t` the "available quota" and "effective
window", i.e. the quota and window that currently apply to this
client. This choice of words is supposed to imply that the `r` quota
and `t` window can be dynamically adjusted.
For instance, section 2 might be rephrased like:
* Quota:
A quota is an allocation of capacity that a server uses to limit
client requests. That capacity is measured in quota units that clients
can consume within a time window.
* Service Limit:
A service limit is the currently available quota under a specific
quota policy and, if defined, the effective time window within
which the client can use no more than the available quota
Some wording suggestions for section 4:
> * r: This REQUIRED parameter value conveys the available quota for
> the identified policy (Section 4.1.1).
>
> * t: This OPTIONAL parameter value conveys the effective window
> within which the client can use no more than the available quota
> (Section 4.1.2).
>
> ...
>
> 4.1.1. Available Quota Parameter
>
> The "r" parameter indicates the quota units that are currently
> available to use.
>
> It is a non-negative Integer expressed in quota units. The server MAY
> arbitrarily alter the available quota parameter value between
> subsequent requests. Clients MUST NOT assume that a positive remaining
> value is a guarantee that further requests will be served. When the
> remaining parameter value is low, it indicates that the server may
> soon throttle the client (see Section 6).
>
> ...
>
> 4.1.2. Effective Window Parameter
>
> The "t" parameter indicates the number of seconds within which the
> client MUST NOT try to consume more than the available quota "r".
>
> ...
>
> The server MAY arbitrarily alter the available quota and effective
> window parameter values between subsequent requests; for example, in
> case of resource saturation or to implement sliding window policies.
>
> The client can expect that more quota units will be available at the
> end of the effective window, but MUST NOT assume that its full quota
> will be restored.
## server behaviour: retry-after
> If a response contains both the Retry-After and the RateLimit header
> fields, the Retry-After field value SHOULD NOT reference a point in
> time earlier than the reset parameter.
Is it guaranteed that a Retry-After header is caused by a RateLimit
policy violation? What about headers that indicate there's plenty of
ratelimit quota remaining but the server wants the client to try later
for some other reason?
Retry-After: 30
Ratelimit: "spqr";r=1000;t=100
It would make sense to me if Retry-After has to be at least as late as
the RateLimit t= effective window when the available quota r= is zero,
but can be anything when the available quota r > 0.
## server behaviour: ratelimit vs ratelimit-policy
> A service using RateLimit header fields MUST NOT convey values
> exposing an unwanted volume of requests
Would it make sense to be more specific here, e.g. recommending that
the RateLimit r=;t= values should be less than the RateLimit-Policy
q=w= values?
## miscellaneous nits
### introduction
The headers allow multiple policies, so I suggest pluralizing the
summaries like:
* RateLimit-Policy: quota policies, defined by the server, that
client HTTP requests will consume.
* RateLimit: currently remaining quota available for specific
policies.
### notational conventions
The list of terms from [SF] is missing Parameters, Byte Sequence, String
--
Tony Finch <dot@dotat.at> https://dotat.at/
Malin, Hebrides: Cyclonic 5 to 7, occasionally gale 8 later in Malin,
perhaps gale 8 later in Hebrides. Rough or very rough. Occasional
rain. Good, occasionally poor.
- [httpapi] other algorithms and ratelimit headers Tony Finch
- [httpapi] Re: other algorithms and ratelimit head… Roberto Polli
- [httpapi] Re: other algorithms and ratelimit head… Tony Finch