Cloudflare.D1 reference
Database
Section titled “Database”Source:
packages/cloudflare/src/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.
Database: Creating a Database
Section titled “Database: Creating a Database”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",});Database: Migrations
Section titled “Database: Migrations”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" },});Database: Importing SQL
Section titled “Database: Importing SQL”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"],});Database: Cloning a Database
Section titled “Database: Cloning a Database”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" },});Database: Binding to a Worker
Section titled “Database: Binding to a Worker”const db = yield* Cloudflare.D1.QueryDatabase(MyDatabase);
// Run a queryconst results = yield* db.prepare("SELECT * FROM users WHERE id = ?") .bind(userId) .all();
// Execute a mutationyield* db.prepare("INSERT INTO users (id, name) VALUES (?, ?)") .bind(newId, name) .run();QueryDatabase
Section titled “QueryDatabase”Source:
packages/cloudflare/src/D1/QueryDatabase.ts
Bind a Database to a Worker and obtain the Effect-native D1
connection client (prepare, exec, batch, raw).
QueryDatabase is a single identifier that is simultaneously the binding’s
Context tag, its type, and the callable —
yield* Cloudflare.D1.QueryDatabase(db).
QueryDatabase: Examples
Section titled “QueryDatabase: Examples”const db = yield* Cloudflare.D1.QueryDatabase(MyDatabase);const rows = yield* db.prepare("SELECT * FROM users").all();Source:
packages/cloudflare/src/D1/SQL.ts
Open an @effect/sql-d1 client over a Cloudflare D1 binding.
Accepts the client returned by Cloudflare.D1.QueryDatabase(db) — or its
raw effect directly — and returns a D1Client (which implements the
generic SqlClient interface) wrapped in a chainable Proxy, so it can be
resolved once at Worker init and used from any handler:
import * as SQL from "@alchemy.run/cloudflare/D1/SQL";
const d1 = yield* Cloudflare.D1.QueryDatabase(Db);const sql = yield* SQL.D1(d1);
fetch: Effect.gen(function* () { const users = yield* sql`SELECT * FROM users`;});The client build is deferred until the first query and memoized on the
current execution’s Scope (via makeExecutionMemo), so the
D1Client (and its prepared-statement cache) is built at most once per
execution — a Worker fetch/queue/scheduled event, a Durable Object
call, or a Workflow run — and torn down when the event settles. Deploy /
plan-time invocations never touch D1.