Skip to content

SQL

An alchemy app talks SQL at whichever level fits: a raw tagged-template client, an ORM, or both against the same connection. The schema rides the same deploy graph as the infrastructure, so alchemy deploy regenerates and applies pending migrations alongside everything else.

  • D1 — Cloudflare’s serverless SQLite, bound natively into a Worker.
  • Hyperdrive — edge connection pooling for any Postgres: Neon, PlanetScale, RDS, or a database you already run.
  • AWS-side connections — DSQL, RDS, and Redshift bindings in the API reference.

alchemy/SQL is the low-level home: tagged-template queries with typed errors, no ORM. alchemy/Drizzle is the ORM sibling: a typed schema and relational queries. Both wrap the same @effect/sql drivers and share one lifecycle.

import * as SQL from "alchemy/SQL";
import * as Drizzle from "alchemy/Drizzle";
// Raw effect-sql — tagged-template queries, typed errors
const sql = yield* SQL.D1(d1);
const users = yield* sql`SELECT * FROM users WHERE id = ${id}`;
// Drizzle — typed schema, relational queries
const db = yield* Drizzle.D1(d1, { relations });
const user = yield* db.query.Users.findFirst({ with: { posts: true } });

Every client builds lazily on the first query of an execution, is reused for every query in that execution, and tears down when the event settles — Connection lifecycle explains why.

Goal Reach for
Raw SQL on Postgres Effect SQL: Postgres
Raw SQL on D1 Effect SQL: D1
Typed schema + queries on Postgres Drizzle: Postgres
Typed schema + queries on D1 Drizzle: D1
Schema changes applied on deploy Drizzle migrations
Hand-written .sql migrations Effect SQL migrations
A service that runs on any database SqlClient + Layers — see Provide as a service

MySQL support is in flight: drizzle’s effect-mysql2 driver and Hyperdrive’s text-protocol requirements are being reconciled upstream in @effect/sql-mysql2. Postgres and D1 are the supported paths today.