Cloudflare Durable Objects is a powerful feature of the Cloudflare Workers platform that enables developers to build stateful, serverless applications with consistent, low-latency storage and coordination capabilities. Below, I’ll provide a detailed explanation of Durable Objects, their key concepts, features, use cases, and limitations, drawing from the provided reference and general knowledge about the platform.
What Are Durable Objects?
Durable Objects are a special type of Cloudflare Worker that combines serverless compute with persistent, strongly consistent storage. Unlike traditional Workers, which are stateless and handle requests in a distributed manner across Cloudflare’s global network, Durable Objects provide a way to maintain state and coordinate interactions between multiple clients or Workers. Each Durable Object is a globally unique instance of a JavaScript (or WebAssembly) class with its own private storage, making it ideal for building distributed, stateful applications without managing infrastructure.
Key characteristics of Durable Objects include:
- Globally Unique Instances: Each Durable Object has a unique identifier, ensuring all requests for a specific object are routed to the same instance, regardless of the requester’s location. This enables consistent state management and coordination.
- Persistent Storage: Each Durable Object has its own private, transactional, and strongly consistent storage (up to 10 GB per object with SQLite backend), which is co-located with the compute for low-latency access.
- Serverless: Like Workers, Durable Objects are automatically provisioned, scaled, and managed by Cloudflare, requiring no infrastructure management. They are instantiated close to the first request and can migrate to healthy servers as needed.
- Single-Threaded Execution: Each Durable Object processes requests sequentially, avoiding race conditions and simplifying concurrent programming.
- WebSocket Support: Durable Objects can act as WebSocket servers, enabling real-time, bidirectional communication for applications like chat or multiplayer games.
How Durable Objects Work
Durable Objects are designed to align with the logical units of an application’s state. For example, in a chat application, a Durable Object might represent a single chat room, or in an e-commerce platform, it might represent a shopping cart. This alignment simplifies state management and coordination compared to traditional databases or stateless serverless architectures.
Key Components
- Globally Unique Identifier:
- Each Durable Object is identified by a unique name or ID, which allows requests from anywhere in the world to be routed to the same instance. This ensures consistency for operations like updating state or coordinating clients.
- Example: A Durable Object for a chat room named “room123” will handle all requests for that room, regardless of where the clients are located.
- Storage API:
- Durable Objects provide two storage backends: key-value (KV) and SQLite. Cloudflare recommends using the SQLite backend for new projects due to its flexibility and features like Point-in-Time Recovery.
- Key-Value Storage: Suitable for simple key-value pairs but limited to 128 KiB per key.
- SQLite Storage: Supports complex data structures (e.g., tables) and up to 10 GB of storage per object. It also offers Point-in-Time Recovery for restoring data to any point in the last 30 days.
- Storage is strongly consistent, meaning reads and writes are immediately reflected, avoiding the eventual consistency issues common in distributed systems.
- Data written to storage persists across restarts or evictions, unlike in-memory state, which may be lost if the object is idle or evicted.
- Alarms API:
- Durable Objects support an Alarms API, allowing you to schedule future tasks (e.g., waking up the object to perform work like batch processing or queue management). Alarms are set using the Storage API and have guaranteed at-least-once execution with automatic retries using exponential backoff.
- Example: A Durable Object can use an alarm to periodically aggregate data or process a queue without requiring an external trigger.
- WebSocket Hibernation:
- For WebSocket-based applications, the WebSocket Hibernation API reduces costs by allowing Durable Objects to “hibernate” when idle, maintaining WebSocket connections without incurring continuous compute charges.
- This is particularly useful for applications like chat or gaming, where WebSocket connections may remain open for long periods with sporadic activity.
- Remote Procedure Call (RPC):
Lifecycle and Management
- Instantiation: Durable Objects are created on first access and remain active as long as they process requests. They hibernate after a few seconds of inactivity to save resources.
- Eviction: Inactive Durable Objects may be evicted from memory, losing in-memory state. Persistent data must be written to the Storage API to survive evictions or restarts.
- Migration: Durable Objects can migrate across Cloudflare’s network to optimize latency or handle server failures. Developers don’t need to manage this process.
- Deletion: A Durable Object ceases to exist if its storage is empty (e.g., no data written, no alarms set). To delete an object, you must explicitly call
storage.deleteAll()andstorage.deleteAlarm().
Use Cases
Durable Objects are well-suited for applications requiring stateful coordination or real-time collaboration. Common use cases include:
- Real-Time Applications:
- Chat Applications: A Durable Object can represent a chat room, managing WebSocket connections and storing message history.
- Multiplayer Games: Durable Objects can coordinate game state and player interactions in real time.
- Live Notifications: Durable Objects can broadcast updates to connected clients, such as in a live dashboard or notification system.
- Stateful Serverless Applications:
- Distributed Systems:
- AI Agents:
Getting Started with Durable Objects
To use Durable Objects, you need a Cloudflare account and the Workers CLI (Wrangler). Here’s a high-level overview of the setup process:
- Set Up a Cloudflare Account:
- Create a Project:
- Define a Durable Object:
- Create a JavaScript or TypeScript class that extends
DurableObject. Define methods likefetchfor HTTP requests orwebSocketMessagefor WebSocket handling. Example:import { DurableObject } from "cloudflare:workers"; export class MyDurableObject extends DurableObject { async fetch(request) { let count = (await this.ctx.storage.get("count")) || 0; count += 1; await this.ctx.storage.put("count", count); return new Response(`Count: ${count}`); } } - Configure the Durable Object in
wrangler.jsoncwith a binding name (e.g.,MY_DURABLE_OBJECT) and class name (e.g.,MyDurableObject).
- Create a JavaScript or TypeScript class that extends
- Access from a Worker:
- A Worker can communicate with a Durable Object using its binding. Example:
export default { async fetch(request, env) { let id = env.MY_DURABLE_OBJECT.idFromName("counter"); let stub = env.MY_DURABLE_OBJECT.get(id); return await stub.fetch(request); } };
- A Worker can communicate with a Durable Object using its binding. Example:
- Deploy:
- Testing and Debugging:
Durable Objects vs. Other Cloudflare Products
- Durable Objects vs. D1:
- D1: A managed SQLite database designed for traditional database use cases, with support for external HTTP API access and schema management. It’s not co-located with compute, which may introduce latency.
- Durable Objects: Co-locate compute and storage for low-latency access, ideal for stateful, real-time applications. SQLite in Durable Objects is private to each object, unlike D1’s shared database model.
- Use D1 for applications needing a centralized database; use Durable Objects for distributed, stateful logic.
- Durable Objects vs. Workers KV:
- Durable Objects vs. Queues:
Pricing and Limits
Durable Objects are available on both Workers Free and Paid plans, with specific constraints:
- Pricing:
- Compute: Billed based on the duration a Durable Object is active in memory. WebSocket Hibernation reduces costs for idle WebSocket connections.
- Storage: SQLite-backed Durable Objects currently incur no storage charges, but this will change with advance notice. Key-value storage incurs charges on the Paid plan.
- Example: A moderately trafficked application with 100 Durable Objects and 100 WebSocket connections per object (using hibernation) might cost ~$416.51/month, primarily due to compute duration.
- Limits:
- Storage: Up to 10 GB per Durable Object (SQLite backend). Free plan accounts are limited to 5 GB total across all objects.
- Compute: 30 seconds of CPU time per request invocation, resettable by new requests. Exceeding this increases eviction risk.
- Requests: Soft limit of 1,000 requests per second per object. Horizontal scaling is unlimited by creating more objects.
- SQLite Limits: Apply to SQLite-backed Durable Objects (e.g., 2 MB row limit in JSON mode, mitigated by fragmented mode).
- Free plan supports only SQLite-backed Durable Objects; Paid plan supports both SQLite and key-value backends.
To increase limits, submit a Limit Increase Request Form.
Advantages and Challenges
Advantages
- Stateful Serverless: Combines the simplicity of serverless with persistent state, reducing the need for external databases.
- Low Latency: Co-located compute and storage, plus automatic provisioning near users, minimize latency.
- Simplified Concurrency: Single-threaded execution eliminates race conditions, making it easier to build correct concurrent applications.
- Global Scalability: Cloudflare’s network supports millions of Durable Objects worldwide with automatic scaling and migration.
- WebSocket and Alarms: Enable real-time applications and scheduled tasks without external infrastructure.
Challenges
- Learning Curve: The concept of Durable Objects can be complex for developers unfamiliar with stateful serverless architectures.
- Single-Threaded Limitation: Each object processes requests sequentially, which may bottleneck high-throughput applications. Horizontal scaling (more objects) is required for high concurrency.
- In-Memory State: In-memory state is lost on eviction or restart, requiring careful use of the Storage API for persistence.
- Cost Considerations: Compute duration charges can accumulate for applications with long-running WebSocket connections, though hibernation helps mitigate this.
- Schema Evolution: Managing changes to Durable Object schemas over time requires migrations, which can be complex.
Example Applications and Demos
Cloudflare provides several demos showcasing Durable Objects:
- Chat Demo: A real-time chat application using Durable Objects for WebSocket coordination and message history storage.
- Multiplayer Doom: A WebAssembly port of Doom with multiplayer support using Durable Objects and WebSockets.
- Wildebeest: An ActivityPub and Mastodon-compatible server running on Durable Objects.
- Rate Limiter and Counter: Simple examples demonstrating state persistence and RPC.
Best Practices
- Persist Critical State: Always write critical state to the Storage API to survive evictions or restarts.
- Use SQLite Backend: Prefer SQLite for new projects due to its flexibility and features like Point-in-Time Recovery.
- Leverage WebSocket Hibernation: For WebSocket applications, use the Hibernation API to reduce costs.
- Optimize for Single-Threading: Design applications to minimize heavy computation within a single Durable Object, and scale horizontally by creating more objects.
- Test Locally: Use
wrangler devto simulate Durable Objects locally, but test deployed performance due to latency differences. - Monitor Costs: Track compute duration and request volume in the Cloudflare dashboard to manage billing.
Conclusion
Cloudflare Durable Objects offer a unique approach to building stateful, serverless applications with strong consistency, low latency, and global scalability. By combining compute and storage in a single-threaded, globally unique instance, they simplify the development of real-time, collaborative, and distributed systems. While they require careful design to manage limitations like single-threaded execution and in-memory state, their integration with Cloudflare’s global network and features like WebSocket Hibernation and Alarms make them a powerful tool for modern applications. For more details, explore the Cloudflare Durable Objects documentation and try the provided templates to get started.
Comments