{"id":74,"date":"2025-12-15T00:00:00","date_gmt":"2025-12-15T00:00:00","guid":{"rendered":"https:\/\/wordpress.securinsight.ca\/index.php\/2025\/12\/15\/durable-objects-workers-new-best-practices-guide-for-durable-objects\/"},"modified":"2025-12-15T00:00:00","modified_gmt":"2025-12-15T00:00:00","slug":"durable-objects-workers-new-best-practices-guide-for-durable-objects","status":"publish","type":"post","link":"https:\/\/wordpress.securinsight.ca\/index.php\/2025\/12\/15\/durable-objects-workers-new-best-practices-guide-for-durable-objects\/","title":{"rendered":"Durable Objects, Workers &#8211; New Best Practices guide for Durable Objects"},"content":{"rendered":"<p>A new <a href=\"https:\/\/developers.cloudflare.com\/durable-objects\/best-practices\/rules-of-durable-objects\/\">Rules of Durable Objects<\/a> guide is now available, providing opinionated best practices for building effective Durable Objects applications. This guide covers design patterns, storage strategies, concurrency, and common anti-patterns to avoid.<\/p>\n<p>Key guidance includes:<\/p>\n<ul>\n<li><strong>Design around your &#8220;atom&#8221; of coordination<\/strong> \u2014 Create one Durable Object per logical unit (chat room, game session, user) instead of a global singleton that becomes a bottleneck.<\/li>\n<li><strong>Use SQLite storage with RPC methods<\/strong> \u2014 SQLite-backed Durable Objects with typed RPC methods provide the best developer experience and performance.<\/li>\n<li><strong>Understand input and output gates<\/strong> \u2014 Learn how Cloudflare&#8217;s runtime prevents data races by default, how write coalescing works, and when to use <code>blockConcurrencyWhile()<\/code>.<\/li>\n<li><strong>Leverage Hibernatable WebSockets<\/strong> \u2014 Reduce costs for real-time applications by allowing Durable Objects to sleep while maintaining WebSocket connections.<\/li>\n<\/ul>\n<p>The <a href=\"https:\/\/developers.cloudflare.com\/durable-objects\/examples\/testing-with-durable-objects\/\">testing documentation<\/a> has also been updated with modern patterns using <code>@cloudflare\/vitest-pool-workers<\/code>, including examples for testing SQLite storage, alarms, and direct instance access:<\/p>\n<ul>\n<li>\n<p>JavaScript<\/p>\n<div>\n<div>\n<figure>\n<pre data-language=\"js\"><code class=\"language-js\"><div><div><span>import <\/span><span>{<\/span><span><span> <\/span><span>env<\/span><\/span><span>,<\/span><span><span> <\/span><span>runDurableObjectAlarm<\/span><span> <\/span><\/span><span>}<\/span><span> from <\/span><span>\"cloudflare:test\"<\/span><span>;<\/span><\/div><\/div><div><div><span>import <\/span><span>{<\/span><span><span> <\/span><span>it<\/span><\/span><span>,<\/span><span><span> <\/span><span>expect<\/span><span> <\/span><\/span><span>}<\/span><span> from <\/span><span>\"vitest\"<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>it<\/span><span>(<\/span><span>\"can test Durable Objects with isolated storage\"<\/span><span>,<\/span><span> <\/span><span>async<\/span><span> <\/span><span>()<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>  <\/span><span>const<\/span><span> <\/span><span>stub<\/span><span> <\/span><span>=<\/span><span> <\/span><span>env<\/span><span>.<\/span><span>COUNTER<\/span><span>.<\/span><span>getByName<\/span><span>(<\/span><span>\"test\"<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>  <\/span><span>\/\/ Call RPC methods directly on the stub<\/span><\/div><\/div><div><div><span>  <\/span><span>await<\/span><span> <\/span><span>stub<\/span><span>.<\/span><span>increment<\/span><span>()<\/span><span>;<\/span><\/div><\/div><div><div><span>  <\/span><span>expect<\/span><span>(<\/span><span>await<\/span><span> <\/span><span>stub<\/span><span>.<\/span><span>getCount<\/span><span>())<\/span><span>.<\/span><span>toBe<\/span><span>(<\/span><span>1<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>  <\/span><span>\/\/ Trigger alarms immediately without waiting<\/span><\/div><\/div><div><div><span>  <\/span><span>await<\/span><span> <\/span><span>runDurableObjectAlarm<\/span><span>(<\/span><span>stub<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><\/code><\/pre>\n<div><\/div>\n<\/figure>\n<\/div><\/div>\n<\/li>\n<li>\n<p>TypeScript<\/p>\n<div>\n<div>\n<figure>\n<pre data-language=\"ts\"><code class=\"language-ts\"><div><div><span>import <\/span><span>{<\/span><span><span> <\/span><span>env<\/span><\/span><span>,<\/span><span><span> <\/span><span>runDurableObjectAlarm<\/span><span> <\/span><\/span><span>}<\/span><span> from <\/span><span>\"cloudflare:test\"<\/span><span>;<\/span><\/div><\/div><div><div><span>import <\/span><span>{<\/span><span><span> <\/span><span>it<\/span><\/span><span>,<\/span><span><span> <\/span><span>expect<\/span><span> <\/span><\/span><span>}<\/span><span> from <\/span><span>\"vitest\"<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>it<\/span><span>(<\/span><span>\"can test Durable Objects with isolated storage\"<\/span><span>,<\/span><span> <\/span><span>async<\/span><span> <\/span><span>()<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>  <\/span><span>const<\/span><span> <\/span><span>stub<\/span><span> <\/span><span>=<\/span><span> <\/span><span>env<\/span><span>.<\/span><span>COUNTER<\/span><span>.<\/span><span>getByName<\/span><span>(<\/span><span>\"test\"<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>  <\/span><span>\/\/ Call RPC methods directly on the stub<\/span><\/div><\/div><div><div><span>  <\/span><span>await<\/span><span> <\/span><span>stub<\/span><span>.<\/span><span>increment<\/span><span>()<\/span><span>;<\/span><\/div><\/div><div><div><span>  <\/span><span>expect<\/span><span>(<\/span><span>await<\/span><span> <\/span><span>stub<\/span><span>.<\/span><span>getCount<\/span><span>())<\/span><span>.<\/span><span>toBe<\/span><span>(<\/span><span>1<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>  <\/span><span>\/\/ Trigger alarms immediately without waiting<\/span><\/div><\/div><div><div><span>  <\/span><span>await<\/span><span> <\/span><span>runDurableObjectAlarm<\/span><span>(<\/span><span>stub<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><\/code><\/pre>\n<div><\/div>\n<\/figure>\n<\/div><\/div>\n<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>A new Rules of Durable Objects guide is now available, providing opinionated best practices for building effective Durable Objects applications. This guide covers design patterns, storage strategies, concurrency, and common anti-patterns to avoid. Key guidance includes: Design around your &#8220;atom&#8221; of coordination \u2014 Create one Durable Object per logical unit (chat room, game session, user) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-74","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts\/74","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts\/74\/revisions"}],"wp:attachment":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/media?parent=74"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/categories?post=74"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/tags?post=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}