---
title: "Build an idempotent scheduled job with Cloudflare Queues and D1"
url: https://daily.dev/posts/build-an-idempotent-scheduled-job-with-cloudflare-queues-and-d1-2wtuziptf
source_url: https://flaviocopes.com/idempotent-scheduled-job-cloudflare-queues-d1
type: article
source: "Flavio Copes"
published: 2026-08-25T13:24:39.158Z
updated: 2026-08-25T13:25:05.366Z
tags: ["distributed-systems"]
reading_time: 11
upvotes: 0
comments: 0
language: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Build an idempotent scheduled job with Cloudflare Queues and D1

**[Flavio Copes](https://daily.dev/sources/flaviocopes)** · 11 min read · 0 upvotes · 0 comments

## Summary

A step-by-step tutorial builds a reliable Cloudflare scheduled job that checks pricing pages using cron triggers, Cloudflare Queues, and D1. The core problem is that cron triggers and queues only guarantee at-least-once execution, so the job must be idempotent. The approach uses a deterministic 'work ID' derived from the target and its due slot, D1 tables with unique constraints to prevent duplicate work, an expiring lease with a random token to allow safe recovery from crashed Workers, a D1 batch transaction to save results and advance the schedule atomically before acknowledging the queue message, and cadence-preserving logic that calculates the next run from the original due slot rather than the current time. It also covers distinguishing retryable from permanent failures and using exponential backoff with a dead letter queue.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://flaviocopes.com/idempotent-scheduled-job-cloudflare-queues-d1>

## Questions this post answers

### How do I prevent duplicate processing when Cloudflare Queues delivers the same message twice?

Give each scheduled check a deterministic work ID derived from the target ID and its due slot timestamp, not from when the consumer starts. Store completed checks in a D1 table with the work ID as primary key plus a unique index on target and scheduled time, so duplicate deliveries recognize existing work and skip it safely.

_daily.dev surfaces patterns like this for engineers designing at-least-once queue consumers._

### How can I stop two Cloudflare Queue consumers from processing the same scheduled job at the same time?

Use a conditional UPDATE in D1 that sets a random lease token and an expiration time only when no active lease exists, so only one consumer can claim a given due slot. The lease must expire (for example after 5 minutes) so a crashed Worker doesn't leave the target locked forever, and the token in the WHERE clause prevents a slow old consumer from clearing a newer lease.

_track locking patterns like this on daily.dev when building reliable background jobs._

### How do I keep a recurring job on schedule after a delayed run instead of drifting later each time?

Calculate the next run from the original due slot instead of from the current time, using elapsed time divided by the interval to skip missed slots while preserving cadence. For example, a daily 08:00 job that actually runs on August 6 at 10:00 after being due August 4 should be rescheduled for August 7 at 08:00, not three hours later than the original time.

_daily.dev helps developers keep track of scheduling patterns like fixed-cadence recovery._

## Similar posts on daily.dev

- [Cloudflare Cron Triggers: run a Worker on a schedule](https://daily.dev/posts/cloudflare-cron-triggers-run-a-worker-on-a-schedule-allyxbppi) · Flavio Copes · 0 upvotes · 0 comments
- [How I auto-publish scheduled posts with a Cloudflare Worker cron](https://daily.dev/posts/how-i-auto-publish-scheduled-posts-with-a-cloudflare-worker-cron-0tvkhx5nx) · Flavio Copes · 2 upvotes · 0 comments
- [How to rebuild a Cloudflare site on a schedule](https://daily.dev/posts/how-to-rebuild-a-cloudflare-site-on-a-schedule-ihah9qwcf) · Flavio Copes · 0 upvotes · 1 comments

---

Tags: [#distributed-systems](https://daily.dev/tags/distributed-systems)

[View this post on daily.dev](https://daily.dev/posts/build-an-idempotent-scheduled-job-with-cloudflare-queues-and-d1-2wtuziptf)
