Skip to content

Limits & Errors ​

Beta

Telemetry is in beta. It's included with paid plans at no extra cost while in beta, and limits are subject to change.

Plans ​

Telemetry is on paid plans. The Free plan doesn't include it: you can't create Streams, and data sent to a Free account's Streams gets 403 plan_required.

PlanStreamsEvents per monthRetentionRequests per minuteData per minute
Hobby21,000,0007 days3,00064 MB
Pro510,000,00014 days12,000256 MB
Team2050,000,00030 days30,0001 GB
Founders510,000,00014 days12,000256 MB
EnterpriseCustomCustomUp to 90 daysCustomCustom

Events, requests and data are counted across every Stream in every namespace on the account, not per Stream.

Monthly events ​

Every stored record counts as one event. Each Stream's Overview shows the account's total for the month.

  • At 80% and 100% we email the account owner, and the console shows a banner.
  • At 110% ingest pauses until the 1st of next month (UTC): requests get 429 quota_exceeded. Upgrading lifts the pause within a minute, and your stored data is never affected.

Rate limits ​

Budgets are per rolling minute and apply across all our servers, so bursts are fine as long as the minute's total stays under the budget.

  • Account budget: the plan's requests and data per minute (table above). Data is the request body as sent, so compressing stretches it further.
  • Key limits (optional): cap a single ingest key below the account budget, for example a key shipped in browser code. Set them under Keys & Setup → Limits.
  • Fair share: if ingest falls behind and our buffer passes half full, the Streams holding the most of it are slowed first (429 buffer_fair_share), so one flood can't hold up everyone else.

A 429 always carries Retry-After, and tells you which limit you hit in the X-Latency-Limit header and the body's limit field:

limitMeaning
account_requests_per_minuteOver the plan's requests per minute
account_bytes_per_minuteOver the plan's data per minute
key_requests_per_minuteOver this key's own request limit
key_bytes_per_minuteOver this key's own data limit
buffer_fair_shareIngest is catching up and this Stream holds more than its share
monthly_eventsThe account is at 110% of its monthly events (quota_exceeded)

Throttled requests show up in the Stream's Overview, under usage and Ingest Health.

Requests ​

LimitValue
Request body4 MB (compressed size, if you compress)
Decompressed body32 MB
Records per request100,000

Batching is the way to go: one request with 1,000 records costs you far less than 1,000 requests.

Records ​

LimitValueOver the limit
Log message or event body1,048,576 charactersThe excess is dropped
Attributes per record256Extra attributes are dropped
Attribute name256 charactersThe excess is dropped
Attribute value16 KBThe excess is dropped
Nesting depth8 levelsDeeper objects are stored as JSON text

Nothing is dropped silently. The record is still stored, and carries a latency.dropped attribute saying what was dropped (for example body:2000000>1048576 attrs:+56), so you can find them all with the search latency.dropped:*. Each Stream's Overview counts records with dropped data and shows why, with an example.

Timestamps ​

  • More than 24 hours in the future: replaced with the time we received it.
  • Older than the stream's retention: rejected, since it would be deleted straight away.

Responses ​

StatusMeaningWhat to do
202 (HTTP API) or 200 (OpenTelemetry)StoredNothing
400 stream_type_mismatchOpenTelemetry signal sent to the wrong kind of streamUse a key from a stream of the right type
401Key missing, wrong, disabled or revoked, or its Stream is deletedCheck the key in Manage Streams
403 plan_requiredThe account's plan doesn't include telemetryUpgrade the plan
403 ingest_blockedLatency has blocked this key, Stream or namespace; the body's reason says whyContact feedback@latency.app
403 (older URL)Only with /v1/ingest/{stream}: the key belongs to a different StreamSend to /v1/ingest
413Body over 4 MBSend smaller batches, or compress
415Unsupported Content-Type or Content-EncodingSee the HTTP API or OpenTelemetry setup
429 rate_limitedOver a rate limitRetry after the Retry-After header
429 quota_exceededThe account is at 110% of its monthly eventsUpgrade, or wait for next month
429 ingest_backlog_fullOur buffer is full while ingest catches upRetry after the Retry-After header
503Ingest briefly unavailableRetry after the Retry-After header

429 and 503 are safe to retry. OpenTelemetry SDKs and the Collector do it automatically. For the HTTP API, add an Idempotency-Key so a retry never stores twice. A 403 won't succeed on retry, so SDKs drop the data instead.

Records we can't read ​

A 202 means the request was stored, before we parse it. If a record turns out to be unreadable (say, a metric with no name, or a timestamp older than the Stream's retention), that record is skipped and the rest of the request is kept. A body that can't be read at all (invalid JSON, say) is set aside whole.

Either way you can see it: the Stream's Overview lists every reason from the last 7 days with a count and an example, and counts rejected records in its usage.

© 2026 Latency Labs LLC