Bluesky-hosted PDSes advertise ratelimit-policy: 6000;w=300 for getRepo but appear to function under the old 3000;w=300 limit.
Describe the bug
Bluesky-hosted PDSes advertise getRepo as 6000;w=300, but calls to getRepo return a generic HTML 429 after exactly 3,000 total requests across endpoints.
To Reproduce
Steps to reproduce the behavior:
- Send 2,900
listReposrequests. - Send
getRepoin batches of 20, with alistReposto check ratelimit-remaining after each batch. - The interspersed
listReposcalls report global remaining values of 99, 98, 97, 96, and 95. This confirmsgetRepodoes not consume the PDS-visible global bucket, consistent with #5082. getRepocall 95 succeeds while advertising:
ratelimit-limit: 6000
ratelimit-remaining: 5905
ratelimit-policy: 6000;w=300- Despite the indicated 5905 remaining,
getRepocall 96 (the 3001st call across all endpoints) returns a 429 with no ratelimit headers.
That the 429 has neither the x-powered-by: Express of the successful responses or any ratelimit-* headers and that the headers when present seem to decrement according to #5082 makes me suspect that the 429 is generated neither by the getRepo limiter nor the getRepo-excluded global limiter but an additional, sequentially-prior rate limiter that replicates the old global policy of 3000;w=300 over all endpoints that was in place prior to #5082.
Expected behavior
Expected 6000 calls permitted to getRepo within the w=300 window.
Details
Reproduced on meadow.us-east.host.bsky.network at 2026-08-25T22:49:04.324Z
Resolved IP: 40.160.16.164
Thank you all! ATProto is a joy to work with!
Source: bluesky-social/atproto