Database Provisioning
Create, configure, and manage fully managed serverless PostgreSQL databases with automatic scaling, instant branching, and connection pooling.
Createst provides fully managed PostgreSQL databases that you can provision, manage, and connect to your projects — all from within the platform. Each database is a serverless Postgres instance with automatic scaling, connection pooling, and instant branching for preview deployments.
Overview
Every Createst database is a fully managed, serverless PostgreSQL instance. Key properties:
- Serverless — Compute scales to zero when idle and wakes up on the first connection. You only pay for what you use.
- Instant branching — Create copy-on-write branches of your database in seconds. Branches share storage with the parent, so they're almost free until data diverges.
- Connection pooling — Every database includes a built-in PgBouncer connection pooler. Use the pooled connection string for web applications.
- Encrypted at rest — Connection strings and passwords are AES-256-GCM encrypted before storage. They're decrypted only when you request them.
- Automatic cleanup — Preview database branches are automatically deleted when their deployment is removed. An hourly cleanup job catches any orphaned branches.
Creating a Database
From the UI
- Navigate to Settings in the left sidebar
- Click Databases in the Settings menu
- Click Create Database
- Enter a name for your database (must be unique within your account)
- Select a region (default: AWS US East - Ohio)
- Click Create
The database begins provisioning immediately. Status updates appear in real time. Most databases become active within 10-15 seconds.
From the API
POST /api/databases
Content-Type: application/json
{
"name": "my-app-db",
"region": "aws-us-east-2"
}Optional fields:
| Field | Type | Default | Description |
|---|---|---|---|
name | string | (required) | Unique name for the database |
region | string | aws-us-east-2 | Infrastructure region (see Regions) |
minComputeCU | number | 0.25 | Minimum compute units (scales down to this) |
maxComputeCU | number | 4 | Maximum compute units (scales up to this) |
suspendTimeoutSeconds | number | 3600 | Seconds of inactivity before compute suspends |
Database Lifecycle
Each database has a status that reflects its current state:
| Status | Description |
|---|---|
| PROVISIONING | Database is being created. Typically completes in under 15 seconds. |
| ACTIVE | Database is ready for connections. Compute may be suspended if idle, but wakes automatically on the first connection. |
| SUSPENDED | Compute is suspended due to inactivity. The database wakes automatically when a connection is made — no action required. |
| FAILED | Provisioning failed. Use the Retry button or POST /api/databases/:id/retry to try again. |
| DELETING | Database is being removed. |
| DELETED | Database has been deleted. |
Provisioning Status (SSE)
You can subscribe to real-time provisioning updates via Server-Sent Events:
GET /api/databases/:id/provisioning-statusThe stream emits JSON events every 2 seconds:
{"status": "PROVISIONING", "done": false}
{"status": "ACTIVE", "done": true}The stream ends when status reaches ACTIVE, FAILED, or after 60 seconds.
Retrying Failed Provisioning
If a database enters the FAILED state, you can retry:
- UI: Click the Retry button on the database card
- API:
POST /api/databases/:id/retry
This resets the status to PROVISIONING and polls the infrastructure again.
Deleting a Database
- UI: Click Delete on the database card (with confirmation)
- API:
DELETE /api/databases/:id
Deletion is permanent. The underlying infrastructure is destroyed asynchronously. Associated database branches are also cleaned up.
Connection Strings
Each database provides two connection strings:
Pooled (Recommended)
The pooled connection uses a built-in PgBouncer connection pooler. Use this for web applications — it handles connection multiplexing and prevents exhausting the connection limit.
postgresql://user:password@ep-cool-name-pooler.us-east-2.aws.neon.tech/neondb?sslmode=requireDirect
The direct connection bypasses the pooler and connects straight to the Postgres instance. Use this for:
- Database migrations (e.g.,
prisma migrate deploy) - Long-running queries
LISTEN/NOTIFY- Tools that manage their own connection pool
postgresql://user:password@ep-cool-name.us-east-2.aws.neon.tech/neondb?sslmode=requireViewing Connection Strings
- UI: Click Connection String on any active database card. A modal shows both pooled and direct strings with copy buttons.
- API:
GET /api/databases/:id/connection-string
Every time you view a connection string, an audit log entry is created.
Compute and Scaling
Databases use a serverless compute model measured in Compute Units (CU):
| Setting | Default | Description |
|---|---|---|
minComputeCU | 0.25 | Minimum compute when active. Lowest possible is 0.25 CU (~0.25 vCPU, 1 GB RAM). |
maxComputeCU | 4 | Maximum compute the database can scale to under load. |
suspendTimeoutSeconds | 3600 | Seconds of inactivity before compute suspends (scales to zero). |
How Autoscaling Works
- When a connection arrives, compute starts at
minComputeCU - Under load, compute scales up automatically (up to
maxComputeCU) - When load decreases, compute scales back down
- After
suspendTimeoutSecondsof zero activity, compute suspends entirely - The next connection wakes compute automatically (cold start ~500ms)
Updating Compute Settings
PATCH /api/databases/:id
Content-Type: application/json
{
"minComputeCU": 0.5,
"maxComputeCU": 8,
"suspendTimeoutSeconds": 1800
}Changes are applied to the underlying compute endpoint asynchronously.
Preview Databases (Branching)
The most powerful database feature is instant branching for preview deployments. When you push a commit and Createst creates a preview deployment, it can automatically create a database branch — a copy-on-write clone of your production database.
How It Works
- You configure a source database for your project (see Project Database Configuration)
- When a preview deployment is triggered (e.g., by a git push), Createst:
- Creates a database branch named
preview-{commit-sha}from the source database's default branch - Fetches the branch's connection URI
- Injects it as an environment variable (default:
DATABASE_URL) into the preview deployment container
- Creates a database branch named
- Your preview app boots with its own isolated database that contains a snapshot of production data
- When the preview deployment is deleted, the database branch is automatically cleaned up
Why This Matters
- Instant: Branches are created in seconds using copy-on-write — no data copying
- Isolated: Each preview deployment gets its own database. Schema changes, test data, and migrations in one preview don't affect others or production
- Cost-effective: Branches share storage with the parent. You only pay for data that diverges
- Automatic: No manual setup — branches are created and destroyed with the deployment lifecycle
Branch Lifecycle
| Status | Description |
|---|---|
| CREATING | Branch is being provisioned |
| ACTIVE | Branch is ready for connections |
| SUSPENDED | Branch compute is suspended (wakes on connection) |
| FAILED | Branch creation failed |
| DELETED | Branch has been cleaned up |
Orphan Branch Cleanup
If a deployment is deleted through an unexpected path (crash, force-delete, etc.), its database branch might be left behind. A background cleanup job runs every hour and:
- Finds all database branches linked to deployments
- Checks if the linked deployment still exists
- Deletes any branches whose deployments are gone
- Logs each cleanup action in the audit log
Project Database Configuration
To enable automatic preview database branching for a project, configure a Project Database Config:
From the API
PUT /api/databases/projects/:projectKey/database-config
Content-Type: application/json
{
"sourceDatabaseId": "clxx1234...",
"previewMinComputeCU": 0.25,
"previewMaxComputeCU": 1,
"previewSuspendTimeoutSeconds": 300,
"previewMaxStorageGB": 5,
"autoCreateBranchForPreview": true,
"autoDeleteBranchOnCleanup": true,
"envVarName": "DATABASE_URL"
}Configuration Fields
| Field | Type | Default | Description |
|---|---|---|---|
sourceDatabaseId | string | null | The database to branch from for previews |
previewMinComputeCU | number | 0.25 | Min CU for preview branches |
previewMaxComputeCU | number | 1 | Max CU for preview branches |
previewSuspendTimeoutSeconds | number | 300 | Suspend timeout for previews (5 min default — faster suspension saves cost) |
previewMaxStorageGB | number | 5 | Max storage for preview branches |
autoCreateBranchForPreview | boolean | true | Automatically create a branch on preview deploy |
autoDeleteBranchOnCleanup | boolean | true | Automatically delete the branch when preview is removed |
envVarName | string | DATABASE_URL | The environment variable name injected into the preview container |
Reading the Config
GET /api/databases/projects/:projectKey/database-configReturns null if no config exists.
Removing the Config
DELETE /api/databases/projects/:projectKey/database-configProduction Databases
For production workloads, the database you create in Createst is your production database. There's no separate "production mode" — the same database serves all environments:
- Production: Your app connects using the database's connection string (pooled recommended)
- Preview/Staging: Automatic branches give each preview its own isolated copy of the production data
- Development: You can connect directly from your local machine using the direct connection string
Recommended Setup
- Create one database per application (e.g.,
my-saas-db) - Configure Project Database Config to enable preview branching
- Set compute limits appropriate for your production load:
- Small apps:
minComputeCU: 0.25,maxComputeCU: 2 - Medium apps:
minComputeCU: 0.5,maxComputeCU: 4 - High-traffic:
minComputeCU: 1,maxComputeCU: 8
- Small apps:
- Use pooled connection for your web app, direct connection for migrations
- Set
suspendTimeoutSecondsbased on your traffic pattern:- Always-on:
0(never suspend) - Light traffic with occasional gaps:
3600(1 hour) - Dev/staging:
300(5 minutes)
- Always-on:
Connection in Your App
In your application code:
// The connection string is available as an env var
const connectionString = process.env.DATABASE_URL;
// For Prisma
// In schema.prisma:
// datasource db {
// provider = "postgresql"
// url = env("DATABASE_URL")
// }
// For raw pg
import pg from 'pg';
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });For preview deployments, the DATABASE_URL (or your configured envVarName) is automatically set to the branch's connection string. No code changes needed.
Password Rotation
You can rotate the database password at any time:
- API:
POST /api/databases/:id/rotate-password
This generates a new password and updates the encrypted connection strings stored in Createst. The response includes the new password.
Important: After rotation, you must update any external services that use the old password. Applications running on Createst preview deployments will automatically use the new credentials on their next deployment.
Usage and Billing
Database usage is metered along these dimensions:
| Metric | Description |
|---|---|
| Compute Time | Total seconds of active compute (CPU time) |
| Active Time | Total seconds the database had at least one active connection |
| Written Data | Bytes written to storage |
| Data Transfer | Bytes transferred out of the database |
| Storage Size | Total size of data stored on disk |
Viewing Usage
- UI: Available in the database detail view
- API:
GET /api/databases/:id/usage?days=30
Usage records are broken down by period (hourly granularity) with cost estimates in cents:
{
"success": true,
"data": [
{
"periodStart": "2026-04-10T00:00:00Z",
"periodEnd": "2026-04-10T01:00:00Z",
"computeTimeSeconds": 3600,
"activeTimeSeconds": 3200,
"writtenDataBytes": 1048576,
"storageSizeBytes": 52428800,
"computeCostCents": 12,
"storageCostCents": 3,
"totalCostCents": 15
}
]
}Cost Model
- Compute: Billed per CU-hour of active compute
- Storage: Billed per GB-month of stored data
- Branching: Branches use copy-on-write — you only pay for data that diverges from the parent
There is no free tier. All usage is billed from the first CU-hour. This keeps the pricing simple and predictable.
Regions
Choose the region closest to your application servers for lowest latency:
| Region ID | Location |
|---|---|
aws-us-east-2 | AWS US East (Ohio) — Default |
aws-us-west-2 | AWS US West (Oregon) |
aws-eu-west-1 | AWS EU West (Ireland) |
aws-ap-southeast-1 | AWS Asia Pacific (Singapore) |
The region is set at database creation time and cannot be changed. To move to a different region, create a new database and migrate your data.
Admin Dashboard
Platform administrators have access to a comprehensive database management dashboard at Admin > Databases. It includes four tabs:
Summary Tab
Platform-wide aggregates:
- Total databases, active databases, suspended databases
- Total branches across all users
- Aggregate compute and storage costs
- Per-user breakdown (user name, email, database count)
Databases Tab
Searchable, filterable list of all databases across the platform:
- Filter by status (Active, Provisioning, Suspended, Failed)
- Search by database name
- View owner, region, compute settings, branch count
- Force-delete any database (admin only)
Keys Tab
Monitoring and management of the platform's API key configuration:
- Which key is currently active (primary vs fallback)
- Whether primary and fallback keys are configured
- Fallback usage count and last fallback usage timestamp
- Swap Keys button for zero-downtime key rotation
Audit Log Tab
Complete audit trail of all database operations across the platform:
- Filterable by action, user, or database
- Tracks: creation, deletion, connection string views, password rotations, settings changes, orphan cleanups, retry attempts
API Key Management (Admins)
The platform uses API keys to communicate with the database infrastructure. Admins can manage these keys:
Primary + Fallback Key Architecture
Two API keys can be configured simultaneously:
- Primary Key — Used for all API calls by default
- Fallback Key — Automatically used if the primary key returns a 401 or 403 error
This enables zero-downtime key rotation:
- Set the new key as the fallback
- Monitor the admin Keys tab — fallback usage count shows if the primary is failing
- When ready, click Swap Keys to promote the fallback to primary
- Remove the old key from the fallback slot
Key Status API
GET /api/admin/databases/neon/statusResponse:
{
"success": true,
"data": {
"primaryKeyConfigured": true,
"fallbackKeyConfigured": false,
"activeKey": "primary",
"fallbackUsageCount": 0,
"lastFallbackUsage": null
}
}Swap Keys API
POST /api/admin/databases/neon/swap-keysInstantly promotes the fallback key to primary and demotes the old primary to fallback.
Audit Log
Every database operation is logged in an immutable audit trail. Logged actions include:
| Action | Description |
|---|---|
DATABASE_CREATE | New database provisioned |
DATABASE_DELETE | Database deleted |
DATABASE_UPDATE | Database settings modified |
BRANCH_CREATE | Preview branch created |
BRANCH_DELETE | Preview branch deleted |
PASSWORD_ROTATE | Database password rotated |
CONNECTION_STRING_VIEW | Connection string was viewed (for security auditing) |
SETTINGS_UPDATE | Compute or timeout settings changed |
RETRY_PROVISIONING | Failed provisioning was retried |
ORPHAN_BRANCH_CLEANUP | Orphaned preview branch was automatically cleaned up |
USER_DELETE_CLEANUP | User account deletion triggered database cleanup |
Each entry records:
- Timestamp
- User who performed the action
- Database and branch involved (if applicable)
- Success/failure status
- Error message (if failed)
- Additional details as JSON
API
# Admin: View all audit logs (paginated, filterable)
GET /api/admin/databases/audit-log?action=DATABASE_CREATE&limit=50&offset=0Environment Variables
Platform Configuration
| Variable | Required | Description |
|---|---|---|
VIBECORE_123455_NEON_API_KEY | Yes | Primary API key for database infrastructure |
VIBECORE_123455_NEON_API_KEY_FALLBACK | No | Fallback API key for zero-downtime rotation |
VIBECORE_123455_NEON_DEFAULT_REGION | No | Default region for new databases (default: aws-us-east-2) |
Security Notes
- The API key is never exposed to executor pods or user code. It exists only on the control plane.
- Connection strings and passwords are encrypted with AES-256-GCM before storage. They are decrypted only at the moment of use or when explicitly requested by the database owner.
Injected Into Deployments
When preview branching is enabled, the following environment variable is automatically injected into preview deployment containers:
| Variable | Default Name | Description |
|---|---|---|
| Database URL | DATABASE_URL | Connection string for the preview branch. Configurable via envVarName in Project Database Config. |
This variable is set per-deployment and contains the branch-specific connection string, so each preview gets its own isolated database.
API Reference
All endpoints require authentication. Admin endpoints additionally require the platform admin role.
User Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/databases | List your databases |
POST | /api/databases | Create a new database |
GET | /api/databases/:id | Get database details |
PATCH | /api/databases/:id | Update database settings |
DELETE | /api/databases/:id | Delete a database |
GET | /api/databases/:id/connection-string | Get connection strings (direct + pooled) |
POST | /api/databases/:id/rotate-password | Rotate database password |
GET | /api/databases/:id/branches | List database branches |
GET | /api/databases/:id/status | Get current status |
GET | /api/databases/:id/provisioning-status | SSE stream for provisioning progress |
POST | /api/databases/:id/retry | Retry failed provisioning |
GET | /api/databases/:id/usage?days=30 | Get usage records |
GET | /api/databases/projects/:key/database-config | Get project database config |
PUT | /api/databases/projects/:key/database-config | Set/update project database config |
DELETE | /api/databases/projects/:key/database-config | Remove project database config |
Admin Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/admin/databases/summary | Platform-wide database summary |
GET | /api/admin/databases | List all databases (filterable) |
GET | /api/admin/databases/:id | Full database detail (including connection strings) |
GET | /api/admin/databases/:id/usage | Usage records for any database |
GET | /api/admin/databases/:id/branches | Branches for any database |
DELETE | /api/admin/databases/:id | Force-delete any database |
GET | /api/admin/users/:userId/databases | List databases for a specific user |
GET | /api/admin/databases/neon/status | API key configuration status |
POST | /api/admin/databases/neon/swap-keys | Swap primary/fallback API keys |
GET | /api/admin/databases/audit-log | Audit log (filterable by action, user, database) |