#5443·atproto

Bluesky-hosted PDSes advertise ratelimit-policy: 6000;w=300 for getRepo but appear to function under the old 3000;w=300 limit.

Author: hmerrileesCreated Aug 25, 2026Updated Aug 25, 2026
Labelsbug

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:

  1. Send 2,900 listRepos requests.
  2. Send getRepo in batches of 20, with a listRepos to check ratelimit-remaining after each batch.
  3. The interspersed listRepos calls report global remaining values of 99, 98, 97, 96, and 95. This confirms getRepo does not consume the PDS-visible global bucket, consistent with #5082.
  4. getRepo call 95 succeeds while advertising:
       ratelimit-limit: 6000
       ratelimit-remaining: 5905
       ratelimit-policy: 6000;w=300
  1. Despite the indicated 5905 remaining, getRepo call 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!