dozeGitHubGet doze
Registry
Check against your doze

Which doze do you run?

doze 0.1.1newest · 2 Jul 2026doze 0.1.02 Jul 2026Stop checkingKept in this browser only. Nothing is sent anywhere.

PostgreSQL

OfficialSigned

Real local Postgres, declared not scripted.

doze/postgres
$ doze add postgres
Newest
0.2.4 · 2 Nov 2026
Needs
any doze
Runs
Postgres 14 – 18
Platforms
macOS arm64 · Linux arm64 · Linux x86_64
Licence
Apache-2.0

Start

Three lines in doze.hcl give you a real Postgres. Nothing starts until something connects.

1 · In doze.hcl
doze.hcl
module postgres "postgres" {
  version = 18
}
2 · Hand your app the URL
doze.hcl
app "orders" {
  run = "go run ./services/orders"
  env = { DATABASE_URL = module.postgres.url }
}

Your app sees postgres://postgres@127.0.0.1:5432/postgres?sslmode=disable. The database is named after the instance. doze env prints it for tools outside doze.hcl.

3 · Connect
import (
  "context"
  "os"

  "github.com/jackc/pgx/v5/pgxpool"
)

func open(ctx context.Context) (*pgxpool.Pool, error) {
  // The first connection wakes Postgres; it can take a moment.
  return pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
}

Node: new pg.Pool({ connectionString: process.env.DATABASE_URL }) · Python: psycopg.connect(os.environ["DATABASE_URL"]) · psql: psql "$(doze url postgres)"

Recipes

The setups people write most, each complete. Paste one over the block above.

A role and a schema per service

From our example project, Larder

Each service connects as itself and can touch only its own tables. The schema shares the role's name, so the default search_path finds it.

doze.hcl
module postgres "postgres" {
  version = 18

  role "orders"   { password = "orders" }
  role "payments" { password = "payments" }

  schema "orders"   { owner = "orders" }
  schema "payments" { owner = "payments" }
}

Vectors with pgvector

Coming in postgres 0.3

Name the extension; doze fetches the build for your Postgres major and platform, pins it in doze.lock and runs CREATE EXTENSION.

vector: versions, platforms, how to query
doze.hcl
module postgres "postgres" {
  version    = 18
  extensions = ["vector"]
}

Pin an exact minor

18 takes the newest 18.x at first use (today 18.6) and then never moves. Quote a version with a dot: as a number, 17.10 would read as 17.1.

All 79 Postgres builds
doze.hcl
module postgres "postgres" {
  version = "18.4"
}

A throwaway database for tests

A second instance on its own port. Reset wipes its rows; the next connection brings your roles and schemas back. Parallel workers each create and drop their own database inside it.

doze.hcl
module postgres "test" {
  version = 18
  port    = 5433
  sleep   = "30s"
}
terminal
$ doze reset test --yes
$ doze run -- go test ./...

Extensions

16 extensions by name, coming in postgres 0.3: doze fetches each for your Postgres major and platform. Contrib ones (pg_trgm, uuid-ossp, hstore, citext) ship with Postgres and work now.

All 16 extensions

Preloads: doze adds it to shared_preload_libraries and restarts the instance once when the set changes.

What doze does for you

Wakes on connect

doze holds port 5432. The first connection wakes Postgres and is handed over once it is ready.

Sleeps after 2 minutes

With no connection open for 2m it goes to sleep; the data stays on disk. sleep = "never" keeps it on.

Converges what you declare

Roles, schemas, grants and extensions: creates what is new, changes what changed, drops what you removed.

Moves your data between majors

Change 17 to 18, then doze migrate postgres: dump, fresh cluster, restore. The old data is kept beside it.

Tuned for a laptop

fsync off, 16MB shared_buffers, 50 connections. Set fsync = true when you need it crash-safe.

Same bytes on every machine

The module and the Postgres build are pinned by sha256 in doze.lock. Commit it.

Quality

Each line says where it comes from, so you can check it.

  • Signed by doze-dev

    ed25519 key Nu5y8mbj…GWjw=, compiled into doze, over every file and over the whole index. How signing works

    signed index
  • Three platforms

    macOS arm64, Linux x86_64, Linux arm64, each with its own sha256, in every release.

    signed index
  • Conformance-tested on Postgres 14–18

    Every argument on the Reference tab converged into a running server, once per major, before a release is signed.

    doze-modules CI · new
  • Every example on this page parsed by doze

    By doze 0.2 with doze lint --offline, on every change to the registry.

    registry CI · new
  • Source linked

    doze-modules/modules/postgres, Apache-2.0; Postgres builds from doze-binaries.

    GitHub