billflare.

How to keep a Durable Objects dead loop from bankrupting you

karamage explains Durable Objects billing as an hourly hotel, recounts how his own alarm loop pushed the projected usage charge of a personal service from a few yen to nearly ¥8,000 (his figure), and lists four coding rules and two monitoring habits to catch a runaway loop early.

Products
Durable ObjectsAgents SDK
Source
Author experienceZenn
Author
karamage

Key points

  • He compares Durable Objects to an hourly hotel: while an object is checked in, the meter runs even if it does nothing, and each request is a separate per-call charge. Whether the object can hibernate decides most of the cost: an eligible idle object hibernates after about 10 seconds, a non-hibernatable one is evicted after 70 to 140 seconds, but pending I/O, setTimeout or setInterval each keep it in memory for up to 15 minutes from when they start.
  • His incident: a notification queue’s alarm() caught failures and immediately called setAlarm(Date.now()). When the notification target started returning 400 errors one Friday, the queue never cleared and the alarm rescheduled itself instantly, all weekend, across per-user objects. Each alarm run is billed as a request, each setAlarm() counts as a storage write, and the duration meter never stopped.
  • He also retells an onStart() trap reported on Hacker News: onStart() runs on every wake, and calling setAlarm() there without checking means the object never gets to sleep; with more than 60 preview deployments each holding its own objects, the poster saw about 930 billion row reads a day at peak. The fixes: check getAlarm() before setAlarm(), pass { idempotent: true } to the Agents SDK schedule() for delayed or date-based tasks, and remove Durable Object bindings from preview environments.
  • His four coding rules: give every alarm a stop condition and a minimum interval, backing off exponentially on failure and giving up after a set number of retries; pass call depth between objects and cut off past a limit, since A calling B calling A loops silently; use alarms instead of setInterval, and ctx.acceptWebSocket() (the Hibernation API) instead of accept(); and build an emergency switch first, an environment flag checked at the top of alarm() that calls deleteAlarm() and returns, so a redeploy stops every object.
  • For operations he sets a budget alert (he suggests $5 or $10 for a personal project that normally costs a few yen), noting that Durable Objects have no hard cap that stops usage and that the Hacker News poster’s Workers usage notifications only watched CPU time. He opens the Durable Objects dashboard graphs (requests, duration, rows read and written) the day after each deploy and before weekends; a loop shows as requests and writes spiking together with duration staying high.
  • Official docs (rechecked 2026-10-16): the lifecycle page confirms hibernation after 10 seconds, eviction after 70 to 140 seconds and the 15-minute window per pending operation; Durable Objects pricing bills each setAlarm() as one row written; Agents SDK schedule() idempotency defaults to true for cron schedules and false for delayed and date-based ones; budget alerts are informational only and do not pause or cap usage.

Original sources

  1. Last updated

    How to keep a Durable Objects dead loop from bankrupting you

    Open original source

    karamage explains Durable Objects billing as an hourly hotel, recounts how his own alarm loop pushed the projected usage charge of a personal service from a few yen to nearly ¥8,000 (his figure), and lists four coding rules and two monitoring habits to catch a runaway loop early.

Author experienceWorkers +5

Four layers of cost protection for small Cloudflare projects

David Z (@davezfr) writes an X article for vibe coders on budget alerts, stop conditions for paid paths, automatic pausing, and letting a personal agent verify and pause.

Workers

RetainDB: a reported $36k bill from a queue loop with 81 users.

Reddit user alameenswe, building RetainDB on Workers, KV, Durable Objects and Queues, reports a Cloudflare bill of about $36k for one month with 81 users; the post body says $35,000. He attributes it to a queue consumer that re-queued async writes, 12 unbatched Durable Object writes per memory write and a kv.list() authentication fallback.

Other

mike269: a $35 monthly charge months after cancelling.

Community user mike269 says the account was cancelled months ago but a $35 monthly charge continues and support has not explained how to cancel it.