Sync any database, anywhere.
A single binary that turns the painful, error-prone sprawl of pg_dump → pg_restore shell scripts into a guided, observable workflow — with named profiles, integrity-checked dumps, and server-to-server streaming, across multiple database engines.
Warning
Pre-1.0 — active development. Postgres backup/restore/sync/verify/inspect work end-to-end today (Phase B), and bare siphon opens an interactive multi-panel dashboard (Phase C). The driver layer is hardened with a shared cross-driver test harness, capability gating, and connection retry (Phase D), so MySQL/MariaDB can land mechanically next. MySQL/MariaDB, incremental backups, and ops features are on the roadmap. APIs, flags, and the on-disk dump format may change before 1.0. Track progress via the milestone tags (phase-a, phase-b, phase-c, phase-d, …).
- One CLI, many databases. Postgres works today; MySQL and MariaDB land in v1.0 (sharing a common backend). The driver interface is engine-agnostic, so SQLite, MongoDB, SQL Server, and ClickHouse can follow.
- Native, not reimplemented. siphon shells out to
pg_dump/pg_restore(andmysqldump/mariadb-dumpin v1.0) for the actual data movement — you inherit 20+ years of correctness from the official tools, wrapped in a consistent UX. - Integrity by default. Every dump is checksummed (SHA-256) and recorded in a sidecar metadata file.
siphon verifyre-hashes the dump and flags corruption or tampering — and fails with a distinct exit code so CI can catch it. - Built for scripts and humans. A Cobra command tree with predictable flags and POSIX exit codes for automation; an interactive Bubble Tea dashboard when you invoke
siphonbare. - Named profiles + secret refs. Store connection details once; reference secrets as
env:VARtoday, with OS keychain / Vault / 1Password / AWS Secrets Manager backends on the roadmap. Plaintext passwords never have to live in your config. - Streaming sync.
siphon sync src dstpipes a backup straight into a restore with no intermediate file on disk.
| Phase | What it delivers | Status |
|---|---|---|
| A — Skeleton | Go module, Cobra CLI, TUI placeholder, Driver interface + registry, errs/config/secrets/profile packages, golangci-lint + depguard, cross-platform CI |
✅ Complete |
| B — Postgres walking skeleton | backup, restore, sync, verify, inspect, dumps, config, profile working end-to-end against PostgreSQL |
✅ Complete |
| C — TUI dashboard | Multi-panel Bubble Tea dashboard (profiles · dumps · jobs) with live job progress, backup/restore modal forms, and snapshot tests | ✅ Complete |
| D — Driver hardening | Shared cross-driver test harness (RunDriverSuite), capability-gating helper (RequireCapability), Postgres connection-probe retry, and a docs/DRIVERS.md contributor guide |
✅ Complete |
| E — MySQL + MariaDB | Both drivers via a shared _mysqlcommon package |
⏳ Planned |
| F — Advanced transfer | Incremental backups, bounded-buffer streaming, cross-engine sync, CDC | ⏳ Planned |
| G — Ops features | Cloud storage, secret backends, profile groups + 2FA, team mode, audit log, retention, telemetry | ⏳ Planned |
| H — Distribution | GoReleaser, Homebrew tap, Scoop bucket, install script, docs site | ⏳ Planned |
-
Go 1.26 or newer — to build from source (the only install method until Phase H).
-
PostgreSQL client tools —
pg_dump,pg_restore, andpsqlmust be on yourPATH. siphon shells out to them; it does not embed a Postgres client.Platform Install macOS brew install postgresql@16Debian/Ubuntu sudo apt install postgresql-clientFedora/RHEL sudo dnf install postgresqlWindows Install the EDB PostgreSQL package and add its bin/toPATH -
Docker (optional) — only needed to run the integration test suite (
make test-integration).
Pre-1.0: no Homebrew tap or prebuilt binaries yet. Build from source.
git clone https://github.com/nixrajput/siphon.git
cd siphon
make build
./bin/siphon --versionThis produces ./bin/siphon. Move it onto your PATH (e.g. sudo install -m 0755 bin/siphon /usr/local/bin/siphon) to call it as siphon.
# 1. Register a connection profile (secrets via env: refs, never plaintext in config)
export PROD_DB_PASS='…'
siphon profile add prod \
--driver postgres \
--host db.example.com \
--user app_user \
--password 'env:PROD_DB_PASS' \
--database app_prod \
--sslmode require
siphon profile list # show saved profiles
# 2. Inspect the schema (tables, row estimates, on-disk sizes)
siphon inspect prod
# 3. Back it up — written to ~/.local/share/siphon/dumps/ with a checksummed sidecar
siphon backup prod
siphon dumps list # newest first
# 4. Verify integrity (re-hashes the dump against the recorded checksum)
siphon verify <dump-id>
# 5. Restore into another profile
siphon restore --profile staging --dump <dump-id> --clean
# 6. Stream prod → staging directly, no intermediate file
siphon sync prod stagingExit codes follow a POSIX-friendly taxonomy (0 ok, 1 user error, 2 system error, 3 integrity failure, 130 cancelled) so siphon backup prod && upload and CI pipelines behave correctly.
| Command | Description |
|---|---|
siphon backup [profile] |
Dump a database to a checksummed file in the catalog |
siphon restore [dump-id] |
Load a dump into a database (--clean to drop-and-recreate) |
siphon sync [from] [to] |
Backup + restore in one streamed pass |
siphon verify <dump-id> |
Re-hash a dump and check it against its recorded checksum |
siphon inspect <profile> |
Show tables, row estimates, and sizes for a profile |
siphon dumps list|inspect|prune |
List, inspect, or prune saved dumps |
siphon profile add|list|show|rm |
Manage named connection profiles |
siphon config path|edit |
Show or edit the config file |
siphon schedule |
Cron-managed recurring backups (Phase G) |
siphon tunnel |
SSH tunnel helper (Phase G) |
siphon (bare) |
Launch the interactive multi-panel dashboard |
Run siphon <command> --help for full flags.
siphon reads a YAML config from an XDG-compliant path. Find it with siphon config path:
- Linux:
$XDG_CONFIG_HOME/siphon/config.yaml→~/.config/siphon/config.yaml - macOS:
~/.config/siphon/config.yaml - Windows:
%APPDATA%\siphon\config.yaml
Override the location with SIPHON_CONFIG_HOME. A profile entry looks like:
version: 1
defaults:
dump_dir: ~/.local/share/siphon/dumps # where backups + sidecars are stored
jobs: 4
profiles:
prod:
driver: postgres
host: db.example.com
port: 5432
user: app_user
password: env:PROD_DB_PASS # resolved from $PROD_DB_PASS at runtime
database: app_prod
sslmode: requireSecret references (env:VAR) are resolved at runtime, so the config file is safe to commit. Plain values are also accepted.
siphon is a strictly layered Go application; imports flow downward only, enforced at lint time by golangci-lint's depguard (an upward import fails CI):
cmd/siphon entry point (one-line main)
│
internal/cli internal/tui presentation (Cobra · Bubble Tea) — siblings
└──────┬───────┘
internal/app application verbs (backup, restore, sync, …)
│
internal/driver/<engine> database adapters (postgres; mysql/mariadb in v1.0)
│
config · secrets · profile · dumps · jobs · errs domain + support packages
- Drivers are compile-time Go packages that shell out to native tools for data movement and use a client library (pgx) for fast schema reads.
- Dumps live on disk as
<id>.dumpwith a<id>.meta.jsonsidecar (profile, driver, size, SHA-256 checksum, timestamp). - Jobs run long operations on a goroutine and stream progress
Events that the CLI heartbeat (and, later, the TUI) renders.
make help # list all targets
make build # produce ./bin/siphon
make run # go run ./cmd/siphon (launches the TUI on bare invoke)
make test # unit tests
make test-integration # integration tests against a real Postgres (needs Docker)
make lint # golangci-lint, incl. depguard layer enforcement
make tidy # go mod tidy
make clean # remove bin/ and dist/Tests run race-clean (go test -race ./...). The integration suite is gated behind the integration build tag and spins up postgres:16-alpine via testcontainers.
See CONTRIBUTING.md for the full contributor guide and SECURITY.md for reporting vulnerabilities.
v1.0 targets a single mega-release covering four pillars:
- Foundation — the CLI, TUI, profiles, config, and dump catalog (Phases A–C).
- Drivers — Postgres, MySQL, and MariaDB (Phases D–E).
- Advanced transfer — incremental backups, native server-to-server streaming, cross-engine sync, and CDC (Phase F).
- Ops — cloud storage (S3/GCS/Azure), multi-backend secrets, profile groups, team mode, audit log, retention policies, and opt-in telemetry (Phase G).
Distribution (Homebrew, Scoop, install script, signed release binaries) lands in Phase H alongside the 1.0 tag.
Contributions are welcome. Please read CONTRIBUTING.md, keep changes within the layered architecture (depguard will tell you if you stray), and make sure make test and make lint pass before opening a PR.
Adding a new database engine? See docs/DRIVERS.md for the driver contributor guide.