RedditapisRedditapis

Rate limits

There is no per-key request quota on the Reddit data endpoints. What a 429 actually means, what Retry-After tells you, and why a fixed client-side throttle does not help.

Short version: the Reddit data endpoints have no fixed per-key request quota (deep comment search has a concurrency cap of 2, below). If you are seeing 429, throttling to a specific requests-per-minute number is not the fix, and picking one by guesswork will slow you down without stopping the errors.

What has a quota and what does not

EndpointsLimit
GET /api/reddit/* (posts, comments, users, search, listings)No fixed per-key request quota
GET /api/account/me, GET /api/account/payments30 requests per minute
POST /feedback, GET /feedback/{id}10 requests per minute
Dashboard and usage endpoints30 requests per minute
Monitoring endpointsSee Live Monitoring limits

The 30 per minute figure applies to the account endpoints only. It is not the limit on the data endpoints, and applying it there is a common and costly mistake.

So what is the 429?

It is Reddit's, relayed to you. We read Reddit through a pool of accounts. When Reddit rate-limits one of them we park it, rotate to another, and retry. You only ever see a 429 when that whole retry chain is exhausted, which makes it a transient condition rather than a quota you have crossed.

{ "error": "HTTP_429", "retry_after": 10 }

The response also carries a Retry-After header with the same value in seconds. It is a floor to honour, not a promise: the next attempt is usually served by a different, healthy account well before any per-account cooldown expires.

A 429 is not billed. You are not charged for a request that returned one.

What to do instead of a fixed throttle

  1. Treat 429 as retryable. Read Retry-After, back off exponentially from it, and add jitter so a fleet of workers does not retry in lockstep.
  2. Cap concurrency rather than requests per minute. How many calls you have in flight at once matters more here than the rate you issue them at.
  3. Do not treat 429 as fatal or as a reason to stop. The same request normally succeeds shortly afterwards.

Two concurrency limits, both answered with 429

Two things on this API answer 429, and neither is a quota. The first is a per-account cap on deep comment search (DEEP_SEARCH_CONCURRENCY, upper case, the spelling the endpoint has always used). The second is a per-key brake on reads in flight that only engages while the service is degraded (too_many_concurrent_reads, lower case, the spelling the shared error format uses). The two values are spelled differently because they come from different layers; both carry Retry-After, neither is billed.

Deep comment search: at most 2 at once per account

GET /api/reddit/search/comments/deep is the one endpoint with a cap in normal operation. Each call expands several comment trees at once, so one account can run at most 2 of them at the same time. A third call waits up to 3 seconds for a slot, then returns 429 with Retry-After: 2. It is not billed.

{ "error": "DEEP_SEARCH_CONCURRENCY", "message": "At most 2 deep comment searches can run at once per account. Wait for one to finish, then retry.", "retry_after": 2 }

Run deep searches two at a time per key and this never fires. Every other endpoint has no per-key cap in normal operation.

The per-key brake while the service is degraded

While the service is degraded (rare), a key that already has four reads in flight has its extra reads WAIT up to 2 seconds for one to finish; a read still waiting after that, or arriving when eight are already waiting, receives a 429 with "error": "too_many_concurrent_reads" and Retry-After: 2; it is not billed. Treat it as "slow down": keep at most four reads in flight per key (the message states the current limit) and retry after the header. A 503 upstream_unavailable (below) means "retry this read", so the two are distinguishable by status and by error value.

{ "error": "too_many_concurrent_reads", "message": "Too many reads are already in flight on this API key. This request was not billed. Retry after 2 seconds, or keep at most 4 reads in flight per key while the service is degraded.", "retry_after": 2 }

That is a brake on fan-out while the service is degraded, not a quota.

The other retryable statuses

A 503 means we could not complete the call at all. It is also retryable, also carries Retry-After, and is also not billed. A 502 on a GET read is not billed either: it means a hop on our side failed to answer, and a plain retry is the right response. (A write Reddit refused or throttled still bills, see the write endpoints; so does a 502 from a proxy you supplied yourself, and the few reads that use POST, such as DM threads and comment verification, keep their documented billing.)

{ "error": "upstream_unavailable", "message": "This request could not be completed right now. It was not billed. Please retry shortly.", "retry_after": 5 }

A 408 upstream_timeout means the read did not complete in time. It carries Retry-After: 2, is not billed, and a plain retry is the right response. If your client only retries 5xx, add 408 to its retry list.

{ "error": "upstream_timeout", "message": "The read did not complete in time. It was not billed. Please retry shortly.", "retry_after": 2 }

Check readiness before a burst

GET /health needs no key and answers { "ok": true, "reads": "ok" }. ok is the service being up; reads is the pass rate of customer reads over the last five minutes, as one of ok, degraded or unknown (too few reads in those five minutes to say; under a very heavy spell it is the last twenty thousand reads). When it reads degraded, expect some 503 and 408 answers and space your calls out instead of retrying hard; it is cached for ten seconds, so poll it no faster than that.

{ "ok": true, "reads": "ok" }

If 429s are constant rather than occasional

That is not normal and it is worth telling us about. Send your API key prefix and a rough timestamp to support and we will look at the traffic directly.

Independent third-party API for developers and researchers. Not affiliated with, endorsed by, or sponsored by Reddit, Inc.

On this page