Skip to content

Fly.Postgres reference

Source: src/Fly/ConnectPostgres.ts

Bind a Postgres cluster to a Fly Service and obtain the Effect-native connection strings for Drizzle.Postgres / SQL.Postgres. Alchemy transports the cluster’s connection URIs automatically; callers do not configure connection-string env vars.

ConnectPostgres is the Context tag, the type, and the callable — yield* Fly.ConnectPostgres(Db). Provide ConnectPostgresHttp.

import * as Drizzle from "alchemy/Drizzle/Postgres";
const conn = yield* Fly.ConnectPostgres(Db);
const db = yield* Drizzle.Postgres(conn.connectionString);
fetch: Effect.gen(function* () {
const rows = yield* db.select().from(users);
});

Source: src/Fly/ConnectPostgresHttp.ts Kind: Layer · Provides: Fly.ConnectPostgres

Implementation of ConnectPostgres. Provide it on the Service Effect.

Registers the cluster attachment for Fly’s private network. Alchemy transports each cluster’s connection URIs through resource Outputs, so callers do not configure connection-string environment variables.

Effect.gen(function* () {
const conn = yield* Fly.ConnectPostgres(Db);
const db = yield* Drizzle.Postgres(conn.connectionString);
}).pipe(Effect.provide(Fly.ConnectPostgresHttp))

Source: src/Fly/Postgres.ts

A Fly.Postgres is a Managed Postgres (MPG) cluster. It is billed. Do not wrap unmanaged fly postgres.

region is required. Alchemy generates a unique name unless you pass one. Omit name in tests and CI.

const db = yield* Fly.Postgres("Db", {
region: "iad",
});

plan is the hardware size: basic, starter, launch, scale, performance. Default is basic.

const db = yield* Fly.Postgres("Db", {
region: "iad",
plan: "starter",
});

The cluster is regional. An App is global. Pass region on the cluster, not on the App.

const db = yield* Fly.Postgres("Db", {
region: "lhr",
});

volumeSizeGb is the initial disk. Fly defaults to 10 GB.

const db = yield* Fly.Postgres("Db", {
region: "iad",
volumeSizeGb: 20,
});

postgis: true enables PostGIS at create.

const db = yield* Fly.Postgres("Db", {
region: "iad",
postgis: true,
});

Yield ConnectPostgres inside init. Provide ConnectPostgresHttp. Pass conn.connectionString to Drizzle.Postgres or SQL.Postgres.

import * as Drizzle from "alchemy/Drizzle/Postgres";
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
export default class Api extends Fly.Service<Api>()(
"Api",
{ app: Site, main: import.meta.url, port: 3000 },
Effect.gen(function* () {
const conn = yield* Fly.ConnectPostgres(Db);
const db = yield* Drizzle.Postgres(conn.connectionString);
return {
fetch: Effect.gen(function* () {
const rows = yield* db.execute("select 1 as ok");
return HttpServerResponse.json({ rows });
}),
};
}).pipe(Effect.provide(Fly.ConnectPostgresHttp)),
) {}

Pass a directory, { dir, table? }, or a Drizzle.Schema resource. Alchemy applies pending files on deploy over the direct URI.

Directory

const db = yield* Fly.Postgres("Db", {
region: "iad",
migrations: "./migrations",
});

Drizzle.Schema

const schema = yield* Drizzle.Schema("app-schema", {
schema: "./src/schema.ts",
out: "./migrations",
});
const db = yield* Fly.Postgres("Db", {
region: "iad",
migrations: schema,
});