#ActivityPub developers only: do you implement rate limit support in your HTTP client implementation?
-
@julian There are 3 main clusters.
They're linked here for the ActivityPub API task force, but they also apply for the federation protocol:
Rate limiting · Issue #4 · swicg/activitypub-api
"As an ActivityPub client developer, I want a reliable and standard way to discover rate limits in an ActivityPub API server, so I can avoid unexpected failures for my users."
GitHub (github.com)
-
@julian There are 3 main clusters.
They're linked here for the ActivityPub API task force, but they also apply for the federation protocol:
Rate limiting · Issue #4 · swicg/activitypub-api
"As an ActivityPub client developer, I want a reliable and standard way to discover rate limits in an ActivityPub API server, so I can avoid unexpected failures for my users."
GitHub (github.com)
@julian The first is the most standard, `Retry-After`. You get it mostly on `429 Too Many Requests` responses, as a way to tell you when you're next allowed to make a request. Unfortunately, by the time you get it, you're already in the penalty box. It's better to get information on the request quota *before* you get locked out, so you can throttle your requests and avoid getting locked out.
-
@julian The first is the most standard, `Retry-After`. You get it mostly on `429 Too Many Requests` responses, as a way to tell you when you're next allowed to make a request. Unfortunately, by the time you get it, you're already in the penalty box. It's better to get information on the request quota *before* you get locked out, so you can throttle your requests and avoid getting locked out.
@julian The second cluster is a de facto standard used for a lot of APIs, with a lot of incompatible variations. The most common pattern is:
X-RateLimit-Remaining: integer, how many requests left in your quota
X-RateLimit-Reset: timestamp, when your quota will reset to full -
@julian The second cluster is a de facto standard used for a lot of APIs, with a lot of incompatible variations. The most common pattern is:
X-RateLimit-Remaining: integer, how many requests left in your quota
X-RateLimit-Reset: timestamp, when your quota will reset to fullSo, if the rate limit is 300 requests every 5 minutes, and you've already used 143 requests, you might see headers like this:
X-RateLimit-Remaining: 157
X-RateLimit-Reset: 2026-03-22T22:10:00Z -
So, if the rate limit is 300 requests every 5 minutes, and you've already used 143 requests, you might see headers like this:
X-RateLimit-Remaining: 157
X-RateLimit-Reset: 2026-03-22T22:10:00Z@julian Unfortunately, there are a ton of conflicting variations on this pattern. Some APIs use a Unix timestamp for the reset datetime (!), others use HTTP header values. Mastodon uses an ISO 8601 datetime.
The X-RateLimit-* headers also don't work well if there are multiple quota policies. That can happen if there are particular types of requests that are under a stricter quota than others. There are some variants that APIs use, but they're specific to the platform.
-
@julian Unfortunately, there are a ton of conflicting variations on this pattern. Some APIs use a Unix timestamp for the reset datetime (!), others use HTTP header values. Mastodon uses an ISO 8601 datetime.
The X-RateLimit-* headers also don't work well if there are multiple quota policies. That can happen if there are particular types of requests that are under a stricter quota than others. There are some variants that APIs use, but they're specific to the platform.
@julian The big advance is the new rate limit headers RFC draft:
RateLimit header fields for HTTP
RateLimit header fields for HTTP (Internet-Draft, 2025)
IETF Datatracker (datatracker.ietf.org)
It supports having multiple policies. It's very clean and elegant. Unfortunately, it's still in draft stage. It's probably good to be ready for future changes if you're going to implement this.
-
@smallcircles @julian I think that's always a tension in standards! How do you make it explicit enough that developers can build interoperable software, but extensible enough that they can try new things?
I think one pattern that works well is some base-level standards assumed, and easy ways for extensions to be discoverable and negotiable. If your preferred extension isn't available from the software on the other side of the line, you fall back to the base-level standard.
-
@smallcircles @julian I think that's always a tension in standards! How do you make it explicit enough that developers can build interoperable software, but extensible enough that they can try new things?
I think one pattern that works well is some base-level standards assumed, and easy ways for extensions to be discoverable and negotiable. If your preferred extension isn't available from the software on the other side of the line, you fall back to the base-level standard.
@smallcircles @julian I'd suggest streaming data as an example of a good extension. If it's not available, the client can resort to periodically polling instead.
-
#ActivityPub developers only: do you implement rate limit support in your HTTP client implementation?
Thanks to everyone who responded. My answer is yes; I've had to add HTTP client throttling support in tags.pub. I'm going to add rate limit checking on the server side, too. It's worth it to be explicit.
-
@smallcircles @julian I'd suggest streaming data as an example of a good extension. If it's not available, the client can resort to periodically polling instead.
I have created a separate issue "Protocol design" in the #ActivityPub API repo, cross-referencing to this discussion and the issue I created earlier to "Avoid misconception".
Protocol design · Issue #66 · swicg/activitypub-api
(This issue is created in follow-up of #63 Avoid misconception and #4 Rate limiting, and related fedi thread.) Avoiding misconceptions: What is a profile? I think my overarching concern is that the ActivityPub API specification doesn't b...
GitHub (github.com)
-
I have created a separate issue "Protocol design" in the #ActivityPub API repo, cross-referencing to this discussion and the issue I created earlier to "Avoid misconception".
Protocol design · Issue #66 · swicg/activitypub-api
(This issue is created in follow-up of #63 Avoid misconception and #4 Rate limiting, and related fedi thread.) Avoiding misconceptions: What is a profile? I think my overarching concern is that the ActivityPub API specification doesn't b...
GitHub (github.com)
Great, thanks.