Home
On-call

On-call limits

Every limit that applies to a webhook you send us, what happens when you cross it, and which ones you can change. Values here are the defaults a new integration starts with.

Every limit that applies to a webhook you send us, what happens when you cross it, and which ones you can change. Values here are the defaults a new integration starts with.

Delivery rate

LimitDefaultRangeScope
Sustained rate60 deliveries/minute1–6000Per integration
Instantaneous burst15 deliveriesderived: ceil(rate ÷ 4)Per integration
Refill1 delivery/secondderived: rate ÷ 60Per integration

The budget is a token bucket, not a fixed window. At the default you may send 15 deliveries back-to-back, after which one more becomes available each second, up to 15 again. A source that paces itself at or under the sustained rate never sees a refusal regardless of how long it runs.

The budget is per integration, not per organization. A noisy Grafana integration cannot exhaust the budget of your PagerDuty one. If you need more headroom for one source, raise that integration's limits.ratePerMin rather than splitting traffic across integrations.

When you exceed it

You get 429 with a JSON body. Every telemetry source we support retries on 429, and retrying is safe: each delivery carries an id, and re-sending one we already processed returns the original outcome instead of filing a second ticket. You do not need to deduplicate on your side.

{ "code": "RATE_LIMITED", "retryable": true }

One honest caveat about the ceiling

The limiter runs in-process on each server instance, so with N instances live the effective ceiling is up to N × your configured rate. It is sized for shedding a flood, not for metering you precisely — we would rather let a legitimate burst through than drop an incident. Do not treat the number as a billing boundary or build a client that paces itself right at the edge expecting exact enforcement.

Payload size

LimitDefaultRange
Request body256 KB1–512 KB

Bodies are read under this cap before any signature is checked, so an oversized payload costs you a 413 and costs us a bounded read. If your alerts legitimately exceed 256 KB, raise limits.payloadCapKb — but consider trimming the payload instead: everything that lands on the ticket is bounded separately (below), so the extra bytes usually buy nothing.

The 512 KB ceiling is not arbitrary. We forward your payload wrapped in an envelope that includes the original body again, and the receiving service caps a request at 1 MB — so a larger setting would accept your webhook and then fail to record it.

HTTP 413

Repeat alerts

A repeat firing of an alert you have already sent — same fingerprint, ticket still open — appends to that ticket rather than filing a new one. Repeats arriving within 30 seconds of each other are counted without a full write. Neither behaviour costs you anything beyond the delivery budget, and both are why a flapping alert does not become fifty tickets.

If you want one ticket per firing, set the integration's lifecycle to per_event.

What we keep, and for how long

DataRetained
Delivery records (what arrived, what it did)30 days
Raw payload of a refused delivery7 days
Refused payloads stored per integration20 per hour
Alert correlation state (what links a repeat firing to its ticket)30 days from the last firing

The correlation row is what makes a repeat alert append to its existing ticket instead of filing a new one. Its window slides: every firing re-stamps it, so a long-running incident keeps its ticket however long it lasts. It expires 30 days after the alert last fired — a fingerprint that goes quiet for longer starts a fresh ticket if it ever returns.

Refused deliveries are kept so you can see what your source actually sent when a signature or key is wrong. Past 20 in an hour we record that the refusal happened but stop storing bodies — a misconfigured sender in a retry loop should not fill storage with copies of the same bad request.

Both retention windows are set by your workspace admin and can be shortened. A change applies to future deliveries only; it does not delete what is already stored.

Telemetry that lands on a ticket is not covered by these windows. The alert summary, labels and allowlisted annotations copied onto an incident ticket live as long as the ticket does. If your alerts carry data you do not want retained indefinitely, restrict what crosses using the integration's mapping.annotationAllowlist.

Reading your delivery log

LimitValue
Page size50 default, 200 maximum

Paged newest-first. A nextCursor in the response means more rows exist; its absence means you have the complete list.

Notifying agents

When an incident is broadcast rather than assigned to a named on-call agent, we wake up to 50 live agents in the project. Beyond that the ticket still lands on the board and is still claimable — only the push notification is bounded.

Changing any of this

limits.ratePerMin and limits.payloadCapKb are per-integration and editable from the On-call screen or over the API:

update_integration {
  projectId, integrationId, version,
  patch: { limits: { ratePerMin: 300, payloadCapKb: 512 } }
}

Retention windows, the coalescing interval and the broadcast cap are workspace-wide and set by an admin. Everything else in this page is fixed.