Limits
Morse has three limits you can actually hit, and each one returns a different 429 so you can
tell them apart without guessing:
| What ran out | Error code | Is it a billing event? |
|---|---|---|
| Monthly billable-span allowance | event_limit_exceeded | Yes — upgrade or wait for the period to reset |
| Infra-span fair use | INFRA_SPAN_FAIRUSE_EXCEEDED | No — a storage ceiling, never billed |
| Ingest rate | RATE_LIMIT_INGEST / SPAN_BURST_LIMIT | No — retry shortly |
Every one of them sets Retry-After where retrying is the right move.
What counts against your plan
Only spans your own code authored are billable. Spans of type db and http — the ones our
auto-instrumentation creates for you — are ingested, stored, correlated, and shown in the trace
exactly like any other span, and are never counted against your monthly allowance.
This matters more than it sounds. On a typical auto-instrumented workload we measured about
11.5 infrastructure spans for every billable span — roughly 90% of all spans are db spans
our SDK wrote, not calls you made. Metered naively, that would mean two bad things:
- You could not forecast your bill from anything you control. An N+1 query in your code would arrive as a billing incident rather than a performance one.
- Correlating infrastructure into your traces — the thing Morse is for — would be the thing that multiplied your bill.
So we took it off the meter. Correlate as much infrastructure as you want; we don’t bill you for spans you didn’t write.
The no-silent-raise commitment
This is a promise, not a current-behavior note:
The set of non-billable span types may only ever grow.
When we add a new auto-instrumentation source — cache, middleware, queue, anything — it will not increase the billable volume of any existing customer. A Morse SDK upgrade can lower what you’re metered for. It cannot raise it.
Without this, “we don’t bill for auto-instrumented spans” would be worth very little: we could ship a new instrumentation source next month, your span count would jump, and nothing in your code would have changed. The commitment closes that door and is the reason you can size a plan against your own code rather than against our release schedule.
The current non-billable set is db and http. If it ever changes, it changes by getting
longer.
Infra span fair use
Exempting infrastructure spans from the meter does not exempt them from storage, so they are bounded rather than billed. The ceiling is 10× your plan’s billable-span allowance per month, and hitting it returns:
{
"error": "INFRA_SPAN_FAIRUSE_EXCEEDED",
"message": "Fair-use ceiling of … auto-instrumented (db/http) spans reached …",
"current_count": 750000,
"limit_count": 750000,
"plan_id": "free",
"docs_url": "https://docs.morsehq.dev/limits#infra-span-fair-use"
}This is not a billing event and never becomes one. There is deliberately no upgrade prompt or usage-breakdown pressure in that response — it is a storage guard, and it is scoped to spans you are not paying for.
Because the measured real-world ratio is about 11.5:1 against a billable allowance already sized
above expected usage, a 10× ceiling leaves substantial headroom over normal auto-instrumented
volume. In practice you reach it only through runaway instrumentation — most often a polling loop
or health check instrumented per request, writing thousands of near-identical db spans an hour.
If you hit it:
- Look at the traces with the highest
db/httpspan counts — a single repeating caller is the usual culprit. - Stop instrumenting the hot path that is generating them, or reduce its call rate.
- If your workload genuinely needs the volume, a higher plan raises the ceiling with the allowance, since the ceiling is derived from it.
The counter resets with your billing period.
Ingest rate limits
Two independent gates protect ingestion, one on requests and one on spans:
- Requests per second, per API key (
RATE_LIMIT_INGEST). A per-key sliding window. Sustained abuse — 10× your plan’s limit within a rolling hour — trips an org-level circuit breaker that returns503 CIRCUIT_BREAKER_OPENuntil support restores service. - Spans per second, per org (
SPAN_BURST_LIMIT). A rate limit on requests alone would let a compliant request rate of maximum-size batches drain a month’s quota in seconds, so batch size is budgeted too. The budget is set so a full month cannot be consumed in under roughly 15 minutes, and it is checked before your batch is added — a single large batch on an idle connection is never rejected.
Both return Retry-After: 1. The Morse SDKs already retry with backoff, so if you are using one
you generally do not need to handle these yourself.
Related
- Usage — this period’s consumption against your allowance.
- Billing — plans, allowances, and invoices.
- Data model — what a span is and how span types are assigned.