Identify the limiting layer
Limits can originate from reverse proxies, gateway user or model limits, channel capacity, and upstream providers. Values and windows depend on deployment configuration; OpenRouter plan limits do not describe your own instance. Additional API keys do not necessarily increase a user’s aggregate allowance.
The Redis rejection path in current
middleware/model-rate-limit.go sets Retry-After in seconds. Its in-memory implementation can reject without that header and with an empty body. Other limiting paths and upstream behavior differ, so do not require JSON error bodies or uniform rate-limit headers on every 429.
Retry-After can contain seconds or an HTTP date. It suggests when to try again, without guaranteeing success. Use jittered backoff when absent or invalid. If the wait exceeds your total deadline, stop instead of shortening the server’s requested wait and retrying early.
Runnable: discover models and record diagnostic metadata
Saveexamples/diagnostics.mjs with http-client.mjs in the same directory. Run from the documentation directory:
API_ROOT_URL, excluding /v1. The script only calls GET /v1/models, with at most 3 attempts and a 10-second total deadline. Only 429 / 502 / 503 / 504 are retried. Network errors, redirects, other HTTP errors, and invalid success responses stop immediately. Error bodies are not printed; success bodies are limited to 1 MiB and only the model count is output. stderr receives status, attempt, cumulative elapsed time, and a format-checked request ID when each response’s headers arrive.
maxRetries: 0. Successful model discovery does not verify inference capability; see production acceptance.