Hi,
Shouldn’t the delay to wait be in the Response as a Retry-After header?
The discussion centers on adding a Retry-After HTTP header when rate limiting is triggered in Discourse, as recommended by MDN and IETF standards jdevost. sam agrees it’s a good idea, and xrav3nz submits a PR to implement it, noting that some controller actions (like invites) should intentionally omit the header to hide retry timing from users. Later, Mike_Yermolayev reports that despite the PR being merged, no Retry-After header appears in responses — sharing screenshots showing missing headers despite a 429 error. guidoleenders supports the suggestion and references IETF’s standardized rate-limiting headers, noting that Discourse v3 already returns Retry-After and Discourse-Rate-Limit-Error-Code headers on 429 responses, along with JSON extras like wait_seconds. However, these headers are only sent after hitting the limit — there’s no way to proactively detect or avoid rate limits before they occur. The thread highlights the need for consistent, predictable rate-limit feedback for API clients.
Hi,
Shouldn’t the delay to wait be in the Response as a Retry-After header?
Sure, sounds like a good suggestion
Taking a stab at this ![]()
https://github.com/discourse/discourse/pull/5659
I am assuming:
Retry-After shouldn’t be set in controller actions like the following, where the retry time is (intentionally) hidden from the end user.
Hi,
Seems like the PR is merged but I don’t observe any ‘Retry-After’ headers.
Here you can see the body of my error:
Is this a bug? Thanks in advance
Good suggestion!
In between time, the IETF has standardized the headers for informing calling programs about rate limiting; see RateLimit Header Fields for HTTP. Our software uses them for a range of rate limiters (see https://forums.invantive.com/t/fair-use-daily-limits-for-a-better-user-experience/3767).
In our case it would help definitely when Discourse would return rate limit information through headers; the programs don’t have access to the configuration file and we have no exact idea without asking what the definitions are. Nor can our calling software try to evade a 429 by trying alternatives when the rate limit is in near sight.
On v3, the following headers are present that provide some guidance:
Retry-After: number of seconds after which the rate limit window expires and a new set of API calls is allowedDiscourse-Rate-Limit-Error-Code: an indication what type of rate limit is hit (such as admin_api_key_rate_limit or ip_10_secs_limit).On HTTP 429, also the payload contains some hints, but nothing additional compared to the HTTP headers:
{
"errors": [
"i18n text"
],
"error_type": "rate_limit",
"extras": {
"wait_seconds": 21,
"time_left": "21 seconden"
}
}
Note that these headers are only returned upon 429. It is not possible to predict an upcoming failure to back off a little.