Stripe events arrive out of order; Sume sends only terminal job events

Stripe does not order events and says to dedupe on event ID. Sume sends only terminal job events keyed by job_id, so order rarely matters. Fetch state.

4 min readSume
All posts

Stripe says events are not delivered in order and that you should dedupe on the event ID. Sume sidesteps most of that problem by sending only terminal job events (job.completed, job.failed, job.canceled), once per job. You still should not trust arrival order, but you can make every handler order-independent by reading the job instead.

The comparison below is built from Stripe's webhook page and Sume's webhook and jobs docs.

What each provider says

Event ordering, Stripe read 2026-10-05, Sume docs checked 2026-10-05
ItemStripeSume
OrderingEvents are not orderedNo ordering promise in the docs I read
Dedupe keyEvent IDjob_id
Event typesMany event typesThree terminal events; no progress or partial deliveries
RetriesLive mode up to 3 days with exponential backoff10 attempts, fixed 30 s
Pull alternativeNot covered hereGET /v1/jobs/{id}/status and /result; /events is a pull snapshot

Why terminal-only helps

Out-of-order trouble mostly comes from lifecycle events: a 'started' arriving after 'completed'. Sume's event set has no such pair. A job reaches exactly one terminal state, and the event reports it. If a job.completed and a job.failed ever both reached you for the same job_id, your store should keep the status you read from GET /v1/jobs/{id}/status, because that endpoint is the source of truth.

Order-independent handler

  • Treat the webhook as a notification, not as the state. On receipt, read the job from Sume and update your row from that.
  • Upsert by job_id. A second delivery of the same event should change nothing.
  • Never use arrival time as the business timestamp. Use fields you stored at submit time.
  • Use the events endpoint (job.created, job.queued, job.started, generation.submitted and the terminal events) when you need a timeline for debugging. Public events do not expose raw provider ids.

Late deliveries

A Sume retry arrives about 30 seconds after the failed attempt, and a redeliver can arrive at any time, so a late job.completed is normal. The signature timestamp is fresh each time, but the job_id is not, which is why dedupe belongs on job_id. See the Sume webhooks docs.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume