Questions & answers
The questions we’d ask before trusting anyone with our backups.
43 answers about how the jobs actually run, where the bytes end up, and what VPS Snaps still can't do. The awkward ones are in here too.
web-01 site files
2h ago · triggered by scheduler
Status
Duration
1m 44s
Size
412 MB
Checksum (MD5)
9f2c4ab1e77d...
Storage path
files/cf7q2b1x/file-backup-cf7q2b1x-2026-09-02T02-00-06-118Z.tar.gz
Run logs
Getting started
What you need in hand before the first job runs, and how far the free plan actually gets you.
What is VPS Snaps, exactly?
A scheduler and a runner. You connect a cloud provider (for snapshots) or an SSH server (for dumps and archives), point the job at your own S3-compatible bucket, and choose a cadence. From then on our worker wakes up on schedule, does the work, writes the result to your bucket or into your provider account, and records what happened. There is no storage product to buy from us and no proprietary archive format to get locked into.
What do I need before I can run my first backup?
For a VPS snapshot: a read/write API token from DigitalOcean, Hetzner, Vultr, Linode, AWS, or Google Cloud. That is the whole list — snapshots stay in your provider account, so they need no bucket at all. For a database, Docker, or file backup: SSH access to the server (private key or password) plus an S3-compatible bucket and an access key scoped to it.
Do I have to install an agent on my servers?
Not for provider snapshots, which are pure API calls, and not for SSH jobs — we run pg_dump, mysqldump, tar, or docker over the SSH connection you already have, and nothing is installed or left behind. The one exception is the Agent, and only if you want it: a Docker container you run yourself on machines we have no inbound route to.
Which providers can you take snapshots on?
DigitalOcean, Hetzner, Vultr, Linode (Akamai), AWS EC2, Google Compute Engine, and Microsoft Azure. Each one goes through that provider's own snapshot API, so the image is created inside your account, stays there, and is billed by them rather than by us. Two caveats worth knowing up front. Linode is the odd one out — its API creates a disk image of a single disk you select rather than a whole-instance snapshot, so a Linode with several disks attached is not fully covered by one job. Azure has no whole-machine snapshot at all, so a run snapshots every managed disk on the VM as a set; unmanaged (classic) VMs cannot be snapshotted and are refused with a message saying so.
My host isn't on that list. Am I stuck?
Only for snapshots. Database, Docker, and file backups do not care who the host is — they need an SSH login and nothing else. An unsupported provider, a bare-metal box in a colo, or a machine under your desk all work identically.
How much can I actually do on the free plan?
One server, one backup job, one storage destination, running daily, with a one-day retention window. VPS snapshots, file backups, Kubernetes, and Agent jobs are all included on Free; database and Docker jobs unlock on Standard. It is not a trial — there is no card, no countdown, and nothing to cancel.
Can I bring my team in?
Team seats open up on Pro and Agency. Free, Starter, and Standard are single-seat. On the plans that allow it, members join a shared workspace as owner, admin, or member — so the backups outlive whoever set them up.
How the backups actually run
The real commands, the real staging directories, and what happens on the night one of them fails.
How does a database backup actually run?
We open an SSH session to your server and run, for PostgreSQL, pg_dump -h <host> -p <port> -U <user> <database> | gzip. The compressed stream is never written to disk on your server and never written to disk on ours — it goes straight into a multipart upload to your bucket as it is produced, hashed on the way past. MySQL and MariaDB use the equivalent mysqldump pipeline, and the object lands as <database>-<timestamp>.sql.gz. MongoDB is the one that differs: mongodump --archive --gzip compresses and frames the stream itself rather than being piped through gzip, so the object is <database>-<timestamp>.archive.gz and it goes back in with mongorestore rather than a SQL client — from the dashboard like the others, or by hand.
Will the dump lock my database?
pg_dump takes an ACCESS SHARE lock: reads and writes carry on normally, and only schema changes block. mysqldump runs with MySQL's default options, which take a read lock across the tables in the database being dumped for the duration of the dump — so schedule MySQL jobs for a quiet hour rather than your traffic peak.
Can I back up a managed database like RDS or DigitalOcean Managed Postgres?
Yes, indirectly. Set the job's database host and port to the managed endpoint and attach it to any SSH server allowed to reach that endpoint. The dump runs from that box, which means it needs the matching pg_dump or mysqldump client installed and the managed database's firewall has to permit its address. We connect to your server; your server connects to your database.
What is inside a Docker backup?
A single tar.gz containing one archive per named volume you selected — each produced by a throwaway alpine container that mounts the volume — plus a copy of every compose file path you listed and docker inspect output for the containers you named. Volumes are staged in /tmp/vpssnaps-<run-id> on the server first, so you need roughly the compressed size of those volumes free in /tmp. The staging directory is removed when the run finishes.
What happens if one Docker volume fails to archive?
That volume is recorded as a warning and the run continues with the rest. It is deliberate — one unreadable volume should not cost you the other nine — but it does mean a run can finish successfully with a volume missing from the archive. The run log names every volume it archived, so check it if that distinction matters to you.
How do file backups handle a path that doesn't exist?
It is skipped, logged as a warning, and the run carries on. Only if none of the configured paths exist does the run fail outright. Exclude patterns are passed through to tar --exclude verbatim, and tar strips the leading slash, so an archive of /var/www extracts as var/www — it will not overwrite the root of wherever you unpack it.
What does the Kubernetes backup cover, and what does it miss?
If Velero is already installed in the cluster, we detect it and drive it, and your Velero configuration decides what happens. If it is not, we authenticate with a service account token, export the manifests for the namespaces you chose to your bucket, and request a CSI VolumeSnapshot for each persistent volume. Volumes whose storage driver has no CSI snapshot support are skipped and logged rather than silently dropped. We do not install Velero for you.
How often can backups run?
Daily on Free and Starter, every 12 hours on Standard, and as often as every 5 minutes on Pro and Agency. The schedule form offers manual, every 5 minutes, hourly, every 12 hours, daily, weekly, and monthly, with a time of day and an IANA timezone for the last three — so a 2am job runs at 2am where you are, not at 2am UTC.
Can I trigger a backup by hand?
Yes. Any job can be run on demand from the dashboard — before a migration, before a risky deploy, before you touch the database — without disturbing its schedule or its retention window.
When things break
Failure handling is where backup products get quietly optimistic. Here is what we do, and the two places we currently do nothing.
What happens when a backup fails?
The run is marked FAILED with the underlying error text — the provider's message or the shell's stderr, not a generic replacement — the failure is written into that run's log, and a notification goes out on every channel you have configured. The job's row in the dashboard flips to a failed state so it is visible without opening anything.
Do you retry a failed backup automatically?
No, not today. A failed run stays failed until its next scheduled slot or until you re-run it by hand from the dashboard. We would rather say that plainly than let you assume a transient SSH timeout heals itself. The error text and the step-by-step log are kept precisely so the re-run is an informed one.
Will you tell me if a job never ran at all?
Yes. If an enabled job is more than 15 minutes past its scheduled run with nothing dispatched, you get an alert on the same channels as a failure — a stuck run from a previous attempt, a disconnected agent, and a scheduler-level outage all trip it, since they all leave the same symptom. It fires once per outage, then again at most once a day if it's still unresolved, so a multi-hour incident doesn't flood your inbox. It rides the same on/off toggle as failure alerts rather than a separate setting, and Slack/Teams/Google Chat/Discord destinations can be pointed at it individually in Settings if you want it routed differently.
Where do alerts go?
Email plus Slack, Microsoft Teams, Google Chat, and Discord, on success or on failure, per job. All five are available on every plan including Free — there is no chat-notifications upsell. Arbitrary custom webhook URLs, for routing into something we do not support by name, are the Agency plan's addition.
What do I get to look at after a run?
Status, duration, byte size, MD5 checksum, what triggered it, and a timestamped log of every step in order — the SSH connect, each volume archived, each path skipped, the upload, the retention deletions. Warnings stay in place next to the steps that produced them instead of being rolled up into a summary.
Restoring
The most important section on this page. Restore exists for database and file backups now, and the limits are spelled out here rather than discovered later.
How do I restore a backup?
For a database or file run, from the dashboard: open the run, choose the server to restore onto, and confirm. Everything else is still by hand, from your own storage, with standard tools — a Docker volume: docker run --rm -v myvolume:/target -v /path/to/backup:/backup alpine tar xzf /backup/myvolume.tar.gz -C /target. A provider snapshot: restore it from your provider's console, where it already lives. And any archive at all can be restored by hand if you would rather not go through us: gunzip -c mydb-2026-08-31T02-00-00Z.sql.gz | psql mydb. The help centre carries the exact commands for each backup type.
Is there a restore button?
For database and file backups, yes. Open a successful run, pick the server to restore onto, and it downloads the archive, checks it against the checksum recorded when the backup was taken, backs up whatever it is about to overwrite, and only then applies it — and it refuses to go ahead if that safety backup fails. There is also a check-only mode that downloads and verifies without changing anything, which is the honest way to answer 'would this actually restore?'. Two limits worth knowing: Docker and Kubernetes runs cannot be restored from the dashboard yet, and a provider snapshot is rebuilt from your provider's console, where it already lives. One thing to be clear about rather than surprised by: a database restore replaces the tables the backup contains, so a table created after the backup survives it — you get the backup's contents back, not a byte-exact reset. Every artefact also stays an ordinary .sql.gz, .tar.gz or provider snapshot, so the manual path still works whether or not VPS Snaps is online, reachable, or still in business.
How do I know a backup would actually restore?
We record the byte size and an MD5 checksum computed as the archive streamed into your bucket, alongside the full run log, so you can verify that what landed is what left. We do not test-restore it for you. Restoring into a scratch database or a throwaway container once a quarter is the only thing that genuinely proves a backup — a backup you have never restored is a hypothesis.
What happens to my backups if I stop paying?
Nothing happens to them, because they were never ours. Provider snapshots sit in your provider account; archives sit in your bucket. Cancelling stops us scheduling new runs and takes away the dashboard. Everything already written stays exactly where it is, in a format you can open without us.
Storage and retention
Bring your own bucket. That decision shapes the answers below — including one that costs us a feature we would otherwise advertise.
Where does my backup data actually end up?
In the bucket you connected, in the region you chose, under a key of <your prefix>/<job id>/<filename>. Provider snapshots do not move at all — they are created through the provider's API and stay in your account. What we hold is metadata: job configuration, run status, timestamps, byte sizes, checksums, and log lines.
Which storage providers work?
Anything S3-compatible. Amazon S3, Cloudflare R2, Backblaze B2, DigitalOcean Spaces, Wasabi, and UpCloud Object Storage are selectable by name; anything else works by entering a custom endpoint URL. Non-AWS endpoints are addressed path-style automatically, which is the detail that usually breaks S3 clients pointed at R2 or MinIO.
Can one bucket serve every job?
Yes. Each storage destination can carry its own prefix if you want the separation, and every job writes beneath its own job ID inside that. Plans cap how many storage destinations you can register, not how many jobs point at one: Free and Starter allow one destination, Standard three, Pro ten, and Agency effectively unlimited.
How do retention rules work — and what do they not touch?
Retention is a per-job window measured in days. After a run succeeds, we delete the provider snapshots, Linode images, EC2 AMIs, and Kubernetes VolumeSnapshots that we created and that are older than that window, and we prune old run records. We do not delete objects out of your bucket. Your keys are yours, and a bucket lifecycle rule is the right tool for expiring them.
So my storage bill grows forever?
It will if nothing expires the objects. Every S3-compatible provider supports lifecycle rules — expire objects under your prefix after N days and the curve flattens. Set it once when you create the bucket. We would rather you own that switch than hand us blanket delete authority over your archive.
Do you charge for storage?
No. There is no storage add-on, no included-gigabytes allowance, and no per-GB metering from us. You pay your storage provider directly at their rate, and you can walk away with the data at any time precisely because it was never on our side of the fence.
Security and privacy
Including the honest version of "do you see my data", which is not a flat no.
Do you see my data?
For provider snapshots and Agent jobs, no: the snapshot is created inside your provider account, and the Agent uploads to your bucket itself. For SSH database, Docker, and file jobs, partly — the dump or archive is piped from your server through our worker process and into your bucket. It is a stream held in memory, bounded to a few tens of megabytes at a time regardless of backup size, never written to disk on our side and never retained. We would rather state that than imply an air gap that is not there.
How are my credentials stored?
Provider API tokens, SSH private keys, database passwords, storage access keys, and TOTP secrets are encrypted with AES-256-GCM before they reach the database — each with its own random 96-bit IV and an authentication tag. They are decrypted only inside a running job. Nothing is written to logs, and nothing is displayed back to you after the first save.
What SSH access do you need?
A host, a port, a username, and either a private key or a password. The account needs to be able to run whatever that job runs — pg_dump, mysqldump, mongodump, tar, or docker — and read the paths you pointed it at. There is no requirement for root, and no requirement for us to be able to reach anything other than that one host on that one port.
My server is behind NAT, a VPN, or a private VPC. Can you still back it up?
Yes, with the Agent. Instead of us dialling in, you run a small Docker container on the machine and it opens an outbound WebSocket to us and waits for instructions. No inbound port, no public IP, no firewall exception. The Agent runs Database, Docker, and File jobs — not provider snapshots or Kubernetes — and uploads straight from your machine to your bucket, so the data never transits our infrastructure at all.
Do you support two-factor authentication?
Yes. TOTP from any authenticator app, with single-use backup codes for recovery. The TOTP secret is stored encrypted and the backup codes are stored as bcrypt hashes.
Can I lock down the storage key I give you?
You should, and the help centre has the policy. It grants s3:PutObject, s3:GetObject, s3:DeleteObject, and s3:ListBucket on one bucket and nothing else. DeleteObject is there only for the "test connection" check, which writes a small probe object and removes it again — the backup path itself never deletes from your bucket.
Is there anything in your security model you'd flag?
One thing: SSH host keys are not pinned. Connections authenticate with your key or password and those credentials are encrypted at rest, but we do not currently verify that the server's host key is the same one we saw last time. If host-key pinning is part of your threat model, it is not covered today.
Plans and billing
Every ceiling the app enforces, read straight out of the plan records. If a number changes, this table changes with it.
| Plan | Servers | Jobs | Storage destinations | Fastest schedule | Retention |
|---|---|---|---|---|---|
| Free | 1 | 1 | 1 | Daily | 1 day |
| Starter | 5 | 3 | 1 | Daily | 3 days |
| Standard | 15 | 20 | 3 | Every 12 hours | 14 days |
| Pro | 40 | 50 | 10 | Every 5 minutes | 30 days |
| Agency | 150 | 250 | Unlimited | Every 5 minutes | 90 days |
Database and Docker jobs unlock on Standard; team seats on Pro; custom webhook URLs on Agency. The pricing page carries prices and the full feature matrix.
What happens when I hit a plan limit?
The next thing you try to create is refused with the exact numbers — "Plan limit reached: 3/3 backup jobs" — and everything already configured keeps running on schedule. Nothing is deleted, nothing is paused, and no backup is skipped because you are sitting at the ceiling.
What happens if my card fails?
Access continues while Stripe retries. A declined card — usually an expired one — should not cost you your backups on day one. If dunning is exhausted and the subscription lands in unpaid or cancelled, paid features switch off. Your snapshots and archives are unaffected either way; they are not stored by us.
What happens to my jobs if I cancel?
Your plan runs to the end of the period you already paid for, then paid features switch off. You can cancel from the billing page at any time — there is no contract and no cancellation step that requires talking to anyone.
Can I get a refund?
Within 14 days of your first payment, yes — email [email protected] and we refund it in full. After 14 days, subscriptions are non-refundable, and cancelling mid-period keeps your access until that period ends. Upgrades take effect immediately and are prorated against the days remaining; downgrades take effect at the start of the next period.
Is the free plan a trial in disguise?
No. It does not expire, it never asks for a card, and there is nothing to cancel. Paid plans do not have a trial either — the 14-day money-back guarantee stands in for one, which we think is the more honest shape.
Didn't find it here?
Three places to go next, in the order most people need them.
Help centre
Step-by-step guides with the actual commands: connecting a server over SSH, configuring S3, R2 and B2, cron schedules, and what to check when a backup fails.
Read moreTalk to a human
A question this page didn't answer, a limit you need clarified before you commit, or a bug. Support is the person who wrote the code, not a queue.
Read moreStatus page
Live component health for the app, the scheduler, the backup workers, and the agent relay — so "is it me or is it them" takes one click to answer.
Read moreRead the awkward answers. Now go break something safely.
Connect one server, point a job at your own bucket, and watch a run finish end to end on the free plan before you decide anything.
No credit card required. Cancel anytime.