db-rotator
v1.0.1
Published
Config-based database rotation and migration tool for Neon and Supabase.
Maintainers
Readme
db-rotator

db-rotator is a config-based database rotation and migration tool that can automatically:
- Create a new Postgres project on your cloud provider
- Dump your existing database
- Restore data into the new project
- Update your
.envconnection strings - Restart your app
It is provider-agnostic and currently supports:
- Neon
- Supabase
You can use it both as:
- A CLI:
db-rotator rotate - A Node.js SDK: import and call from your own scripts
Problem
Managed Postgres services often have free-tier limits (storage, network transfer, etc.). When you hit those limits, you may want to:
- Spin up a fresh project
- Move all data into the new project
- Point your app at the new database with minimal downtime
Doing this manually for each provider is error-prone and repetitive.
Solution
db-rotator provides:
- A simple config file (
rotator.config.json) to define which provider to use and how to restart your app - A core rotation engine that:
- Creates a new project
- Dumps your existing DB
- Restores into the new DB
- Updates
.env - Restarts your server
- Pluggable providers (
Neon,Supabase) with the same interface:createProject()getConnectionStrings()
Installation
Install from npm:
npm install db-rotatorOr with pnpm / yarn:
pnpm add db-rotator
# or
yarn add db-rotatordb-rotator expects:
- Node.js 18+ recommended
- Postgres CLI tools on
PATH:pg_dumppsql
On Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y postgresql-clientCLI Usage
Initialize config
npx db-rotator initThis creates a default rotator.config.json in the current directory.
You can choose provider explicitly:
npx db-rotator init neon
npx db-rotator init supabaseRotate database
npx db-rotator rotateWhat happens:
- Reads
rotator.config.json - Uses the configured provider to create a new project
- Reads current
DATABASE_URLandDATABASE_URL_UNPOOLEDfrom.env - Runs
pg_dumpagainstDATABASE_URL_UNPOOLED - Restores into the new project using
psql - Updates
.envwith newDATABASE_URL+DATABASE_URL_UNPOOLED - Runs your configured
restartCommand(e.g.pm2 restart all)
Monitor database size
npx db-rotator monitorThis command:
- Reads
DATABASE_URL_UNPOOLEDfrom.env - Connects to Postgres
- Prints
pg_database_size(current_database())in MB
Works for any Postgres (Neon, Supabase, self-hosted) as long as the DSN is valid.
Configuration
Configuration file: rotator.config.json
Neon example
{
"provider": "neon",
"projectNamePrefix": "auto-db",
"region": "aws-us-east-1",
"restartCommand": "pm2 restart all"
}Supabase example
{
"provider": "supabase",
"organizationId": "org-id",
"projectNamePrefix": "auto-db",
"region": "us-east-1",
"restartCommand": "pm2 restart all"
}Environment variables (.env)
db-rotator uses dotenv and requires:
DATABASE_URL: current pooled URL (Prisma-style)DATABASE_URL_UNPOOLED: current direct URL (used forpg_dump)NEON_API_KEY: required whenprovider = "neon"SUPABASE_ACCESS_TOKEN: required whenprovider = "supabase"
Example .env:
DATABASE_URL="postgresql://user:pass@host/db?pgbouncer=true&connection_limit=1&sslmode=require"
DATABASE_URL_UNPOOLED="postgresql://user:pass@host/db?sslmode=require"
NEON_API_KEY="napi_xxx"
SUPABASE_ACCESS_TOKEN="sbp_xxx"Security:
- Keep
.envout of version control.
Providers
Neon provider
File: src/providers/neon.ts
- Uses Neon API:
POST https://console.neon.tech/api/v2/projects- Follows up with branch/role/database queries
- Fetches a connection URI
- Returns Prisma-style URLs:
DATABASE_URL(pgbouncer pooled)DATABASE_URL_UNPOOLED(direct)
Supabase provider
File: src/providers/supabase.ts
- Uses Supabase Management API:
POST https://api.supabase.com/v1/projectsto create a projectGET https://api.supabase.com/v1/projects/{ref}to fetch connection details
- Constructs Prisma-style URLs:
DATABASE_URL(pgbouncer-compatible)DATABASE_URL_UNPOOLED(direct)
Both providers expose the same interface:
createProject(config)getConnectionStrings(config, projectIdOrRef)
Core rotation engine
File: src/core/rotate.ts
Responsibilities:
- Read config (
rotator.config.json) - Load env (
.envviadotenv) - Validate required env vars and binaries (
pg_dump,psql) - Create a new project via the selected provider
- Dump old DB (
pg_dump) - Restore into new DB (
psql) - Update
.env(DATABASE_URL,DATABASE_URL_UNPOOLED) - Restart server using
restartCommand
Utilities:
src/utils/dump.ts– runspg_dump ... > dump-<timestamp>.sqlsrc/utils/restore.ts– runspsql ... < dump.sqlsrc/utils/updateEnv.ts– backs up.envand rewrites only the DB URLs
Logs during rotation:
Creating new project...New project created.Dumping database...Dump completeRestoring database...Restore completeUpdating env...Env updated.Restarting server...Restart complete.Rotation finished successfully.
SDK Usage (Node.js)
You can also use db-rotator programmatically:
import { rotate } from "db-rotator";
await rotate(); // uses rotator.config.json in CWDYou can also access the providers directly:
import { neonProvider, supabaseProvider } from "db-rotator";
// Neon
const neonConfig = {
provider: "neon" as const,
projectNamePrefix: "auto-db",
region: "aws-us-east-1"
};
const neonProjectId = await neonProvider.createProject(neonConfig);
const neonConns = await neonProvider.getConnectionStrings(neonConfig, neonProjectId);Safety & rollback
- Old databases are never deleted by
db-rotator. - Before updating
.env, the tool creates:.env.bak-<timestamp>
- Dumps are written as:
dump-<timestamp>.sql
To rollback:
- Restore previous
.env:
cp .env.bak-<timestamp> .env- Restart your app:
pm2 restart all