Skip to main content

Overview

DBOS provides CLI commands for managing database schemas, running migrations, and administering the DBOS system database.

dbos migrate

Create DBOS system tables and run application-specific migrations.
dbos migrate [OPTIONS]

Options

--db-url
string
Application database URL. Overrides application_database_url from configuration.
--sys-db-url
string
System database URL. Overrides system_database_url from configuration.
--app-role
string
PostgreSQL role to grant permissions to. Only applicable for PostgreSQL databases.When specified, DBOS grants all necessary permissions on system tables to this role.
--schema
string
default:"dbos"
Schema name for DBOS system tables.

What It Does

  1. Creates DBOS system tables in the system database
  2. Creates DBOS application tables (if application database is configured)
  3. Grants permissions to the specified role (PostgreSQL only)
  4. Runs custom migrations from dbos-config.yaml

Database Schema Structure

DBOS creates these tables in the system schema: System Database Tables:
  • workflow_status - Workflow execution state and metadata
  • workflow_inputs - Serialized workflow input parameters
  • workflow_outputs - Serialized workflow results
  • operation_outputs - Step-level outputs for recovery
  • workflow_events - Event and notification queues
  • workflow_queue - Enqueued workflows
  • scheduled_workflows - Scheduled workflow definitions
  • migrations - Schema version tracking
Application Database Tables (if configured):
  • migrations - Application migration tracking

Examples

Basic migration:
dbos migrate
Starting DBOS migrations
Application database: postgresql://localhost/myapp
System database: postgresql://localhost/myapp_dbos
DBOS system schema: dbos
With explicit database URLs:
dbos migrate \
  --sys-db-url postgresql://localhost/prod_dbos \
  --db-url postgresql://localhost/prod_app
Grant permissions to application role:
dbos migrate --app-role myapp_user
Starting DBOS migrations
System database: postgresql://localhost/myapp_dbos
DBOS system schema: dbos
Granting permissions for the dbos schema to myapp_user in database postgresql://localhost/myapp_dbos
GRANT USAGE ON SCHEMA "dbos" TO "myapp_user"
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA "dbos" TO "myapp_user"
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA "dbos" TO "myapp_user"
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "dbos" TO "myapp_user"
Custom schema name:
dbos migrate --schema custom_dbos

Custom Application Migrations

Define custom migration commands in dbos-config.yaml:
dbos-config.yaml
database:
  migrate:
    - alembic upgrade head
    - python scripts/seed_data.py
These commands run after DBOS system migrations complete. Example output:
dbos migrate
Starting DBOS migrations
System database: postgresql://localhost/myapp_dbos
DBOS system schema: dbos
Executing migration commands from 'dbos-config.yaml'
Executing migration command: alembic upgrade head
INFO  [alembic.runtime.migration] Running upgrade -> 001, initial schema
INFO  [alembic.runtime.migration] Running upgrade 001 -> 002, add user table
Executing migration command: python scripts/seed_data.py
Seeded 100 initial records

dbos reset

Reset the DBOS system database, deleting all workflow history and metadata.
dbos reset [OPTIONS]
This command permanently deletes all data in the DBOS system database:
  • Workflow execution history
  • Workflow inputs and outputs
  • Queued workflows
  • Scheduled workflows
  • Event queues
Application data in the application database is not affected.

Options

--yes
boolean
Skip confirmation prompt and reset immediately.
--db-url
string
Application database URL.
--sys-db-url
string
System database URL to reset.

Examples

Interactive reset (with confirmation):
dbos reset
This command resets your DBOS system database, deleting metadata about past workflows and steps. Are you sure you want to proceed? [y/N]: y
Resetting system database...
System database reset successfully.
Non-interactive reset:
dbos reset --yes
Reset specific database:
dbos reset --sys-db-url postgresql://localhost/test_dbos --yes

When to Use Reset

Development:
  • Clear test data between runs
  • Reset after changing serialization formats
  • Clean up after experiments
Testing:
  • Ensure clean state for integration tests
  • Reset between test suites
After resetting, you must run dbos migrate to recreate the system tables.

dbos postgres

Manage a local PostgreSQL database using Docker.

dbos postgres start

Start a local PostgreSQL instance in Docker.
dbos postgres start
What it does:
  • Pulls PostgreSQL 16 Docker image (if not present)
  • Creates a persistent volume dbos_postgres_data
  • Starts container named dbos-postgres
  • Exposes port 5432
  • Sets default credentials: postgres:dbos
Example output:
dbos postgres start
Starting PostgreSQL with Docker...
PostgreSQL is now running on port 5432
Connection string: postgresql://postgres:dbos@localhost:5432/postgres
Connect to the database:
psql postgresql://postgres:dbos@localhost:5432/postgres

dbos postgres stop

Stop the local PostgreSQL Docker container.
dbos postgres stop
Example output:
Stopping PostgreSQL container...
PostgreSQL stopped.
Data is preserved in the dbos_postgres_data volume. Starting again will restore your databases.

Database URL Formats

SQLite

