CoDuck Docs

#Database

Every CoDuck project comes with its own private Postgres database. It's provisioned automatically on first deploy, and the connection string is injected into your container as DATABASE_URL (pooled) and DIRECT_URL (direct, for migrations).

[!IMPORTANT] The database is provisioned empty — CoDuck creates the database, not your tables. You must create your schema yourself on deploy (see below). An app that assumes tables already exist will fail with relation "…" does not exist.

#How it works

On first deploy, CoDuck:

  1. Creates a Postgres database dedicated to your project.
  2. Provisions a dedicated database user with permissions scoped to that DB only.
  3. Injects DATABASE_URL (PgBouncer at 127.0.0.1:6432 on the VPS loopback, transaction-pool mode with max_prepared_statements=100) and DIRECT_URL (postgres directly at 127.0.0.1:5433, used only by Prisma's schema engine for prisma db push / prisma migrate deploy) — both reserved; you can't override them. See Runtime architecture for the full container + networking model.

Subsequent deploys reuse the same database. Your app reads process.env.DATABASE_URL like any normal Postgres host — Prisma, Drizzle, Kysely, node-postgres, pg, knex, and sequelize all work against it. The CoDuck Auth SDK (@coduckai/sdk/auth) uses the same database to store users.

#Schema and migrations

How CoDuck applies your schema depends on whether you use Prisma and whether you've set a preStart:

  • Prisma, no preStart — if prisma/schema.prisma declares models, CoDuck runs prisma db push on each deploy to sync the schema (additive; it preserves tables it doesn't know about). This is the zero-config path.
  • You set a preStart — CoDuck does not auto-push; your preStart owns schema setup. Use this for real migration files: "preStart": "prisma migrate deploy".
  • Not using Prisma — set a preStart that runs your migration tool, e.g. "preStart": "drizzle-kit push" or "preStart": "node scripts/migrate.js".

preStart runs after install + build, before the app starts, on every deploy — see the coduck.json reference. For migrations, prefer DIRECT_URL over DATABASE_URL (Prisma's schema engine doesn't go through PgBouncer).

#Inspect your data

Open your project at https://app.coduck.ai/project/<projectId>, switch to the Cloud panel, then the Data tab. You'll see your schema, every table, and recent rows. The view is read-only — to write data, use your application code.

#Backups

Backups run automatically every night (cluster-level physical backups via pgBackRest, managed by CoDuck). You can also create one on demand from the Cloud panel → Data tab, in the Backups section. On-demand backups use pg_dump so you get a portable SQL export of just your project's database. Restoring is destructive and asks for confirmation before overwriting your current DB.

#Why there's no raw connection URL

#Connection pooling

PgBouncer handles connection pooling on the server side, so a single project doesn't need a large client-side pool. Inside your app, set your client's max_connections to 10 or lower. Opening too many direct connections will get throttled.

#Limits

ResourceLimit
Storage1 GB per project DB (soft; raisable on paid plans)
ConnectionsPgBouncer-pooled; keep app pool ≤ 10
ComputeShared with the cluster; no separate DB CPU billing

#Common failures

  • relation "…" does not exist at runtime. The database starts empty and your schema never got created. Make sure a Prisma schema with models is present (CoDuck runs prisma db push), or set a preStart that runs your migrations.
  • Migration/db push fails on deploy. Check the deploy logs. A destructive change (dropping a column with data) is blocked by prisma db push without --accept-data-loss; switch to a real migration (preStart: "prisma migrate deploy").
  • bouncer config error on every query. PgBouncer can't authenticate connections to your DB. Almost always caused by running DROP SCHEMA public CASCADE (or equivalent) from your app, which destroys the public.user_lookup() function PgBouncer needs and the USAGE grant to pgbouncer_auth. Contact support to restore them. To migrate, drop and recreate your own tables instead of nuking public.
  • Connection pool exhausted. Symptom is too many clients or hung requests under load. Lower max_connections in your client pool — PgBouncer is already pooling on the server side, so your app should open very few direct connections.
  • Schema mismatch at runtime. Your code expects a column the DB doesn't have — a migration wasn't applied. CoDuck auto-runs prisma generate when your schema has models, so you don't need it in your build step; the usual cause is an uncommitted schema change.

#For developers

If you'd rather work from a terminal, the CoDuck CLI exposes read-only schema/table inspection and backup management for your project. See CLI commands.

#Next