Database
A Database is a managed Postgres database. v1 supports Postgres only; MySQL on the runtime lands in v1.1.
Quick example
import { Project, Database } from '@sprintsail/sdk';
export const app = new Project('orders');
export const db = new Database(app, 'orders', {
engine: 'postgres',
version: '16',
});
Usage in a handler (after binding):
import { db } from '../infra.js';
await db.query(
'INSERT INTO orders (id, amount) VALUES ($1, $2)',
[order.id, order.amount],
);
const rows = await db.query<{ id: string; amount: number }>(
'SELECT id, amount FROM orders WHERE status = $1',
['paid'],
);
Config
interface DatabaseConfig {
engine: 'postgres' | 'mysql'; // mysql runtime support: v1.1
version: string; // e.g. '16', '16.6'
size?: 'small' | 'medium' | 'large'; // AWS only; default 'small'
publiclyAccessible?: boolean; // AWS only; default false
}
Target mapping
| Target | Maps to | Notes |
|---|---|---|
aws | RDS | Default db.t4g.micro, 20 GB gp3, encrypted, single-AZ. Master credentials stored in Secrets Manager. Provision is async (~5–10 min to "available"). |
sprintsail-runtime | CloudNativePG Cluster | One CNPG Cluster per Database primitive. Default 1 instance, 1Gi PVC. Ready in ~15s on kind, longer on real clusters. App user + database created via CNPG bootstrap.initdb. |
Runtime methods
db.query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
pg-style parameterised SQL ($1, $2). Returns an array of rows.
Connection pools are per-process and cached for the lifetime of the container. Cold-start–sensitive primitives (Function, API) get a fresh pool per invocation; long-running primitives (WebApp, Worker, CronJob) reuse it.
What sail migrate does
| Path | What happens |
|---|---|
| AWS → AWS | Manual pg_dump/pg_restore for now (stubbed). Provider provisions the destination RDS. |
| AWS → Sprintsail Runtime | Auto: an in-cluster Kubernetes Job runs `pg_dump |
| Runtime → Runtime | Same in-cluster Job, K8s source secret → K8s dest secret for creds. |
| Runtime → AWS | Planned. |
Credentials
You never deal with credentials in your code — db.query() resolves them through the runtime adapter.
On AWS: master creds in Secrets Manager as {username,password} JSON.
On Runtime: CNPG auto-creates <cluster>-app Secret with username/password keys.
If you need direct DB access (psql from your laptop, debugging), open the right port and SG/Ingress rule. The credentials Secret is yours to read.
Safety
sail destroy for a Database on AWS sets SkipFinalSnapshot: true and DeleteAutomatedBackups: true. This is a deliberate dev/test default — you lose backups. v1.1 will add a protected flag.