D1 free-tier limit now fails queries: dedupe Sume webhooks safely
Cloudflare D1 queries on Workers Free now fail past the daily row limits. Dedupe Sume webhooks on request_id, return a 5xx, and use redeliver after the reset.

Insert the request_id into D1 as your dedupe key, and if the insert throws because the account is over its limit, return a 5xx so Sume retries. Cloudflare's September 1 entry says D1 queries on the Workers Free plan fail once an account exceeds the daily row read or row write limits.
Sume facts are from the Run webhooks docs; the Cloudflare entry was read 2026-09-30.
What happens at the limit?
Cloudflare says the queries fail, and the limit persists until midnight UTC. A webhook handler that ignores that error and answers 204 will lose the event; one that returns a 5xx lets Sume try again.
| Delivery | Attempts | Spacing |
|---|---|---|
| Job webhook | Up to 10 | Fixed 30 seconds |
| Run webhook | Up to 10 | Exponential backoff, capped at 1 hour |
| D1 limit reset | Midnight UTC | Per Cloudflare |
What does the handler look like?
Verify the signature first (not shown), then write. A failed write becomes a 503 so the delivery counts as failed.
export async function record(db: D1Database, event: { request_id: string }) {
try {
await db
.prepare("INSERT OR IGNORE INTO seen (id) VALUES (?)")
.bind(event.request_id)
.run();
return new Response(null, { status: 204 });
} catch {
return new Response("storage unavailable", { status: 503 });
}
}Will retries outlast the reset?
Not necessarily. Ten job attempts at 30 seconds cover only a few minutes. After the limit clears, use redeliver: POST /v1/jobs/{job_id}/webhook/redeliver for a job or POST /v1/format-runs/{run_id}/webhook/redeliver for a run, which does not consume an automatic attempt.
Which id do I dedupe on?
request_id for run events, where it equals run_id and is stable across retries, and job_id for job events.
Sources
Related posts
More in Developers
- Start a Cloudflare Workflow from a Sume webhook with ctx.exports
Verify the Sume webhook signature in a Worker, then start a Workflow with ctx.exports and no workflows binding. Includes a short Worker handler.
- Workflows keeps state 7 days now: store your Sume job ids
Cloudflare Workflows on Workers Paid now keeps finished instance state 7 days by default. Save the Sume job id and result URL in your own store.
- Workflows instance limits vs Sume queue headroom: which binds?
Cloudflare lists 50,000 concurrent Workflow instances (Paid, April entry). Sume reports your own generation headroom; size fan-out by that formula.
- Workflows .subscribe() vs Sume job events: push or pull?
Cloudflare Workflows can stream instance events with subscribe(). Sume has no SSE stream for jobs: use a signed webhook, or poll status and the events snapshot.
Written by Sume