For development and testing:
# Absolute path
dbos migrate --sys-db-url sqlite:////absolute/path/to/database.sqlite

# Relative path (recommended)
dbos migrate --sys-db-url sqlite:///./myapp.sqlite

PostgreSQL

For production:
dbos migrate --sys-db-url postgresql://username:password@hostname:port/database
With query parameters:
dbos migrate --sys-db-url "postgresql://user:pass@host:5432/db?connect_timeout=10&sslmode=require"
Common parameters:
  • connect_timeout - Connection timeout in seconds
  • sslmode - SSL mode (require, prefer, disable)
  • application_name - Application name in pg_stat_activity

Permissions Management

When using PostgreSQL with separate database users for migrations and runtime, use the --app-role option.

Role-Based Access Pattern

1. Create roles:
-- Admin role for migrations
CREATE ROLE dbos_admin WITH LOGIN PASSWORD 'admin_password';

-- Application role for runtime
CREATE ROLE dbos_app WITH LOGIN PASSWORD 'app_password';

-- Create databases
CREATE DATABASE myapp_dbos OWNER dbos_admin;
CREATE DATABASE myapp OWNER dbos_admin;
2. Run migration as admin:
dbos migrate \
  --sys-db-url postgresql://dbos_admin:admin_password@localhost/myapp_dbos \
  --db-url postgresql://dbos_admin:admin_password@localhost/myapp \
  --app-role dbos_app
3. Run application as limited user:
dbos-config.yaml
name: myapp
system_database_url: postgresql://dbos_app:app_password@localhost/myapp_dbos
application_database_url: postgresql://dbos_app:app_password@localhost/myapp

Granted Permissions

When --app-role is specified, DBOS grants:
  • USAGE on the DBOS schema
  • ALL PRIVILEGES on all tables
  • ALL PRIVILEGES on all sequences
  • EXECUTE on all functions
  • Default privileges for future objects

Migration Patterns

Development Setup

# 1. Start local PostgreSQL
dbos postgres start

# 2. Create development database
psql postgresql://postgres:dbos@localhost:5432/postgres -c "CREATE DATABASE myapp_dev;"

# 3. Run migrations
dbos migrate --sys-db-url postgresql://postgres:dbos@localhost:5432/myapp_dev_dbos

CI/CD Pipeline

.github/workflows/test.yml
steps:
  - name: Start PostgreSQL
    run: dbos postgres start
  
  - name: Run migrations
    run: dbos migrate --sys-db-url postgresql://postgres:dbos@localhost:5432/test_dbos
  
  - name: Run tests
    run: pytest
  
  - name: Cleanup
    run: dbos postgres stop

Production Deployment

#!/bin/bash
set -e

# Run migrations with admin credentials
dbos migrate \
  --sys-db-url "$ADMIN_SYSTEM_DB_URL" \
  --db-url "$ADMIN_APP_DB_URL" \
  --app-role production_app

# Start application with limited credentials
export DBOS_SYSTEM_DATABASE_URL="$APP_SYSTEM_DB_URL"
export DBOS_DATABASE_URL="$APP_DATABASE_URL"
dbos start

Multi-Environment Setup

# config/dev.yaml
name: myapp
system_database_url: postgresql://localhost/myapp_dev_dbos
application_database_url: postgresql://localhost/myapp_dev

# config/staging.yaml  
name: myapp
system_database_url: postgresql://staging-db/myapp_dbos
application_database_url: postgresql://staging-db/myapp

# config/prod.yaml
name: myapp
system_database_url: postgresql://prod-db/myapp_dbos
application_database_url: postgresql://prod-db/myapp
# Migrate each environment
DBOS_CONFIG=config/dev.yaml dbos migrate
DBOS_CONFIG=config/staging.yaml dbos migrate
DBOS_CONFIG=config/prod.yaml dbos migrate

Alembic Integration

DBOS works well with Alembic for application schema migrations.

Setup

1. Initialize Alembic:
pip install alembic
alembic init alembic
2. Configure Alembic to use DBOS database URL:
alembic/env.py
from dbos import load_config

config_file = load_config()
app_db_url = config_file.get("database_url")

config.set_main_option("sqlalchemy.url", app_db_url)
3. Add to dbos-config.yaml:
database:
  migrate:
    - alembic upgrade head
4. Create and run migrations:
# Create migration
alembic revision -m "add users table"

# Edit the generated migration file
# Then run DBOS migrate
dbos migrate

Troubleshooting

Migration Failures

Permission denied:
ERROR: permission denied for schema dbos
Solution: Run migration with admin credentials or use --app-role to grant permissions. Connection timeout:
ERROR: could not connect to server: Connection timed out
Solution: Check database URL, network connectivity, and firewall rules. Schema already exists:
ERROR: schema "dbos" already exists
Solution: This is usually safe to ignore. DBOS migrations are idempotent.

Reset Issues

Cannot connect after reset: Solution: Run dbos migrate to recreate system tables. Foreign key violations: Solution: Reset only affects the system database. Application database foreign keys to system tables may need to be recreated.

See Also

Build docs developers (and LLMs) love