Skip to content
Discord Get Started

Connect to DB9

DB9 speaks the PostgreSQL wire protocol on port 5433 and on the PostgreSQL default 5432. Any client that connects to Postgres — psql, a Node.js driver, Prisma, SQLAlchemy, or a raw libpq binding — connects to DB9 with no adapter or proxy needed.

Every DB9 connection string follows this pattern:

Output
postgresql://<tenant_id>.<role>@<host>:<port>/postgres
ComponentValueNotes
Schemepostgresql:// or postgres://Both work.
Username<tenant_id>.<role>The first component is the tenant ID DB9 uses to route the connection. Use the tenant-qualified username from the generated connection string, not the database name. The default role is admin.
Hostpg.db9.ioThe public endpoint for hosted DB9. The CLI and API print pg.d0000.db9.io, which is the same server.
Port54335432 works too; the CLI and API print 5432.
DatabasepostgresAll DB9 databases use the postgres database name.

Example:

Output
postgresql://a1b2c3d4e5f6.admin@pg.db9.io:5433/postgres

db9 create prints a long-lived connection string with the admin password once, on its Connection String: line — save it then. db9 db status shows the connection string without the password. To get connection details at any time, use db9 db connect:

Terminal
# Create a database
db9 create --name myapp
# Show connection info
db9 db connect myapp

db9 db connect mints a short-lived token by default (recommended for production and automation). It prints a ready-to-use connection string with the token already embedded as the password, plus the matching psql command:

Output
Temporary connection string (10min):
postgresql://a1b2c3d4e5f6.admin:ey...@pg.d0000.db9.io:5432/postgres
User:
a1b2c3d4e5f6.admin
Expires:
10min (at 2026-03-12T10:30:00Z)
psql Command:
psql "postgresql://a1b2c3d4e5f6.admin:ey...@pg.d0000.db9.io:5432/postgres"
Long-lived DSN:
db9 db users myapp create --username <user> --password <password>
db9 db reset-password myapp

The token is embedded in the connection string rather than printed as a separate field. Use --json for machine-readable output (connection_string, host, port, user, database, expires_at, expires_in, expires_in_seconds).

To get a new long-lived connection string instead, reset the admin password — the command prints the new password and connection string:

Terminal
db9 db reset-password myapp

The SDK’s connection strings carry no password. instantDatabase() returns adminPassword only on the call that creates the database — when it reuses an existing one, connectionString, adminUser and adminPassword are empty strings. client.databases.credentials(id) returns the connection string and the stored admin password on every call:

TypeScript
import { instantDatabase, createDb9Client } from 'get-db9';
const db = await instantDatabase({ name: 'myapp' });
const creds = await createDb9Client().databases.credentials(db.databaseId);
const url = new URL(creds.connection_string); // postgresql://a1b2c3d4e5f6.admin@pg.d0000.db9.io:5432/postgres
url.password = creds.admin_password;
url.searchParams.set('sslmode', 'verify-full');
console.log(url.toString()); // pass this to your driver

Or call the connect-token REST endpoint directly to get a short-lived token — the SDK does not yet publish a native connectToken() method:

TypeScript
const res = await fetch(`https://api.db9.ai/customer/databases/${databaseId}/connect-token`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.DB9_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ role: 'admin' }),
});
const { host, port, database, user, token, expires_at } = await res.json();

Use the connection string directly or let db9 db connect generate the command for you:

Terminal
# Using a connect token (recommended)
PGPASSWORD='<token>' psql "postgresql://a1b2c3d4e5f6.admin@pg.db9.io:5433/postgres"
# Using a static password
PGPASSWORD='<password>' psql "postgresql://a1b2c3d4e5f6.admin@pg.db9.io:5433/postgres"

You can also use a .pgpass file:

Terminal
echo "pg.db9.io:5433:postgres:a1b2c3d4e5f6.admin:<password>" >> ~/.pgpass
chmod 600 ~/.pgpass
psql "postgresql://a1b2c3d4e5f6.admin@pg.db9.io:5433/postgres"

Or use the built-in DB9 SQL REPL, which handles authentication automatically:

Terminal
db9 db sql myapp -q "SELECT version()"

DB9 works with any PostgreSQL-compatible driver or ORM. Set the connection string as your database URL.

TypeScript
import pg from 'pg';
const client = new pg.Client({
// node-postgres uses TLS only when asked — keep the sslmode parameter
connectionString: 'postgresql://a1b2c3d4e5f6.admin:password@pg.db9.io:5433/postgres?sslmode=verify-full',
});
await client.connect();
const res = await client.query('SELECT NOW()');
console.log(res.rows[0]);
await client.end();

For detailed setup guides with migrations, schema patterns, and troubleshooting, see the integration guides for Prisma, Drizzle, SQLAlchemy, TypeORM, Sequelize, Knex, and GORM.

DB9 supports three ways to authenticate connections:

Set at database creation or reset with db9 db reset-password. The password is embedded in the connection string or passed via PGPASSWORD. Simple, but the credential does not expire.

