Rate Limits

Rate Limits

Tripswitch rate limits are there to protect two different surfaces: runtime reads and metric ingest. They are related, but they are not the same bucket.

If you are integrating with project keys or signed ingest, this page is the contract to reason against.


The Two Surfaces

Tripswitch exposes two rate-limited surfaces:

Surface Identity Typical endpoints
Runtime API Project API key /v1/projects/:project_id/status, breaker state reads, metadata reads, SSE state stream
Ingest API Project + HMAC secret /v1/projects/:project_id/ingest

These surfaces are isolated from each other.

A burst of runtime status reads does not consume ingest quota. A spike in ingest does not throttle runtime reads.


Runtime API Limits

Project-key runtime requests must pass two checks:

  1. A per-key request budget
  2. A project-wide ceiling

The per-key budget is tier-aware. Each project key gets its own minute-based request budget from the owning org’s tier.

The project-wide ceiling is separate. It exists to stop a project from multiplying its total runtime throughput by minting more keys.

That means:

  • Two different keys in the same project do not drain each other’s per-key budget.
  • All keys in the same project still share the project-wide runtime ceiling.
  • Adding more keys increases concurrency options, not total project throughput without bound.

Current per-key defaults

Tier Per-key runtime requests per minute
Free 60
Starter 600
Pro 6000

The project-wide runtime ceiling is separate from these tier values and is enforced as an anti-abuse guardrail.

What counts against the runtime budget

Runtime API limits apply to project-key authenticated request paths, including:

  • GET and HEAD requests to project status
  • breaker state reads and batch state reads
  • metadata reads on project-scoped breaker and router endpoints
  • establishing an SSE status stream connection

The SSE connection attempt counts as a request. Messages delivered over an already-open stream do not consume additional request budget.


Ingest API Limits

Signed ingest is project-scoped, not key-scoped.

Tripswitch applies two ingest checks:

  1. A project-wide request ceiling
  2. A project-wide sample-volume ceiling

The request ceiling protects the ingest endpoint from request floods.

The sample-volume ceiling protects the system from sustained high-volume writes even when those writes are batched efficiently. Sample count, not request count, is the load-bearing metric there.

This distinction matters:

  • One request carrying 1000 samples is cheap on the request budget and expensive on the sample budget.
  • One hundred tiny requests are expensive on the request budget even if the total sample count is modest.

If you batch samples, you still need to respect both dimensions.


What a Rate-Limited Response Looks Like

When a request is denied, Tripswitch returns:

  • HTTP 429
  • JSON body: {"error":"rate_limited"}
  • Retry-After header in whole seconds

Retry-After is the value clients should trust. It already reflects the bucket that denied the request.

Do not guess. Wait at least that long before retrying.


Client Behavior

Runtime clients

  • Honor Retry-After.
  • Treat repeated 429 responses as a signal to reduce polling frequency.
  • Back off SSE reconnect loops. Fast reconnect loops are a common way to burn runtime budget without learning anything new.

Ingest clients

  • Honor Retry-After.
  • Keep batches bounded and consistent.
  • Do not fan out retries from multiple workers against the same project when the project is already rate-limited.

If your client ignores Retry-After, you turn a short throttle into a sustained denial.


Common Questions

Does adding more project keys increase total runtime throughput?

Not without limit.

Each key gets its own tier-based minute budget, but the project still shares a separate runtime ceiling. More keys isolate callers from each other. They do not remove the project-wide guardrail.

Can runtime traffic throttle ingest?

No.

Runtime project-key requests and signed ingest requests use separate project-level buckets.

Does opening an SSE stream count as a request?

Yes.

The connection attempt counts against the runtime request budget. Stream delivery after the connection is established does not.

Is ingest limited per key?

No.

Signed ingest is project-scoped. The limiter keys off the authenticated project, not an individual project API key.


Related Guides