Docs
Snapshots and sync
Save a site's files and database in seconds, restore them, and pull from production or push to staging over SSH, SFTP or FTP.
Snapshots
A snapshot saves a site’s project folder and its database, so you can try a plugin update, a migration or an import and go back if it goes wrong.
benbow snapshot create shop --note "before the plugin update"
benbow snapshot list shop
benbow snapshot restore shop 20261103-124501.123 # asks first (--yes)
benbow snapshot delete shop 20261103-124501.123
In the app: the site’s Advanced section → Snapshots.
What a snapshot contains
The project folder is cloned with APFS clones, so a snapshot takes almost no space until files change. .git and node_modules folders, at any depth, are left out: restoring never rewinds your git history or installed packages. If the site lives on a disk without APFS clones, or on a different disk than Benbow’s folder, the files are copied instead, which takes longer and uses space.
If the site has a database, it is saved too: a MySQL dump or a PostgreSQL dump.
Snapshots live in ~/Library/Application Support/benbow/, never in your project folder.
Restoring
Before restoring, Benbow takes a pre-restore snapshot of the current state. Then it puts the snapshot’s files back, keeps your current .git and node_modules, and reloads the database. If any step fails, the folder and the database are put back as they were. To undo a restore, restore the pre-restore snapshot.
How many are kept
Benbow keeps the newest 10 snapshots per site. Change it in Settings → General → Snapshots, or:
benbow snapshot keep 20
Benbow also takes snapshots by itself before a pull, before applying a blueprint and during an AI agent session. An agent session’s snapshots do not count toward the limit while the session is open. Removing a site deletes its snapshots.
Production and staging
A remote is a copy of your site on a server. It is either production, which you can only pull from, or staging, which you can pull from and push to. Benbow never pushes to production.
benbow remote set shop --kind production --host example.com --user deploy \
--path /var/www/shop --url https://shop.example.com
benbow remote set shop --kind staging --name stage --transport sftp \
--host stage.example.com --user deploy --path /www/shop --password
benbow remote show shop
benbow remote remove shop stage
--path is the project folder on the server. For a Laravel site on a host without SSH, add --webroot public. By default Benbow syncs wp-content/uploads for WordPress, storage/app/public for Laravel, or the whole project for other sites; --paths and --exclude change that. .git, node_modules, .DS_Store and cache are never synced by default.
In the app: the site’s Advanced section → Production and staging, with Pull… and Push…. Both show what will change before doing anything.
Transports
| Transport | Login | Files | Database |
|---|---|---|---|
ssh (default) |
your SSH keys, ssh-agent and ~/.ssh/config |
rsync | the server’s wp-cli, or mysqldump with the credentials in the remote wp-config.php or .env |
sftp |
same, for hosts with SFTP but no shell | SFTP | the PHP bridge |
ftps, ftp |
user and password | FTP | the PHP bridge |
Plain ftp sends your password unencrypted, and Benbow warns you about it. Prefer ftps or sftp.
Benbow uses macOS’s own ssh and rsync and never creates or changes ~/.ssh. A new host key is accepted the first time; a changed one is refused.
Credentials
--password asks for the password on the terminal and keeps it in your login keychain. It is never passed as a command argument. --no-password forgets it. Database credentials read from the server are used for that run only and never stored.
Pull
benbow pull shop # from "production"
benbow pull shop stage --dry-run # show what would change
benbow pull shop --no-files # database only (or --no-database)
A pull works in this order:
- A
pre-pullsnapshot of the local site. Restore it to undo the pull. - The synced folders are downloaded. Nothing local is deleted.
- The remote database replaces the local one, created if the site has none.
- For WordPress, the remote address is replaced with your local one by
wp search-replace, which handles serialized data.
If the database download stops half way, the pull fails and you can restore the snapshot.
Push to staging
benbow push shop stage --dry-run
benbow push shop stage # asks first (--yes)
Benbow takes a snapshot of the local site, uploads the changed files in the synced folders, and replaces the staging database with yours, with the local address converted to the staging one. Your local database is not changed by the conversion.
The PHP bridge
Some hosts give you files over SFTP or FTP but no shell to export the database. For those, Benbow uploads a small PHP file with a random name into the site’s web folder and talks to it over HTTPS with a secret one-time token. The file reads the database settings from wp-config.php or .env, answers only requests that carry the token, stops working after 10 minutes and deletes itself. Benbow also deletes it as soon as it is done, whatever happens.
Some hosts block new PHP files with a firewall. Benbow then tells you the bridge did not answer.
Limits
--dry-run changes nothing and takes no snapshot. PostgreSQL sites cannot be synced yet.