Cloudflare D1

Relational application data without operating the database server.

D1 is the SQL database PrimeLabs uses when an application’s records belong in tables: users, organisations, requests, and the events that explain them. The Worker queries it. Nobody patches a database host for that product.

SQLite’s SQL semantics are the dialect. The product is still a managed database with migrations, an HTTP API, and a recovery path. The choice of whether it belongs at all is on Cloudflare application development. The code that calls it is a Worker.

What D1 is for

D1 is Cloudflare’s managed serverless SQL database. A Worker reaches it through a binding. Other tools can reach it through the HTTP API. Queries use SQLite’s SQL, including foreign keys when the schema declares them, and prepared statements with bound parameters.

That fits accounts, memberships, configuration, workflow state, tenant records, audit events, document metadata and the rows a report is calculated from. A internal application often has one database. A SaaS product uses the organisation id on every row that must not leak. A dashboard reads those rows. It does not invent a second set of figures.

The query is only as wide as the organisation

Member Portal is an example schema. Switch between the tables, the statement, the rows it returns, and the index migration those rows assume. No database is connected.

Example interface. Not a client project.

Member portal · example database · September 2026

Signed in as Priya Shah. Her membership is Organisation A, Northstar Services. The bound organisation id is org_northstar.

Tables in this example

  • organisationsid, name
  • usersid, email, name
  • membershipsuser_id, organisation_id, role
  • requestsid, organisation_id, status, updated_at
  • documentsid, organisation_id, object_key
  • workflow_eventsid, request_id, kind, at

A request belongs to one organisation. A document row stores the object key, not the file.

Example only. No database was queried.

Schema is a reviewed change

Tables, keys and foreign keys are the model. A migration file is how that model changes: applied on purpose, in order, and recoverable if it was wrong. Typing a new column into production is not the process.

Relational modelling is the point of choosing D1. A membership is a row that joins a user to an organisation. A request carries the organisation id so a query can be bound to it. A document row stores the object key and the owner. The file lives in object storage. An audit event records what changed, who did it, and when, so a later reader does not have to infer it from a log line.

Writes, batches, and what a replica is allowed to show

Without read replication, queries go to one primary database. Latency follows the distance to that primary. Read replication adds read-only copies in other regions. Writes still go to the primary. A replica can lag, so a read that does not carry context can miss a write the same person just made.

The Sessions API is how a Worker keeps sequential consistency across the queries of one session: a later read in that session does not see an older version than an earlier one, and a writer can read their own write. A bookmark can carry that point forward to the next request. Sessions are a Worker binding feature. They are not a promise that every possible read, from every client, sees the latest commit if the application ignores them.

Several statements can be sent as one batch. They run in order, as a single unit, which is the right shape when a membership change and its audit row must succeed together. The application reads the batch result before it tells the user the change is done.

Recovery is point in time, and a restore overwrites

Time Travel is D1’s backup and point-in-time recovery for databases on the production storage backend. It is on without a separate backup job. A database can be restored to a minute inside the retention window: 30 days on the Workers Paid plan, 7 days on the Free plan. Restoring overwrites that database. Queries in flight are cancelled. The previous bookmark is how the restore itself can be undone.

That window is not an archive policy. A copy that must be kept longer is an export, for example into object storage, decided as its own job. Time Travel does not fork a database into a new one.

A slow query is a throughput problem

Each D1 database is single-threaded. It runs one query at a time. A short indexed read leaves room for the next one. A scan does not. Indexes belong on the columns the application actually filters and sorts, usually the tenant and the time. A statement that would update a huge set of rows is split into batches so it stays inside the query duration limit.

Bound parameters keep the tenant predicate out of string concatenation. The missing organisation filter is a data leak, not a performance tuning item. Query insights exist so a statement that is doing too much can be seen. They do not design the index.

The database has a size, and that is the design

On the Workers Paid plan a single D1 database holds up to 10 GB, and that ceiling is not raised. The Free plan is 500 MB. D1 is meant to scale out across databases — per tenant or per entity — rather than grow one database without a limit. Rows in a table are not capped separately from that storage. A row, string or blob is capped at 2 MB, which is another reason a PDF is not a column.

There is no honest reading of this as infinite SQL. A workload of large analytical scans, or a single hot row that many users must update at the same instant, wants a different store. Ordinary relational records for an application are what the limits describe.

When D1 is the system of record

Use it

  • The application has users, organisations and rows that join.
  • Queries are selective, indexed, and bounded by a tenant.
  • Schema changes need a migration and a way back.
  • The Worker is already the application runtime.
  • A report should be calculated from these rows, not from a second copy.

Look elsewhere

  • The data is a file, an export, or a media object.
  • One key must be coordinated by many writers at once.
  • The workload is a large analytical scan, not an application query.
  • A single database would pass 10 GB and cannot be split.
  • An existing database already owns the records, and copying them would create two sources of truth.

Start from the row the screen has to show

A useful note names that row, who may see it, and which other table it joins. There is no database behind this page.

Discuss an application

Straight answers

Is D1 just SQLite in the cloud?

The SQL is SQLite’s. The product adds a binding, an HTTP API, migrations, query visibility and Time Travel. Treating it as a file you host yourself misses the limits and the recovery model.

Will one database grow with the product?

Up to its storage ceiling, which is 10 GB on the paid plan and is not increased. Past that, the design is more databases, or a different store. It is not a larger version of the same database.

Do read replicas remove consistency questions?

No. Replicas can lag. Sessions are how a Worker asks for sequential consistency. Writes still land on the primary.