Generated with db9 db connect. The token is used as the password and expires automatically. Recommended for production and CI/CD. The TypeScript SDK does not yet publish a native connectToken() method — see API Reference — Connect Tokens & Keys for the REST equivalent.

Terminal
# Generate a token for a specific role
db9 db connect myapp --user admin

Named tokens created with db9 token create are used for the DB9 REST API and SDK, not for direct pgwire connections. Use them when your application manages databases programmatically rather than connecting with SQL.

Terminal
db9 token create --name ci-agent --expires-in-days 90
export DB9_API_KEY=<token>

See the TypeScript SDK docs for the full auth lifecycle, including anonymous trial accounts and Auth0 SSO.

For client-side applications, use a publishable key (db9pk_...) together with a user JWT in the Browser SDK. Publishable keys are scoped to specific schemas and tables and enforce Row-Level Security policies. The key identifies the application, not the user: queries also need BYO JWT, and a key on its own fails with 28P01.

TypeScript
import { createDb9BrowserClient } from '@db9/browser';
const db9 = createDb9BrowserClient({
apiUrl: 'https://api.db9.ai',
databaseId: 'your-database-id',
anonKey: 'db9pk_your_publishable_key',
});
// Required: a publishable key alone cannot query — without a user JWT the
// request fails with 28P01. Configure BYO JWT and attach the user's token.
db9.auth.setSession({ accessToken: userJwt });
const { data } = await db9.from('todos').select('*');

Publishable keys are created via the REST API. See Security & Auth — Publishable Keys for setup.

Every DB9 endpoint negotiates TLS (TLSv1.3), but the server does not require it: a client that does not ask for TLS, or sets sslmode=disable, connects in plaintext. The server uses SCRAM-SHA-256 authentication by default.

libpq-based clients such as psql and psycopg2 default to sslmode=prefer and use TLS when it is offered. node-postgres (pg) does not use TLS unless the connection string or its ssl option asks for it. Set the mode explicitly:

Terminal
psql "postgresql://a1b2c3d4e5f6.admin@pg.db9.io:5433/postgres?sslmode=require"

Or in a connection string for an ORM:

Output
DATABASE_URL="postgresql://a1b2c3d4e5f6.admin:password@pg.db9.io:5433/postgres?sslmode=require"

sslmode=verify-full also works and checks the server certificate against the system CA roots: add sslrootcert=system for psql with libpq 16+ (psycopg binary wheels: sslrootcert=<CA bundle file>); node-postgres 8 treats sslmode=require as verify-full. To see what a session negotiated, run SELECT ssl, version FROM pg_stat_ssl WHERE pid = pg_backend_pid();.

DB9 reads the tenant ID from the username to route the connection to the correct tenant. The format is:

Output
<tenant_id>.<role>
  • The tenant ID is the routing prefix in the PostgreSQL username. Use the complete username printed in the connection string or by db9 db connect; do not substitute the database name.
  • The role defaults to admin. You can create additional roles with db9 db users create.

This encoding means your username in connection strings will look different from a typical Postgres setup, but it works transparently with all standard PostgreSQL drivers.

CheckDetails
Host and portpg.db9.io:5433, or pg.d0000.db9.io:5432 as the CLI prints it — the same server; port 5432 works on either host
Database nameAlways postgres
UsernameMust include the tenant ID prefix: <tenant_id>.<role> — use the username from the generated connection string, not the database name
PasswordStatic password or connect token — both go in PGPASSWORD or the connection string. db9 db status, the API’s connection_string and the SDK’s connectionString carry no password
TLSUse sslmode=require or sslmode=verify-full — the server does not enforce TLS
ProtocolStandard PostgreSQL wire protocol — no special drivers needed

“password authentication failed” or “fe_sendauth: no password supplied”

  • Verify the tenant ID and role in the username field. A database name such as myapp is not the tenant ID prefix, even when the password is correct.
  • Check that the connection string has a password at all — the one from db9 db status, the API, or the SDK’s connectionString does not.
  • If using a connect token, check that it has not expired.
  • Run db9 db connect myapp to generate a fresh token, or db9 db reset-password myapp for a new long-lived connection string.

“connection refused” on port 5432

  • DB9 accepts port 5432 as well as 5433, so the client is not reaching DB9 at all. A refusal from localhost or 127.0.0.1 means the connection string never reached the driver — node-postgres, for example, falls back to localhost:5432 when connectionString is undefined.

“SSL SYSCALL error” or TLS handshake failures

  • Ensure your client supports TLS. Try adding ?sslmode=require to the connection string.
  • Some older clients may need updated CA certificates.

ORM connection timeouts

  • Check that your ORM’s connection string uses the DB9 host, port 5433 or 5432, and database name postgres.
  • Verify your network allows outbound connections on the port you use.
  • Quick Start — create your first database and run SQL
  • CLI Reference — full command reference including db connect and db reset-password
  • TypeScript SDK — instantDatabase(), credential management, and programmatic access
  • Browser SDK — client-side data access with publishable keys and RLS
  • Architecture — how DB9 routes connections through the pgwire protocol to TiKV
  • Extensions — enable vector search, fs9, HTTP from SQL, and pg_cron after connecting