Migrate to RunxBuild today!! Deploy More while Spending Less

Calculate your savings
unxBuild
Back to Blog Explainer

Cloudflare Databases: D1, KV, Durable Objects and Hyperdrive Explained

Sean

Platform Writer

Sep 30, 2026
10 min read

Cloudflare databases are not one product but four: D1 (serverless SQLite), Workers KV (eventually consistent key-value), Durable Objects (strongly consistent state per object) and Hyperdrive (a connection accelerator for a Postgres or MySQL that lives elsewhere).

Cloudflare Databases: D1, KV, Durable Objects and Hyperdrive Explained

Picking the wrong one is expensive because the data models are genuinely different, not variations of one thing. The useful question is not which is best but what shape your data is, how many writers it has, and whether you would rather have relational depth or edge proximity. Below is how each behaves, what the trade-offs are, and the point where a real managed database is the honest answer.

Table of contents

The four products and what each one is for

Cloudflare’s own storage guide, Choosing a data or storage product, is worth reading in full. The short version: KV is an eventually consistent key-value store for read-heavy configuration; D1 is a relational serverless database for ordinary application data; Durable Objects give you strongly consistent, transactional state with global uniqueness for coordination; R2 stores blobs; Hyperdrive speeds up queries from Workers to an existing MySQL or Postgres.

The main mental shift is that these products are designed for code running in Workers. Each one is reached through a binding attached to your Worker rather than a connection string and a network socket. That is elegant inside the platform and awkward outside it: you cannot connect a desktop client, a Rails console or a cron job on another host to D1 the way you would to a normal SQL server.

The second shift is that data placement matters. A database in one region with a compute layer in three hundred locations is only fast if reads are cached or replicated. Cloudflare’s answer is a family of products with different consistency and latency profiles, and the design task is matching your data to them.

  • KV: config, feature flags, redirect tables, cached lookups. Reads fast, writes propagate slowly.
  • D1: users, posts, orders, small to mid-size relational data. SQL with SQLite semantics.
  • Durable Objects: chat rooms, collaborative documents, counters, per-tenant state with strong consistency.
  • Hyperdrive: reach a Postgres or MySQL you already run, without paying the connection cost per request.

D1: SQLite at the edge

D1 is SQLite operated as a service. You create a database, run migrations with the Wrangler CLI, and query it from a Worker using a prepared-statement API. Because it is SQLite, you get familiar SQL, foreign keys, indexes and transactions in a single-writer model, and the ergonomics are excellent for small applications.

npx wrangler d1 create app-db
npx wrangler d1 execute app-db --command "CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT UNIQUE NOT NULL)"
export default {
  async fetch(request, env) {
    const { results } = await env.DB
      .prepare("SELECT id, email FROM users WHERE email = ?")
      .bind("[email protected]")
      .all();
    return Response.json(results);
  },
};

What to check before committing: the per-database size ceiling (Cloudflare documents a maximum per database, and the number is measured in single-digit gigabytes on paid plans), the daily row-read and row-write allowances on the free tier, and the write path. SQLite is single-writer, so write throughput for one database has a ceiling. The pattern Cloudflare suggests for scale is many small databases, one per tenant or per user, rather than one large shared database.

D1 also lacks features you might expect from Postgres or MySQL: no extensions, no stored procedures in the usual sense, limited concurrency control, and restrictions on long-running transactions. If your schema depends on those, the mismatch shows up at migration time.

KV and Durable Objects: two different consistency deals

Workers KV is a distributed cache that happens to be durable. Writes go to a central store and propagate to edge locations over seconds to a minute or so, and reads are served from the nearest cache. That is perfect for configuration and lookups that change rarely and are read constantly, and it is a bad match for anything where two users must see the same current value, such as an inventory count or a session revoke.

Durable Objects are the opposite deal. Each object has a globally unique identity, a single instance handles all requests for that identity, and it has transactional storage. Because there is exactly one writer per object, you get strong consistency without distributed locking. It is the right primitive for rooms, sessions, rate limiters, and per-document collaboration, and it is where Cloudflare’s SQLite-backed storage for objects lives.

The trade-off is that you design your data as many small independent objects. Cross-object queries, such as report on every order across all customers, are not what they are for. If you catch yourself building a homemade query engine on top of Durable Objects, you wanted a relational database.

A common composition is Durable Objects for the hot, strongly consistent state and D1 or an external database for the durable record that reporting and joins use. That splits responsibility instead of stretching one product over a job it was not designed for.

Hyperdrive: keeping a real Postgres or MySQL

Hyperdrive exists because Workers are a poor fit for opening a fresh database connection on every request. Connecting to Postgres involves a TLS handshake, authentication and setup round trips, and doing that from many short-lived isolates against a database far away is slow and eats connection limits. Hyperdrive maintains regional connection pools close to your database and can cache eligible read queries.

The setup is a configuration binding: you give Hyperdrive the connection string to your existing Postgres or MySQL, bind it to the Worker, and connect with your normal driver using the connection string Hyperdrive supplies.

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://app_user:[email protected]:5432/appdb"
import postgres from "postgres";

