Rate limits
ClickStream rate-limits per API key. The public tier number is the sustained collector requests per second your key can send. The SDK batches events, so one request can carry more than one click, scroll, or identify event.
Behind the scenes, the collector enforces that number as a rolling one-minute bucket with a generous 2x burst allowance for real-world spikes. In plain English: you can spike briefly without getting cut off, but sustained traffic above your tier eventually receives 429 responses until the bucket resets.
Per-tier caps
Collector caps, per API key, measured as sustained requests/second:
| Tier | Requests / sec | One-minute bucket | Short burst bucket | Human pageview cap* | Signals Coverage | Overage behavior |
|---|---|---|---|---|---|---|
| Hobby | 100 | 6,000 requests | 12,000 requests | 50,000 pageviews | 250,000 events | Included allowance; collection fails open |
| Growth | 1,000 | 60,000 requests | 120,000 requests | 500,000 pageviews | 2.5M events | Included allowance; collection fails open |
| Scale | 5,000 | 300,000 requests | 600,000 requests | 5,000,000 pageviews | 25M events | Included allowance; collection fails open |
| Network | 25,000 | 1,500,000 requests | 3,000,000 requests | 25,000,000 pageviews | 250M events | Included allowance; collection fails open |
| Enterprise | Contract | Contract | Contract | Contract | Contract | Negotiated |
*The human pageview cap is the included quota for billable human pageviews. Bot, AI crawler, answer-engine, automation, kiosk, and tool traffic does not count as human pageviews, but it can count toward Signals Coverage because it still requires traffic-intelligence work. Click, scroll, form, custom, and identify events help classification but do not count as human pageviews. See the Pricing page for the full tier matrix.
Why request limits, human pageviews, and Signals Coverage are separate
Request limits protect the collection pipe from floods. Human pageview caps are the primary value meter. Signals Coverage protects the infrastructure cost of classifying non-human traffic and serving active Signals decisions.
That means a normal SDK batch with one human pageview plus several clicks still uses one collector request, while only the human pageview counts toward the human monthly cap. Non-human crawler or tool traffic can count toward Signals Coverage instead. Browser visitor realtime streams also draw from Signals Coverage: each open stream reserves 300 units, matching the five-minute server cap at 1Hz active Signals reads. This keeps Hobby useful for real sites and keeps paid customers from being cut off too early during normal interaction-heavy sessions.
Burst allowance
The effective short-burst bucket is 2x the sustained one-minute bucket. A Growth key has a sustained 60,000-request minute and a short burst ceiling around 120,000 requests before the limiter starts rejecting. The sustained 1,000 requests/sec rate reasserts as the rolling window advances.
This exists because real-world traffic is not smooth: brief traffic spikes, crawler waves, monitoring bursts, and QA runs can raise request volume for a few seconds. The burst bucket absorbs the first spike; sustained load beyond the tier still hits the cap.
429 response
When the bucket is exhausted, the collector returns:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 47
X-RateLimit-Limit: 60000
X-RateLimit-Burst-Limit: 120000
X-RateLimit-Policy: 60000;w=60;burst=2
X-RateLimit-Scope: ingest
X-RateLimit-Unit: requests
X-RateLimit-Remaining: 0
X-RateLimit-Burst-Remaining: 0
X-RateLimit-Reset: 1713797700
{
"error": "rate_limit_exceeded",
"message": "Rate limit exceeded (ingest: 1000 requests/sec sustained, 2x burst). Retry in 47s.",
"retryAfter": 47
}
Well-behaved clients, including the ClickStream SDK, respect Retry-After and back off. If you are building your own sender, keep a small local queue and retry after the reset instead of dropping data immediately.
Headers on successful responses
Every authenticated response, not just 429, carries the rate-limit state so you can budget preemptively:
X-RateLimit-Limit: 60000
X-RateLimit-Burst-Limit: 120000
X-RateLimit-Policy: 60000;w=60;burst=2
X-RateLimit-Scope: ingest
X-RateLimit-Unit: requests
X-RateLimit-Remaining: 119847
X-RateLimit-Burst-Remaining: 119847
X-RateLimit-Reset: 1713797700 # unix epoch seconds
Use X-RateLimit-Scope to see which bucket you are using (ingest, signals-read, or api). Use X-RateLimit-Limit and X-RateLimit-Burst-Limit when you are writing your own sender and need the exact one-minute bucket size.
Monthly caps fail open
Monthly human pageview caps are included allowances, not a site-operation kill switch. When an account exceeds its included pageview allowance, POST /v1/events and POST /v1/edge/pageview still return 202 Accepted, still write the event, and add billing metadata such as:
X-ClickStream-Billing-Mode: over_limit_fail_open
The response body mirrors that under billing.monthlyPageviews.mode. Dashboards and billing jobs can report the over-limit state, but customer page code does not stop operating just because the monthly pageview allowance is exhausted.
Stripe overage billing is not enabled by default. Once live Stripe billing is configured for the account, paid Stripe-backed accounts can opt into metered overages from the Billing page. With overage billing off, paid and active included-access accounts keep their included allowance without surprise charges, and collection remains fail-open.
Paid overages bill in blocks, not partial event dust: human pageview overage is $2.00 / 100k on Growth, $1.00 / 100k on Scale, and $0.50 / 100k on Network. Signals Coverage overage is ceil-billed per 1M coverage units at $5.00 on Growth, $3.00 on Scale, and $2.00 on Network.
When Signals Coverage is exhausted without paid overage, customer websites should keep working. The API returns cached, sampled, aggregate, or default classifications instead of blocking page code.
Sites consistently above 1M daily visitors, or sites expecting replay/realtime Signals at 20M+ daily visitors, should move to Enterprise before launch. Self-serve Network is bounded to protect shared infrastructure; Enterprise contracts set explicit throughput, retention, realtime fan-out, and cost controls.
The dashboard shows an upgrade recommendation when your trailing-3-month overage cost exceeds the next tier's monthly price. At that point it is cheaper to move up a tier than keep paying per-pageview overages.
Per-endpoint notes
POST /v1/events— the main collector counter. The limiter counts the HTTP request. The monthly human billing cap counts acceptedpageviewevents that are not clearly bot-classed; clearly non-human pageviews count toward Signals Coverage instead.POST /v1/edge/pageview— counts toward Signals Coverage for crawler, answer-engine, preview, monitor, and automation capture. Normal browser traffic should stay on the browser SDK.GET /v1/signals/:visitorId— uses a separatesignals-readbucket so page decisions do not consume event-write capacity. The official client sendssessionIdso the edge reads one live session partition. Hobby keys must includesessionId; paid keys may fall back to a wider lookup for older integrations. Keep Hobby/Growth usage to one-shot or coarse cached checks; sustained polling belongs on Scale+.GET /v1/signals/:visitorId/streamWebSocket — browser/page-code realtime stream. Scale+ only, requiressessionId, opens exactly one live-session partition, reserves 300 Signals Coverage units on subscribe, caps at 10 visitor streams per partition, and closes after five minutes or two idle minutes. Clients fall back to polling when capped.GET /signals/streamWebSocket — private tenant feed for dashboard/server subscribers. This is separate from browser page-code realtime and still requires a short-lived dashboard stream token.- Optional enrichment resolve — enrichment lookups are gated by plan and site settings. They are separate from the core Signals request limit.
WAF layer
The request limiter described above is the application-layer limiter. Cloudflare's edge can still drop obvious abuse before it reaches a Worker invocation when zone-level protection is enabled.
See also
- API keys + auth — key rotation + reserved scope labels
- Event schema — what each accepted event actually records
- Pricing — tiers, meters, included quotas