Telemetry
Webhooks SQL recipe

Measure Webhook End-to-End Completion

Follow each webhook from receipt through downstream completion and measure the share that finishes within an operating target.

Advancedwebhook_lifecycle_eventsReviewed 2026-07-28Tested with Apache DataFusion 45.2.0

Question answered

Which webhook types finish their downstream work within five minutes?

A fast 200 response does not prove that the business action completed. Joining receipt and downstream outcome by delivery ID exposes accepted webhooks that later stalled or failed.

Event contract

Fields the query expects

FieldTypeWhy it exists
timestamp_utcTimestampWebhook lifecycle event time.
delivery_idUtf8Stable provider delivery identifier.
providerUtf8Webhook provider.
event_typeUtf8Provider event type.
event_nameUtf8webhook_received or downstream_completed.
statusUtf8success or failed for terminal outcomes.
DataFusion SQL

Copy the query

sql
WITH deliveries AS (
  SELECT
    delivery_id,
    provider,
    event_type,
    MIN(CASE
      WHEN event_name = 'webhook_received' THEN timestamp_utc
      ELSE NULL
    END) AS received_at,
    MIN(CASE
      WHEN event_name = 'downstream_completed' AND status = 'success'
      THEN timestamp_utc ELSE NULL
    END) AS completed_at
  FROM webhook_lifecycle_events
  WHERE timestamp_utc >= now() - INTERVAL '7 days'
  GROUP BY delivery_id, provider, event_type
),
delivery_outcomes AS (
  SELECT
    delivery_id,
    provider,
    event_type,
    received_at,
    completed_at,
    date_part('second', completed_at - received_at) AS completion_seconds
  FROM deliveries
  WHERE received_at IS NOT NULL
)
SELECT
  provider,
  event_type,
  COUNT(*) AS received_deliveries,
  SUM(CASE WHEN completed_at IS NOT NULL THEN 1 ELSE 0 END)
    AS completed_deliveries,
  100.0 * SUM(CASE
    WHEN completion_seconds <= 300.0 THEN 1 ELSE 0
  END) / NULLIF(COUNT(*), 0) AS completed_within_target_pct,
  approx_percentile_cont(completion_seconds, 0.95) AS p95_completion_seconds
FROM delivery_outcomes
GROUP BY provider, event_type
HAVING COUNT(*) >= 20
ORDER BY completed_within_target_pct, received_deliveries DESC;

This read-only query is planned and executed against an empty typed table with Apache DataFusion 45.2.0. The deterministic sample output is synthetic and reviewed separately; validate field types, thresholds, and business definitions against your own data. Read the testing methodology.

Query result

Webhook deliveries completed within target

GitHub push processing is acknowledged at receipt but frequently misses the five-minute downstream completion target.

providerevent_typereceived_deliveriescompleted_deliveriescompleted_within_target_pctp95_completion_seconds
stripeinvoice.payment_succeeded8,4208,34696.21242
githubpush3,1802,89083.55811

Synthetic example output. Run the query against your own event schema and thresholds before using it for operational decisions.

How the SQL works

  1. 1The delivery CTE collapses lifecycle events to one receipt and one successful downstream completion.
  2. 2Completion latency measures the business workflow rather than only HTTP handler time.
  3. 3The final aggregation reports both completion share and p95 time so missing outcomes remain visible.

Edge cases to decide

  • Deduplicated provider retries should retain the same delivery ID and not create new logical work.
  • Some event types intentionally fan out into several outcomes and need an explicit terminal definition.
  • Exclude very recent receipts that have not had the full completion window when calculating a final service level.

Recommended dashboard

  • Bars: completed_within_target_pct by event_type
  • Trend: p95_completion_seconds
  • Table: oldest received deliveries without completion

Alert guidance

Alert when mature deliveries miss the completion target at meaningful volume, even if webhook response codes remain healthy.

Read alert setup

Put the recipe to work

Related instrumentation and guides

Continue the analysis

Run it on real events

Create a table, adapt the fields, and save the result

Start free, send structured events, and use the query result as a chart, shared dashboard widget, or alert input.

Get an API key