Production databases on macOS
Butler DB runs your production databases on your Macs and keeps them safe: scheduled backups to disk, S3 and SFTP, automatic test restores so you know they work, users and grants without the SQL, and every server managed from one app over SSH.
Full and incremental backups, every incremental taken against the last full, so a restore is always one full plus at most one incremental.
After every scheduled full backup, Butler DB restores it into a throwaway server, recovers it and runs queries against it, so you know the backup works before you need it.
An external drive, any S3-compatible storage (AWS, R2, B2, MinIO) and SFTP to another Mac or a NAS, all at once. Every copy can drive a restore on its own.
Create users, change passwords and give each one read-only, read-write or admin access per database. Every level shows the exact privileges it grants.
Save every Butler DB server and manage it over SSH with your own keys and ~/.ssh/config. Group them, give each a name and icon, and see their health at a glance.
Import existing DBngin databases. Only the instance being moved is stopped, it's copied cleanly, and it's checked for collation problems first.
Our own builds, signed and checksummed, and installed side by side. Installing a new version never touches a running database.
Native incremental backups with pg_basebackup and pg_combinebackup. TLS, lz4/zstd, every contrib module, pgvector and pg_cron. ICU pinned per build.
Hot backups with Percona XtraBackup, which we build for macOS ourselves. Keeps mysqlbinlog and the server tools a production install needs.
Every server runs in UTC, set on the engine's command line so no config file can change it. Timestamps mean the same thing on every machine.
Butler DB holds your production data, so here's exactly what it does on your Mac.
Every database runs as its own launchd job, not as a child of Butler DB. Updating the app, restarting the daemon or a daemon crash never stops a running database.
Jobs start as root just long enough to set up, then drop permanently to a dedicated _butlerdb account. Data directories owned by anyone else are refused.
The app talks to the daemon over a local socket that only administrators can open. Remote servers are reached over your own SSH, so there's nothing new to expose.
The engine list is signed, and every download is checked against its SHA-256 before it's unpacked. A tampered list or file installs nothing.
Nothing leaves the Mac except the backups you send to your own destinations. Storage secrets stay readable only by the service account and never end up in logs.
A restore always creates a new instance next to the original. It never writes over a database you have.
Everything the app does is a butlerdb command, with --json for scripts.
From download to a tested backup in about ten minutes.
Drag Butler DB into Applications and open it. It asks to add its background service; approve it in System Settings → General → Login Items & Extensions. It shows up there as Butler DB.
Install an engine from the Engines window, then add a database instance. Coming from DBngin? Import it instead, and keep its data and logins.
Add one or more destinations: a drive, an S3 bucket, or another machine over SFTP. Then set each instance's policy: where its backups go, how often fulls and incrementals run, and how many to keep.
Press Test Restore. Butler DB restores the newest backup into scratch space, recovers it and queries it. Scheduled fulls are tested automatically after that.
Install Butler DB on each server Mac. Make sure ssh <host> works from your Mac with a key, logging in as an administrator on the server. Then use Add Server. Hosts from ~/.ssh/config work as-is.
sudo fdesetup authrestart skips that.