State Management
Oxid stores infrastructure state in a real database - SQLite for local development, PostgreSQL for teams. State is queryable with SQL, versioned with history, and supports concurrent access.
Overview
Unlike Terraform, which stores state in a single JSON file, Oxid uses a relational database. This gives you:
- SQL queries - Query your infrastructure with standard SQL
- Built-in history - Every change is recorded automatically
- Concurrent access - Multiple operations can read state simultaneously
- No state locking issues - Database transactions handle concurrency
- Structured storage - Resources, outputs, dependencies, and runs are stored in separate tables
SQLite (Default)
By default, Oxid creates a SQLite database at .oxid/oxid.db. This is perfect for individual use and local development.
$ oxid init # Creates .oxid/oxid.db $ oxid query "SELECT COUNT(*) FROM resources" +----------+ | COUNT(*) | +----------+ | 24 | +----------+
oxid init.PostgreSQL (Teams)
For team workflows, set the OXID_DATABASE_URL environment variable to use PostgreSQL:
export OXID_DATABASE_URL="postgresql://user:pass@host:5432/oxid_state" oxid init
PostgreSQL provides:
- Shared state across team members
- Encrypted sensitive outputs via pgcrypto
- Full PostgreSQL query capabilities
- Connection pooling for concurrent access
See PostgreSQL Backend for detailed setup.
Database Tables
resources
All managed resources with their current attributes, provider, and status.
oxid query "SELECT address, type, status FROM resources LIMIT 5"
outputs
Output values defined in your configuration, evaluated during apply.
oxid query "SELECT name, value, sensitive FROM outputs"
runs
History of plan and apply operations with timestamps and resource counts.
oxid query "SELECT id, action, created, resources_changed FROM runs ORDER BY created DESC LIMIT 5"
dependencies
Resource dependency edges used to build the execution graph.
oxid query "SELECT source, target FROM dependencies WHERE source = 'aws_vpc.main'"
resource_history
Timestamped record of every resource change, including before/after diffs.
oxid query "SELECT address, action, created_at FROM resource_history ORDER BY created_at DESC LIMIT 10"
State Operations
Oxid provides several commands for working with state:
oxid state- List, show, move, and remove resourcesoxid query- Execute SQL against the state databaseoxid import- Import resources from Terraform stateoxid sync- Sync from Terraform remote backendoxid history- View resource change history
Backup and Recovery
SQLite backup
# Simple file copy cp .oxid/oxid.db .oxid/oxid.db.backup # Or use SQLite's backup command sqlite3 .oxid/oxid.db ".backup backup.db"
PostgreSQL backup
pg_dump -t 'oxid_*' $OXID_DATABASE_URL > oxid_state_backup.sql