cloudflare

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.