docs/deploy/database.md
Paperclip uses PostgreSQL via Drizzle ORM. There are three ways to run the database.
Zero config. If you don't set DATABASE_URL, the server starts an embedded PostgreSQL instance automatically.
pnpm dev
On first start, the server:
~/.paperclip/instances/default/db/ for storagepaperclip database existsData persists across restarts. To reset: rm -rf ~/.paperclip/instances/default/db.
The Docker quickstart also uses embedded PostgreSQL by default.
For a full PostgreSQL server locally:
docker compose up -d
This starts PostgreSQL 17 on localhost:5432. Set the connection string:
cp .env.example .env
# DATABASE_URL=postgres://paperclip:paperclip@localhost:5432/paperclip
Push the schema:
DATABASE_URL=postgres://paperclip:paperclip@localhost:5432/paperclip \
npx drizzle-kit push
For production, use a hosted provider like Supabase.
DATABASE_URL in your .envUse the direct connection (port 5432) for migrations and the pooled connection (port 6543) for the application.
If using connection pooling (transaction mode), disable prepared statements via the environment — no source edits needed:
DATABASE_PREPARED_STATEMENTS=false
Related optional client tuning (driver defaults apply when unset): DATABASE_POOL_MAX, DATABASE_IDLE_TIMEOUT_SECONDS, DATABASE_CONNECT_TIMEOUT_SECONDS.
DATABASE_URL | Mode |
|---|---|
| Not set | Embedded PostgreSQL |
postgres://...localhost... | Local Docker PostgreSQL |
postgres://...supabase.com... | Hosted Supabase |
The Drizzle schema (packages/db/src/schema/) is the same regardless of mode.