A 30-line Slack notifier was eating 60% of my CPU-time budget across 4 client Workers. The culprit: a runaway alarm loop I assumed was impossible.

Here's the part Cloudflare's docs don't spell out clearly: when your alarm() handler throws repeatedly, the platform retries with exponential backoff — but the backoff has a ceiling. In my testing it caps around 30-minute intervals after roughly 5 consecutive failures. After that, the alarm keeps firing on that ceiling interval indefinitely. It does not give up. It does not drop the alarm. A broken handler will keep your DO alive and burning CPU-ms until you intervene or delete the object entirely.

The fix that actually changed my production behavior was catching exceptions inside alarm() and rescheduling manually instead of letting the platform control retry timing:

async alarm(): Promise<void> {

try {