Rate limits
Per-IP and per-key windows, 429 handling, anomaly alerts.
What this is
COHESION enforces two rate-limit layers on every request. Monthly decision allotments are separate commercial tier terms, described below. Understanding both prevents surprise 429s and surprise invoices.
Two layers
Layer 1: per-IP, pre-auth
- Cloudflare Workers Rate Limiting API.
- 60 requests per 60 seconds per IP.
- Fails closed, before any key lookup.
- Emits
AUTH_FAIL_RATE_LIMITED_IPtoaudit_log.
Layer 2: per-key, post-auth
- D1 sliding window.
- 1000 requests per 60 seconds per key prefix.
- Keyed on the 8-char prefix, never the plaintext.
- Emits
AUTH_FAIL_RATE_LIMITED_KEYtoaudit_log.
429 response
HTTP/1.1 429 Too Many Requests
Retry-After: 27
Retry-After is always an integer >= 1, per RFC 7231. Back off at least that long.
Monthly decision allotments
Each pricing tier includes a monthly decision allotment. Allotments are commercial tier terms with metered enforcement, not a request throttle: as of 2026-06-09 the two rate-limit layers above are the only technical limits enforced on the request path.
| Tier | Decisions per month |
|---|---|
| Developer (free) | 5,000 |
| L1 self-serve | 10,000 |
| Starter | 100,000 |
| Audited | 500,000 |
| Enterprise | From 5,000,000, custom volume |
Paid tiers are never cut off at the allotment. Usage beyond the allotment bills at $0.0008 per decision. Developer and L1 self-serve have no overage: Developer stops at 5,000 decisions per month, and L1 self-serve stops at 10,000 decisions per month.
Full ladder and tier features: pricing.
SDK behavior
Both SDKs auto-retry with exponential backoff, capped at maxRetries (default 3). On exhaustion they throw RateLimitError (both TS and Python), which carries retryAfter (TS) / retry_after (Python) in seconds.
Best practices
- Batch where you can (POST /v1/score/batch).
- Stagger backfill jobs across minute boundaries.
- Do not retry 429 tighter than the
Retry-Aftervalue.
Next step
- Error catalog
- Performance for latency expectations.