Durable Objects in Dynamic Workers: Give each AI-generated app its own database (opens in new tab)
Dynamic Workers make it possible to run AI-generated code securely in lightweight isolates, but disposable execution is not enough for persistent applications. Cloudflare’s Durable Object Facets address this by letting a supervised Durable Object dynamically load an AI-generated Durable Object class with its own SQLite-backed storage. This combines sandboxed, persistent application state with centralized control over provisioning, access, logging, metrics, and billing. ## From Disposable Code to Persistent Apps - Dynamic Workers load code on demand in secure isolates rather than containers. - Isolates start quickly and use little memory, making them suitable for short-lived AI-generated tasks. - Persistent AI-built applications need: - Custom user interfaces - Long-lived state - Secure execution - A remote SQL database could provide storage, but it introduces network latency and additional infrastructure. ## Why Durable Objects Fit - Each Durable Object has: - A globally unique name - One active instance per name - An attached SQLite database stored locally - Local SQLite storage provides extremely low-latency access. - AI-generated applications can therefore use normal Durable Object storage APIs, including key-value and SQL storage. ## Limitations of the Traditional Model - Standard Durable Objects require: - A class extending `DurableObject` - Exporting the class from the Worker - Wrangler configuration to provision storage - A namespace binding for access - This model does not naturally support code loaded dynamically at runtime. - Giving an agent direct control of Durable Object namespaces could also allow uncontrolled object creation and storage use. - A platform needs an intermediary to enforce limits and provide observability, billing, and other operational controls. ## Durable Object Facets - Facets allow a normal, statically configured Durable Object to dynamically instantiate another Durable Object class. - The outer object acts as a supervisor: - Loads the agent’s code as a Dynamic Worker - Selects the exported Durable Object class - Forwards requests or RPC calls - Controls and monitors the application - The dynamically loaded class can directly extend `DurableObject`. - Each facet receives its own SQLite database, separate from the supervisor’s database. - Multiple facets can exist within one Durable Object, each identified by a name and subject to storage limits. ## Example Architecture - An `AppRunner` Durable Object receives incoming requests. - It obtains a facet named `"app"` through `this.ctx.facets.get(...)`. - When the facet starts, the runner: - Loads the Dynamic Worker - Retrieves its exported application class - Instantiates it as the facet - Requests are then forwarded to the dynamically loaded application. - The sample application maintains a request counter using Durable Object storage. Durable Object Facets provide a practical foundation for AI-generated applications that need persistent state without sacrificing isolation or platform governance. They are especially suited to personal or small “vibe-coded” apps, where each application can receive its own storage while the host platform retains control over resource usage and operational policies.