How to use SQLite in Durable Objects with Base

The ORM pointed at the database embedded inside one object: same shape, local, isolated per entity.

Cloudflare
AhraJuly 22, 2026

How to use SQLite in Durable Objects with Base

A durable object already gives you a single stateful instance. Cloudflare lets that instance carry its own embedded SQLite database, a real relational store that lives inside the object, local to it, fast because there is no network hop to reach it. Base lets you talk to that embedded database with the same ORM you use everywhere else. So a durable object becomes not just a place to hold some in-memory state, but a place to hold a small relational database that belongs to exactly one entity.

This post assumes you have read the durable objects post and the ORM post. Here we put them together.

The ORM, pointed at the object's own SQLite

Base's ORM is built around a database abstraction: you get a database, you get repositories off it, and you work with entities. For a durable object, there is a durable variant of that database, the same ORM database you already know, extended for the durable object setting. The shape is the same. You declare your entities, you reach for repositories, you read and write rows. The difference is where the data lives: not a shared database somewhere on the network, but the SQLite that ships inside this one durable object.

Because it is the same ORM, your durable object's data access looks like the rest of your Base data access. There is no second data API to learn for the in-object database. The entities, the repositories, the query shape, all of it carries over.

Migrations come along

The durable variant of the database adds one thing the network database handles differently: a migrate step. Each durable object carries its own SQLite, so each one needs its schema brought up to date when it starts working with the database. The durable database exposes a migration call for exactly this, so the object's embedded schema can be created and evolved over time. You run the migration as part of the object coming to life, and the object's local database matches the entity definitions your code expects.

Why put a database inside an object

The appeal is locality and isolation. The data for one entity, one user, one room, one tenant, lives with that entity, on the same instance that owns it. Reads and writes do not leave the object, so they are fast. And because each object has its own database, one entity's data is naturally isolated from another's: there is no shared table where tenants could bleed into each other, because there is no shared table at all. For per-entity state that is genuinely relational, this is a clean fit that a single global database cannot match.

It is not for everything. If your data is shared across many entities and queried together, it belongs in a shared database, not scattered across thousands of durable objects. The in-object SQLite is for data that is naturally owned by one object and rarely needs to be seen across the whole set.

The mental model to keep

SQLite in a durable object is the Base ORM pointed at the database embedded inside one object: same entities, same repositories, same query shape as your network database, but the data lives locally on the object and is isolated to it. The durable database adds a migrate step so each object can bring its own schema up to date. Reach for it when relational state belongs to exactly one entity and you want it fast and isolated, not when it is shared and queried across the whole set.