DevStride uses Neon for PostgreSQL hosting, with Drizzle ORM for schema management and migrations. Every developer gets isolated database branches — like git branches, but for your database.
Neon provides instant, copy-on-write database branches:
main (staging data)
├── dev-phil-local ← Phil's local dev branch (stable, branch-independent)
├── dev-phil-feature-auth ← Phil's cloud deploy branch (created by ds deploy up)
├── dev-sarah-local ← Sarah's local dev branch
└── dev-ci-pr-142 ← CI/CD ephemeral branch
main contains the latest staging data. All new branches fork from it.dev-{developer}-local) are used for local development. One per developer, stable across git branch switches.dev-{developer}-{branch}) are created by ds deploy up for isolated cloud testing. Each cloud stage gets its own separate database branch.ds db migrate
Applies all pending Drizzle ORM migrations to your database. Migrations are idempotent — already-applied migrations are skipped.
Options:
| Flag | Description |
|---|---|
--target <stage> | Target a specific stage (default: your current DEVSTRIDE_STAGE) |
When you modify a database schema:
backend/src/modules/notification/infrastructure/persistence/notification.sql-entity.tscd backend && pnpm generate-sql
backend/drizzle/.ds db migrate
ds local run backend
Neon branches are automatically provisioned by the tooling. You don't need to create or delete branches manually.
ds setup creates your local branch (dev-{developer}-local) from main and writes the connection string to .envds deploy up (CI) creates a separate branch for each cloud stage (dev-{developer}-{branch}) and stores credentials in Secrets Managerds deploy down tears down the cloud branch along with all other cloud stage resourcesYour local branch (dev-{developer}-local) is independent from cloud branches. Running ds db migrate locally applies migrations to your local branch. Cloud deployments run their own migrations against their own branches.
For branch inspection and cleanup, use ds db status and ds db audit.
ds db status
Shows your active Neon branch, connection details, and environment info.
Options:
| Flag | Description |
|---|---|
--target <stage> | Check a specific stage |
--json | Machine-readable JSON output |
ds db reset
Resets your Neon branch to match the main branch, then re-applies all migrations. This is the cleanest way to get fresh staging data.
What happens:
main branch snapshot (Neon copy-on-write).env update needed)Options:
| Flag | Description |
|---|---|
--target <stage> | Target a specific stage (default: your current DEVSTRIDE_STAGE) |
When to use:
ds db reset is blocked on dev and prod. It requires explicit confirmation before executing.ds db refresh-staging
This is an admin operation that refreshes the main Neon branch with production data:
main branchOptions:
| Flag | Description |
|---|---|
-o, --organization <id> | Organization ID to copy (default: demo organization) |
Use this when staging data has drifted too far from production, or when you need realistic data for testing.
ds db audit
An interactive explorer that cross-references Neon branches with Pulumi stacks:
d to delete a stale branchOptions:
| Flag | Description |
|---|---|
--json | Machine-readable output |
When to use:
ds deploy downHere's how database branches fit into the development lifecycle:
| Phase | Command | What Happens |
|---|---|---|
| Setup | ds setup | Creates your Neon branch from main automatically |
| Schema change | pnpm generate-sql then ds db migrate | Generates and applies migration |
| Fresh data | ds db reset | Resets branch to main data + re-applies migrations |
| Quick check | ds db status | Shows which Neon branch you're on |
| Cleanup | ds db audit | Find and delete stale/orphaned branches |
| Staging refresh | ds db refresh-staging | Refreshes main with latest prod data |