CapyDB Docs
Getting Started

Connections

CapyDB speaks normal Postgres. One direct URL, one pooled URL, both usable from standard clients and frameworks.

Direct access

Use the direct URL when you need a normal PostgreSQL session: administrative SQL, psql, and migration tools that expect session-level features (advisory locks, LISTEN/NOTIFY, prepared statements with named cursors, DDL in transactions).

Pooled access

Use the pooled URL for app traffic with many short-lived connections. The infrastructure layer runs managed connection pooling (transaction pooling), so your app can stay busy without exhausting the plan's connection budget. Avoid session-level state on pooled connections - the full list of what breaks and the per-driver flags are in Connection pooling.

Which URL goes where

WorkloadURL
App runtime (web servers, serverless functions)Pooled
Schema migrations (Prisma migrate, Drizzle push, Django migrate, Rails db:migrate)Direct
psql, GUI clients, one-off admin sessionsDirect
pg_dump / bulk loadsDirect

Connection fields

  • Host and ports come from the project's region
  • Each project has a generated database name and role name
  • The dashboard exposes both URLs once the provision job completes; the CLI writes them as DATABASE_URL, DATABASE_DIRECT_URL, and DATABASE_POOL_URL. For JavaScript/TypeScript stacks DATABASE_URL gets the pooled URL; for stacks whose canonical driver manages its own pool (pgx, SQLAlchemy, ActiveRecord, and unknown non-JS stacks) the CLI deliberately puts the direct URL in DATABASE_URL instead
  • Integrations (Vercel, Netlify, GitHub Action) use the names DATABASE_URL (pooled) and DATABASE_URL_UNPOOLED (direct)
  • Preview databases expose the same direct and pooled connection pattern

TLS

Connections require TLS, and issued URLs carry sslmode=verify-full. Cells are served from a publicly trusted certificate covering *.db.capydb.dev, so verify-full validates the certificate chain and the hostname - a machine-in-the-middle cannot present a substitute certificate. Keep the parameter in the URL; if a client errors with "SSL off" or refuses to negotiate TLS, check it was not stripped when the URL was copied around.

libpq-based clients need one extra parameter. psql, pgAdmin, Rails, Django and psycopg/SQLAlchemy all use libpq, which does not read your operating system's trust store by default - it looks for ~/.postgresql/root.crt and fails with root certificate file ... does not exist. Point it at the system roots:

psql "$DATABASE_URL&sslrootcert=system"     # libpq 16+

Drivers that use their own TLS stack - postgres.js, node-postgres, pgx, Prisma - already trust the system roots and need nothing extra. sslrootcert is consumed by libpq locally and never sent to the server, so it is safe to leave in a URL you share between tools.

Credential rotation

Rotating credentials (dashboard, POST /v1/projects/{id}/credentials/rotate) generates a new password and invalidates the old URLs. Connected Vercel and Netlify integrations re-push env vars automatically; anything else holding the old URL needs a manual update. A credentials.rotated webhook event fires when it completes. Invalidation timing and the full runbook are in Credential rotation.