Know your quota
| Tier | RPM | Concurrency |
|---|---|---|
| Free | 10 | 2 |
| Pro | 60 | 10 |
| Business | 200 | 50 |
| Enterprise | 1,000 | 200 |
Rule #1: batch where you can
The biggest footgun is firing sync scrapes in afor loop:
POST /v1/read with urls: [...] counts as one request toward RPM:
Rule #2: honor Retry-After
When you get arate_limited error, Reader tells you how long to wait:
Retry-After header with the same value. The SDK honors this automatically. If you’re calling the API directly, sleep for that duration before retrying:
Rule #3: spread out bursts
If you suddenly have 500 URLs to scrape and your tier is 60 RPM, you need to feed them through at a controlled rate. Use a token bucket or a simple delay:Rule #4: don’t poll too hard
Rule #5: separate interactive and background traffic
If you have both user-facing requests and background workers sharing one API key, the background workers will eat the rate budget and starve the users. Two options:- Two API keys, two rate limit overrides (Pro+): set a low RPM override on the background key so interactive traffic always has room.
- A queue in front of background work: let background requests wait, never throttle interactive requests.
Detecting approaching limits
Watch for a risingrate_limited error rate as an early signal. The Reader dashboard shows this; you can also log it yourself and alert when it crosses a threshold.

