rate-limit-radar
Live cross-provider LLM rate-limit reference. Scrapes the official rate-limit documentation page of every major LLM API provider every 6 hours, parses the published RPM / ITPM / OTPM / TPM / RPD numbers per tier per model, persists every snapshot, and surfaces silent changes the moment they ship. No mocks. No seed data. No fake numbers. Every cell links to the upstream URL it was scraped from.
Live at: https://holyai.me/rate-limit-radar/
Why this exists
Every production LLM app eventually gets bitten by the same paper cut: you wire your app against an assumption ("Sonnet at tier 2 gives me ~450k input TPM"), then six weeks later 429s spike and you cannot tell whether you (a) crossed a tier boundary, (b) the provider silently lowered the limit, or (c) the docs you read months ago are stale.
There is no public site that:
- shows the current RPM/TPM matrix for every major provider, by tier and model class, in one screen;
- records historical snapshots so you can prove the limit changed last Tuesday;
- emits an RSS / JSON feed that Slack or Discord can ingest;
- links every cell back to the upstream docs URL it was scraped from, with a
last_verifiedtimestamp.
rate-limit-radar is that page. Sibling product tier-drift tracks consumer subscription tiers; provider-drift tracks OpenRouter model availability. This one fills the API developer tier gap.
Data sources & fetch frequency
| Provider | Docs URL | Fetch frequency |
|---|---|---|
| Anthropic | https://docs.anthropic.com/en/api/rate-limits | every 6h |
| OpenAI | https://platform.openai.com/docs/guides/rate-limits (fallback: https://developers.openai.com/api/docs/guides/rate-limits) | every 6h |
| Google AI Studio | https://ai.google.dev/gemini-api/docs/rate-limits | every 6h |
| Mistral La Plateforme | https://docs.mistral.ai/deployment/laplateforme/tier/ | every 6h |
| Groq | https://console.groq.com/docs/rate-limits | every 6h |
| Together AI | https://docs.together.ai/docs/rate-limits | every 6h |
| DeepSeek | https://api-docs.deepseek.com/quick_start/rate_limit | every 6h |
| Cerebras | https://inference-docs.cerebras.ai/support/rate-limits | every 6h |
| Fireworks AI | https://docs.fireworks.ai/guides/quotas_usage/rate-limits | every 6h |
| xAI | https://docs.x.ai/docs/models | every 6h |
The first sweep happens ~30 seconds after the server boots; subsequent sweeps run on the 0 /6 cron schedule. If a provider blocks scraping or restructures their page, that fetcher returns status="parse_error" and the provider gets a red badge on the dashboard — never a fabricated number.
API
All endpoints are public, no auth required.
| Method | Path | Returns |
|---|---|---|
| GET | /rate-limit-radar/ | SPA dashboard |
| GET | /rate-limit-radar/health | {status, version, uptime_seconds, providers_total, providers_healthy, last_full_sweep, rows} |
| GET | /rate-limit-radar/api/providers | Each provider with last_scrape, scrape_status, error_message |
| GET | /rate-limit-radar/api/limits | Every (provider, tier, model, dimension, value, source_url) row from the latest successful scrape; supports ?provider=, ?tier=, ?model=, ?dimension= |
| GET | /rate-limit-radar/api/snapshots/:provider | All historical scrape attempts for a provider |
| GET | /rate-limit-radar/api/changes?days=N&limit=M | Diff feed of detected changes |
| GET | /rate-limit-radar/api/changes.rss | RSS 2.0 |
| GET | /rate-limit-radar/api/changes.json | JSON Feed 1.1 |
| GET | /rate-limit-radar/api/badge/:provider.svg?tier=...&model=...&dimension=... | Embeddable shields-style SVG |
| GET | /rate-limit-radar/api/methodology | Markdown listing every source URL |
| POST | /rate-limit-radar/api/refresh?provider=:id | Manually triggers a refresh (rate-limited to 1/min) |
Running locally
npm install
PORT=4795 node server.js
# Browse to http://localhost:4795/rate-limit-radar/
Stack
Node.js 20+, Express 4, better-sqlite3 (WAL), node-cron, helmet, compression, cors, cheerio. Vanilla JS SPA, dark theme, no frameworks.
Honesty rules
- NO MOCKS, NO SEED DATA, NO HARDCODED LIMIT VALUES anywhere in this codebase. Every numeric cell is the textual content of an HTML element on a public docs page, captured by a recorded
scraperow at a specificverified_attime. - NO
Math.random(), no synthetic jitter, no "realistic preset" arrays. If you ever see a number on this site that is not on the upstream docs page, file an issue — that is a bug. - NO AUTH. Every endpoint is public.
Adding a new provider
See CLAUDE.md.
License
MIT