export default {
  async fetch(request, env) {
    const sql = postgres(env.HYPERDRIVE.connectionString);
    const rows = await sql`SELECT id, title FROM posts ORDER BY id DESC LIMIT 10`;
    return Response.json(rows);
  },
};

Hyperdrive does not make the database itself closer, it makes the round trips cheaper. Each uncached query still has to reach the region where the database lives, so choose that region deliberately. We cover the pairing in more depth in Cloudflare and Postgres.

It also requires the database to be reachable from Cloudflare’s network, so you will need to think about allowed hosts, TLS and credentials. A database that only accepts connections from a private network needs a tunnel or a public endpoint with strict authentication, which is a design decision in its own right.

When edge SQLite fits, and when you want a real managed database

D1 fits when the app is small to medium, mostly reads, has one writer path, and lives entirely inside Workers. Think blog backends, link shorteners, form handlers, small SaaS tools, per-tenant tables. The operational win is real: no server, no patching, nothing to size.

A managed Postgres or MySQL fits when any of the following is true. You have an existing application in Rails, Django, Laravel, Spring or .NET that speaks Postgres or MySQL natively. You need extensions, mature tooling, point-in-time backups, or read replicas. You want to connect BI tools, migration frameworks and admin clients directly. Several services, not just one Worker, need to read and write the same data. Or you simply value a database that behaves the same on your laptop as in production.

Vendor lock-in is the quiet factor. D1 queries are SQL, so they port, but the binding API, Wrangler migrations and Durable Objects semantics do not. A Postgres database moves between hosts with a dump and a restore. That portability has a value you only appreciate on the day you need to move.

  • Small, Worker-only app with simple relational data: D1.
  • Read-mostly config or lookup tables: KV.
  • Strongly consistent per-entity state: Durable Objects.
  • Existing app or complex relational needs: managed Postgres or MySQL, optionally through Hyperdrive.
  • Reporting, joins, and admin tooling across everything: managed Postgres or MySQL.

Putting a managed database next to your app

If you land on Postgres or MySQL, the practical goals are boring ones: backups you can restore, connection limits you control, and a private network path between the app and the database so the database never needs a public endpoint. That is the setup that keeps latency low and the attack surface small.

On RunxBuild, Postgres and MySQL are the managed database options, with connection limits, backups, user management and private networking, and they sit alongside the web service that uses them. The database docs walk through creating one and connecting from a service; the connection limit page explains why pooling matters, which is the same problem Hyperdrive solves from the Cloudflare side.

A hybrid is entirely reasonable. Keep the Worker on Cloudflare for edge logic and static assets, keep the durable data in a managed database next to your backend, and connect with a driver that supports the platform. What matters is not purity but that every piece of data has one clear home and one clear way to back it up.

How this fits the rest of the stack

Cloudflare’s storage products are excellent inside their lane: small, edge-shaped, Worker-native workloads. Once your data needs joins, extensions, several services or a plain connection string, a managed Postgres or MySQL stops being an upgrade and becomes the baseline. To see what a managed database plus the service that uses it costs, run the numbers in the RunxBuild hosting calculator. When you are ready to try it, create a database from the RunxBuild dashboard and connect a service over the private network. Reference: Database user management on RunxBuild. A practical first step is small: keep the Worker and its edge logic where they are, stand up the database beside the backend, and measure query latency from the region your users are in before you decide whether Hyperdrive or a nearer database region is worth the extra moving part.

Useful related references:

FAQ

What database does Cloudflare offer?

Cloudflare offers D1, a serverless SQLite database; Workers KV, an eventually consistent key-value store; Durable Objects with transactional storage; and Hyperdrive, which accelerates connections to an external Postgres or MySQL. R2 is object storage for files rather than a database. Each is accessed mainly from Workers via bindings.

Is Cloudflare D1 good enough for production?

For small to medium applications that live inside Workers, yes. Check the per-database size limit, the write throughput of a single SQLite writer and the free-tier row allowances. If you need extensions, heavy concurrent writes or external tools connecting directly, a managed Postgres or MySQL is the safer production choice.

What is Hyperdrive used for?

Hyperdrive lets Workers query an existing Postgres or MySQL database efficiently. It maintains connection pools near the database and can cache eligible read queries, which removes the per-request connection setup cost. It does not move the database closer to users; uncached queries still travel to the database region.

When should I use KV instead of D1?

Use KV for read-heavy, rarely changed data such as configuration, feature flags or redirect maps, where a delay of up to about a minute for writes to propagate is fine. Use D1 when you need queries, joins, constraints or immediate consistency for reads that follow writes.

Can I use Postgres with Cloudflare Workers?

Yes. Workers can talk to an external Postgres through Hyperdrive using a standard driver. The database must be reachable from Cloudflare, and you should place it in a region near where most queries originate. Many teams pair Workers at the edge with a managed Postgres next to their backend.

#cloudflare databases#Cloudflare D1#Workers KV#Durable Objects#Hyperdrive