Know your quota
Your account has 60 RPM and 10 concurrent jobs. 60 RPM means one request per second, every second. If your pipeline can burst above that, you’ll get 429s. Design for the average, not the peak.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: 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.

