Skip to content

Database

Source: src/Cloudflare/D1/Database.ts

A Cloudflare D1 serverless SQL database built on SQLite.

D1 is a serverless relational database that runs at the edge. Create a database as a resource, then bind it to a Worker to run SQL queries.

Basic database

const db = yield* Cloudflare.D1.Database("my-db");

Database with location hint

The primary copy of the data is stored in the chosen region; reads can be served closer to users when read replication is enabled.

const db = yield* Cloudflare.D1.Database("my-db", {
primaryLocationHint: "wnam",
});

Database with read replication

Read replication is the only mutable property after creation — toggling it triggers an update rather than a replacement.

const db = yield* Cloudflare.D1.Database("my-db", {
readReplication: { mode: "auto" },
});

Database in a specific jurisdiction

const db = yield* Cloudflare.D1.Database("my-db", {
jurisdiction: "eu",
});

Point migrations at a folder of migration files. Already-applied migrations are skipped on subsequent deploys; new files are detected automatically and applied as part of the next update.

Bookkeeping always lives in Alchemy’s __alchemy_migrations table — one format, owned by Alchemy. A database previously migrated with drizzle-kit, Prisma, or wrangler is adopted by a one-way conversion on first deploy: the old tool’s applied history is copied into Alchemy’s table and the old table is left frozen (never written, never dropped). No baselining required. Legacy Alchemy tracking tables are detected by column shape and upgraded in place.

Apply migrations from a directory

const db = yield* Cloudflare.D1.Database("my-db", {
migrations: "./migrations",
});

Drizzle migrations (adopts an existing drizzle-kit-migrated database)

const schema = yield* Drizzle.Schema("app-schema", {
schema: "./src/schema.ts",
dialect: "sqlite",
});
const db = yield* Cloudflare.D1.Database("my-db", {
migrations: schema,
});

Custom bookkeeping table name

const db = yield* Cloudflare.D1.Database("my-db", {
migrations: { dir: "./migrations", table: "my_migrations" },
});

Use importFiles to seed the database with raw .sql files via Cloudflare’s D1 import API. Each file is hashed; only files whose contents change are re-imported on subsequent deploys.

const db = yield* Cloudflare.D1.Database("my-db", {
importFiles: ["./seed/users.sql", "./seed/posts.sql"],
});

clone performs a full export → import from a source database during creation. It accepts a D1Database resource, a { databaseId }, or a { name } to look up by name.

Clone by passing the source resource directly

const source = yield* Cloudflare.D1.Database("source-db");
const cloned = yield* Cloudflare.D1.Database("cloned-db", {
clone: source,
});

Clone by databaseId

const cloned = yield* Cloudflare.D1.Database("cloned-db", {
clone: { databaseId: "abcdef12-3456-7890-abcd-ef1234567890" },
});

Clone by name

const cloned = yield* Cloudflare.D1.Database("cloned-db", {
clone: { name: "source-db" },
});
const db = yield* Cloudflare.D1.QueryDatabase(MyDatabase);
// Run a query
const results = yield* db.prepare("SELECT * FROM users WHERE id = ?")
.bind(userId)
.all();
// Execute a mutation
yield* db.prepare("INSERT INTO users (id, name) VALUES (?, ?)")
.bind(newId, name)
.run();