What sloop is
sloop is a free, open-source database backup and migration tool for the command line. One binary registers your databases once, then backs them up, restores them, mirrors them, syncs them, reads them, and keeps all of that on a schedule. It speaks PostgreSQL, MySQL and MariaDB, and it runs on Windows, Linux and macOS, on x86-64 and on aarch64. There is no agent to deploy, no server to run and no account to make, and it is MIT or Apache-2.0 licensed.
It has two surfaces and one implementation. sloop on its own opens an interactive menu covering every command; every flag a scheduler would use runs the same function that menu calls, so the two cannot drift apart. Every finished run lands on a screen that says what it did — the steps it took, ticked, and the flag form of what just ran — which is how a session you worked out by hand becomes a line you can put in a script.
Underneath, it drives the client tools your database vendor ships — pg_dump, pg_restore, mysqldump, mariadb-dump — so what goes into a backup is an ordinary dump in the format those tools produce, with an age encryption layer over it that sloop restore takes back off. What it adds is everything around them: where the backup went, whether every row actually arrived, what the password was and where it came from, when the next run is due, and what to delete when the disk fills up.
Work happens against a registry — the set of databases sloop knows about. There is one global registry and as many project registries as you like, found by walking up from the working directory the way git finds .git. A password is never in a registry: a record holds a route to one — the operating system's keyring, an Argon2id-encrypted file, an environment variable, or a command to run — and never a value.
What you can do with it
Each of these is one command, and each has a page below that shows the command with its real output.
- Back up a PostgreSQL, MySQL or MariaDB database from the command line on Windows, Linux or macOS — and have every row counted on both sides before the run calls itself finished.
- Schedule nightly database backups without cron, without a systemd timer and without a Task Scheduler entry. sloop registers itself with the machine's own service manager and does the work with nobody logged in.
- Keep a retention policy — the newest seven, or nothing older than thirty days — and have the old ones pruned automatically, but only ever after a backup that worked.
- Restore a database from an encrypted backup, and know before you start which backup you are restoring and what it is about to replace.
- Copy a production database into staging. Exactly, with
mirror, so the destination ends up identical — or merged, withsync, so rows the destination already had are kept. - Read a table without writing any SQL: pick the table, tick the columns, choose the test. The server is told the transaction is read-only, so nothing it runs can write.
- Check that a backup role has the grants it needs before a dump goes quietly wrong — which, on MySQL and MariaDB, is a thing that genuinely happens.
- Reach a database whose port is closed by having sloop run your own
sshand forward the connection, rather than opening a hole in a firewall. - Drive all of it from CI or a scheduler and branch on the exit code, with machine-readable output and no prompt that can ever hang a run.
Install it
One line, for the platform selected in the strip above. Both installers put the binary on PATH and both say clearly that the shell you are in has to be restarted afterwards.
$ curl -fsSL https://dbsloop.github.io/install.sh | shInstallation covers what each installer does to PATH, the options it takes, taking a release archive by hand and checking it against SHA256SUMS, and both ways to remove sloop again — neither of which ever deletes a backup.
And the claim at the top of this page is something you can check rather than something you have to accept. It takes about thirty seconds:
$ cargo tree | grep -Ei 'reqwest|hyper|ureq|curl'(no output)How these pages are arranged
The groups follow the CLI's own menu — the six doors its home screen opens on — so whichever surface you learned the tool from, the other one is already arranged the way you think. Start here and Reference are the two the menu has no equivalent of.
What people get wrong first
Four things, because each of them is easier to read here than to discover from a command that refused.
mirrorandsyncare not the same command.mirrormakes the destination identical to the source, so anything that existed only there is gone.syncmerges: rows are added, rows already there are replaced, and rows only the destination has are kept. They have different engines underneath and their own page.- Exporting the backup key is a step, not an aside. Backups are encrypted, and the first encrypted backup refuses to run until the private key has been exported or you have explicitly declined. Losing it loses every backup you have.
- Exit
6is not success and not a crash. It means the dump finished and then the row counts disagreed. A scheduler that treats every non-zero code the same will page somebody for the wrong reason. - sloop never prompts when there is no terminal. A scheduled run that hangs on a question is the worst failure this tool could have, so instead it exits
2and names the exact flag that would have answered it.
Questions people ask
How do I back up a PostgreSQL database on Windows?
Install sloop with the PowerShell one-liner above, register the database once with sloop db add, then run sloop backup <name>. Windows does not ship pg_dump, so the first run offers to fetch the official PostgreSQL binaries — checksum-verified, once, and only after you say yes. The same three steps work for MySQL and MariaDB, and they are the same three steps on Linux and macOS. Getting started walks the whole thing.
Can I schedule database backups without cron or Task Scheduler?
Yes, and that is the intended way to run it. sloop service install registers a systemd unit on Linux, a launchd daemon on macOS or a real Windows service, and sloop service schedule orders --every 1d --keep 7 is the whole of a nightly backup with a retention policy. Nothing is written to crontab, to a systemd timer or to Task Scheduler — sloop runs the same commands you would have typed, and a missed run is caught up once and labelled late rather than replayed a hundred times. The background service has the detail.
Does sloop send my database credentials anywhere?
No, and the binary is built so that it could not. There is no HTTP client anywhere in its dependency graph and no SSH client either, continuous integration fails the build if one ever appears, and the background service never opens a port. Passwords are never passed in argv, so they never appear in ps output, and a log is written to be pasteable into a public issue. Security shows how to verify all of that yourself.
What is the difference between mirror and sync?
sloop mirror source --to dest makes the destination an exact copy: anything that existed only in the destination is gone afterwards. sloop sync source --to dest merges instead — rows are added, rows already present are replaced, and rows only the destination has are kept. sync needs a primary key on every table, resets sequences and identity columns afterwards, and refuses outright on circular foreign keys. Both only ever read the source. Mirror and sync puts them side by side.
Can sloop copy a PostgreSQL database to MySQL?
No. Copying is same-engine, and a cross-engine copy is refused rather than attempted — the type systems do not map cleanly and a silent corruption is worse than a refusal. PostgreSQL to PostgreSQL, MySQL to MySQL and MariaDB to MariaDB all work, including across versions and across machines.
How do I know a backup is complete?
Every row is counted on both sides, per table, with one statement — not estimated. A planner estimate has been observed reporting double the true count, so it is available as SLOOP_VERIFY=fast, is always labelled an estimate, and is never presented as proof. A table that did not arrive at all is a failure and the run exits 6. Every backup also gets a manifest beside it recording the engine version, the size, a checksum, the duration and the per-table row counts, and sloop backups list --check re-hashes the dumps later to confirm nothing rotted. Backups and restoring has the whole of it.
Why would a MySQL dump be missing its triggers and stored routines?
Because the role taking it was short of one grant. MySQL and MariaDB will write a dump with every stored routine and every trigger missing from it, say nothing about it, and exit 0 — which is the single most dangerous thing in this area, and the reason sloop doctor exists. It checks what each registered role may actually do against the live connection and exits 8 when it finds something that will break a backup. The privileges a backup role needs lists the minimum per engine and the GRANT that fixes each one.
Is sloop free and open source?
Yes — MIT or Apache-2.0, the Rust default, and the whole source is on GitHub. There is no paid tier, no account and no hosted component, which is also why there is nothing in it that needs to contact a server.