Why Webhook Events Arrive Out of Order
A webhook sends a notice from one service to another when something changes, such as a customer record or an order. Events…
When a service sends event notifications to your endpoint or your client fetches events from a provider, a failed delivery or fetch can leave your records incomplete. A webhook is an HTTP request that a provider sends to report an event. Polling means your client periodically asks the provider for events or current data.
After an event's first delivery fails, check whether you can retrieve it; provider retries help only while delivery attempts continue. Your client can recover missed events by polling if the provider keeps searchable event history. A replay or redelivery endpoint can resend a known delivery, subject to the provider's availability and permission limits.
When a provider sends a webhook, your endpoint responds with an HTTP status code. Providers commonly treat a timely 2xx response as confirmation that they delivered the notification. If your endpoint is unavailable, times out, or returns an unsuccessful status, the provider may retry. Its delivery policy determines how long those attempts continue.
Square documents automatic retries for up to 24 hours after an event. GitHub, by contrast, says it does not automatically redeliver failed deliveries. These are provider-specific policies, so check the documented retry behavior instead of assuming that every webhook will be retried. See Square’s retry policy and GitHub’s handling for failed deliveries.
An acknowledgment also has limits. If your endpoint returns success but then fails while handling the event, the provider has already received confirmation. Your endpoint should therefore confirm receipt only after it has safely accepted the event for handling. A successful HTTP response does not establish that all later work finished.
Your client can recover missed events by polling when the provider offers an event-history endpoint, which lets the client search or list past events. A current-state endpoint shows the latest data for an object, but it may not reveal every change that occurred while your client was offline.
Square’s Events API supports recovery and reconciliation by returning searchable events from the preceding 28 days. It provides time filters and pagination, but the recovery path has prerequisites: events must be enabled for search, and the application must have had access when each event occurred. Stripe’s Events list supports retrieving events from up to 30 days ago with cursor-based pagination. Stripe also returns event data using the API version recorded when the event was created. See the Square Events API and Stripe’s event list.
When polling event history, save a checkpoint, such as a cursor or time watermark, so the client knows where to resume. Request every page of results, and make repeated processing safe. A query that overlaps an earlier range can return records your client has already handled. A current-state query can help reconcile an object’s latest values, but it cannot substitute for event history when each intermediate change matters.
A replay or redelivery endpoint asks a provider to send a particular earlier delivery again; this helps when you know which delivery failed and the provider still makes that delivery available. GitHub permits manual redelivery for deliveries from the past three days, subject to the required permissions. Its documentation notes that a redelivery keeps the original delivery identifier. GitHub’s redelivery instructions describe how to request one.
Replay and polling solve different problems. Redelivery retries a known event. Polling an event-history endpoint searches for events, including ones your client may not know it missed. A provider can offer either mechanism, both, or neither.
Check three separate limits: how long the provider retries, how long it allows redelivery, and how long it keeps event history. Square’s automatic webhook retries stop after 24 hours, while its Events API offers a 28-day history under its access and search conditions. A diagnostic log can help explain a failed delivery, but a log does not itself provide the same recovery capability as an endpoint that returns past events. Square describes its webhook event logs separately from its Events API.
Webhook retries help with failures covered by the provider’s delivery policy. Before relying on them, check how long the provider retries and how you will identify deliveries that still fail. If the provider stops retrying or does not retry automatically, determine whether an operator or script can request redelivery before the provider’s availability window closes.
Polling gives you another way to recover events if the provider keeps the event history long enough for you to find missed records. Check how long the endpoint keeps events. Then check which filters and permissions it supports and how it divides results into pages. Also find out whether you must meet any conditions for the provider to record events. If it returns only current state, use it to reconcile present values, not to assume that it can reconstruct every missed transition.
Both approaches can produce duplicates. Webhook retries and redeliveries can repeat a delivery; polling can return records again when a client revisits a range or resumes from an earlier cursor. Preserve stable event identifiers and use them to prevent repeated handling from applying the same event twice. Square documents an event_id for identifying repeated notifications; its webhook documentation also warns that notifications are not guaranteed to arrive in event order. Use event identifiers and the provider’s documented ordering guarantees when designing recovery. Do not assume each event arrives exactly once or in order.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com