The right WooCommerce backup is whichever one you can restore in under an hour without silently deleting the orders that arrived this morning. That second half is the part the comparison articles skip, and it is the only part that separates a store backup from a blog backup.
A blog that loses six hours of changes loses a draft. A store that loses six hours loses paid orders that the payment processor still has on file — money taken, no record in WooCommerce, a customer waiting for a shipment that will never be picked. So this article compares the four realistic approaches on recovery behaviour rather than on feature lists, and I have deliberately not printed vendor prices: they change, and a stale figure is worse than no figure. Every plan below tells you where to check the current cost yourself.
The five things I judged each approach on
- Granularity. Can you restore the database alone, files alone, or a single table? Whole-server rollback is a blunt instrument on a trading store.
- RPO — how much order data a restore throws away. The gap between the last good copy and the moment things broke, measured in orders rather than hours.
- RTO — how long from broken to trading again. A copy you cannot restore before lunch is a copy that costs you a day of revenue.
- Where the copy lives. Different provider, different credentials. A backup sitting in the same hosting account as the site is not an off-site backup, it is a second copy of the same risk.
- Whether you have ever restored it. An untested backup is a belief, not a backup. This is the criterion that eliminates most setups, including expensive ones.
What a WooCommerce backup has to actually contain
Before comparing tools, know what you are asking them to capture. On the filesystem it is short: wp-content/uploads, wp-content/plugins, wp-content/themes and wp-config.php. Core files you can reinstall in ninety seconds and do not need in the archive.
The database is where store backups differ from everything else. Modern WooCommerce installs keep orders in their own tables rather than in wp_posts, so a backup scoped by guesswork will miss them:
wp_wc_orders,wp_wc_order_addresses,wp_wc_order_operational_data,wp_wc_orders_meta— the orders themselves under High-Performance Order Storage.wp_woocommerce_order_itemsandwp_woocommerce_order_itemmeta— the line items. These live in their own tables regardless of which order storage you use, and an order without them is a receipt with no products on it.wp_wc_order_stats,wp_wc_customer_lookup,wp_wc_product_meta_lookup— the analytics lookup tables. These can be rebuilt, slowly, and reporting looks wrong until you do.wp_woocommerce_sessions— live carts. Plenty of backup tools skip this table by default because it looks like transient junk. Restore without it during trading hours and every shopper mid-checkout finds an empty cart.wp_postsandwp_postmeta— still where products live, and still where orders live on stores that were never migrated off legacy storage.
If you are not certain which storage your store uses, look at your database with wp db tables --all-tables | grep wc_orders. If those tables exist and hold rows, that is where your orders are.
The exclusion list is where good backups quietly become bad ones. Every tool that offers “skip unnecessary tables” is offering you a way to break a store restore. If you exclude anything, exclude caches and logs by name, never by pattern, and write down what you excluded somewhere you will find it at 2am.
The four approaches compared
Almost every store runs one of these four, sometimes two. The table is not a ranking — the right answer depends on your order volume and on who is going to perform the restore.
| Approach | Best for | Granularity | Main strength | Main weakness | Where to check cost |
|---|---|---|---|---|---|
| Host snapshots | Any store, as a floor — never as the whole plan | Usually the entire account or server; rarely a single table | Already included, runs without you, survives a site that will not load at all | Retention is often days, not months; restores can be all-or-nothing; the copy lives with the provider whose outage you are recovering from | Your host’s control panel and plan page |
| Backup plugin, free tier | Low-volume stores, under roughly ten orders a day | Files and database separately; some offer per-table selection | Free, off-site destination of your choosing, restore runs from wp-admin | Full copies each run, so large uploads folders time out on shared hosting; the restore needs wp-admin to be reachable, which is exactly what an outage takes away | The plugin’s page on wordpress.org |
| Backup plugin, paid tier | Stores where nightly full copies have stopped finishing | Incremental file and database changes; selective restore in most | Short backup windows, so you can run the database far more often than the files | Incremental chains have a failure mode full copies do not: one corrupt link can invalidate everything after it. Verify periodically. | The vendor’s own pricing page — check renewal terms, not just year one |
| Managed backup service | Stores taking dozens of orders a day, or anyone without a person on call | Point-in-time restore, often per-order or per-table | Copies held entirely outside your hosting account; restores that work when the site is down | A recurring cost that scales with storage, and one more vendor holding a full copy of your customer data | The service’s pricing page and its data processing terms |
| WP-CLI plus object storage | Teams comfortable with a shell and a cron entry | Total — any file, any table, any point you kept | No plugin overhead, no dashboard to log into, costs pennies per month in storage | You own it. Nobody sends you an alert when it stops working, and it will stop working the week someone rotates a key | Your object storage provider’s per-GB rate |
The pairing that covers most stores is host snapshots plus one of the other three. The host snapshot is your floor for total server loss. The second tool is what you actually reach for, because it restores a database without touching the filesystem — which is what you want when a bad import mangles product data but the site is otherwise healthy.
Measure your RPO in orders, not hours
“Daily backups” sounds adequate until you convert it into the unit that matters. Take a store doing 300 orders a month at an average order value of $65. That is roughly 10 orders a day, but they are not spread evenly — North American stores commonly see a large share land between roughly 11am and 9pm Eastern.
Back up at 03:00 and break the site at 16:00, and you lose thirteen hours that contain most of the day’s orders. Call it 7 of the 10, around $455 of order data, plus the customer service cost of seven people whose cards were charged for an order you have no record of. Now run the same arithmetic on a store doing 60 orders a day and the same thirteen-hour gap is about 40 orders and $2,600.
The fix is cheaper than it sounds, because the two halves of a backup have wildly different sizes. A store database is frequently under 500 MB. The uploads folder is frequently 20 GB or more. So stop backing them up on the same schedule:
- Database: hourly during trading hours. It is small, it compresses well, and it is where every order lives.
- Uploads: daily or weekly. Product images change rarely. Losing a day of them costs you a re-upload, not a refund.
- Plugins, themes and
wp-config.php: before every deploy or update. That is the moment you are most likely to need them, and it is the routine described in updating WordPress plugins without breaking your website.
An hourly database backup in about twelve lines
If your host gives you SSH and cron, this is the whole of it. Save it as wp-db-backup.sh, make it executable, and run it hourly from cron.
#!/usr/bin/env bash
set -euo pipefail
SITE=/var/www/example.com
DEST=/var/backups/wp
STAMP=$(date -u +%Y%m%dT%H%M%SZ)
mkdir -p "$DEST"
# --single-transaction gives a consistent InnoDB dump without locking
# the order tables, so checkout keeps working while this runs.
wp --path="$SITE" db export "$DEST/db-$STAMP.sql" \
--single-transaction --quick --default-character-set=utf8mb4
gzip -9 "$DEST/db-$STAMP.sql"
# Push off-site. Any rclone remote works: S3, B2, Spaces, Drive.
rclone copy "$DEST" store-backup:wp/"$(date -u +%Y/%m)"
# Keep a week locally; the remote keeps the long tail.
find "$DEST" -type f -mtime +7 -delete
Two details do the real work here. --single-transaction is what lets you dump a live store without locking the order tables and stalling checkout, and it only behaves that way if your tables are InnoDB — check with wp db query "SHOW TABLE STATUS" if you inherited the site. And the rclone copy line is the one that makes this a backup rather than a copy: until the archive is on a different provider under different credentials, ransomware or a deleted hosting account takes it with the site.
The restore problem nobody warns store owners about
Here is the scenario that turns a good backup into a bad afternoon. Something breaks at 16:00. You restore last night’s database. The site comes back perfectly. And every order placed between 03:00 and 16:00 is now gone from WooCommerce — while the payment processor still holds all of them, settled and charged.
Nothing is wrong with the backup. The restore did exactly what it promised. But you have just created a reconciliation problem that gets worse every hour you leave it, because the deposits will land in your bank account with no matching orders behind them.
The sequence that avoids it takes ten extra minutes:
- Before restoring anything, export the gap. Open your processor’s dashboard and export every successful payment between the backup timestamp and now. This is your authoritative record of what the restore is about to erase, and it exists independently of your site. Worth knowing what that dashboard holds before you need it — it is the same one behind your WooCommerce payment gateway fees.
- Take a backup of the broken site. Yes, broken. It still contains those orders, and it is the only copy of them that exists in WooCommerce’s own format.
- Restore to staging first if the outage lets you. Confirm the restore is clean before you point customers at it. Restoring a production database onto a different domain means fixing URLs, which is its own careful procedure — see changing your WordPress site URL safely rather than running a blind search and replace.
- Restore the narrowest thing that fixes the problem. A corrupt options table needs one table restored, not thirteen hours of trading rolled back. This is why granularity is the first criterion in the list at the top.
- Re-enter the gap orders, then reconcile. Against the processor export from step one. Tedious, finite, and vastly better than discovering the discrepancy at month end.
Once the site is back, do not trust a homepage that loads. Place a real test order, including a refund, and walk the checklist in testing your WordPress site after a major update. Restores routinely bring back a stale API key or a plugin at a version that no longer matches the rest of the stack, and the symptom is a checkout that half works.
Rehearse the restore, or you do not have one
Schedule ninety minutes, once a quarter, and restore last night’s backup onto a staging site from scratch. Time it. The number you get is your real RTO, and it is usually two to three times what you assumed.
What that rehearsal tends to expose, in rough order of frequency: archives that are present but truncated because a PHP process hit its time limit every night; the person who knows the storage credentials is on holiday; a 20 GB uploads restore that takes four hours on the connection you have; database imports failing on character set mismatches; and a backup that has silently excluded the order tables since someone tidied the exclusion list in March.
Check that your failure alerts can actually reach you. Most backup tools report by email, and most WordPress installs send mail through PHP’s default transport, which mailbox providers increasingly drop without a bounce. The result is a store owner who has not seen a backup failure notice in four months and reads that as good news. Send yourself a test, and if it does not arrive, the diagnosis is in WordPress emails not sending.
Fixing it means routing mail through an authenticated service. Send Emails is my own free plugin for this. Disclosure: I build and maintain it. Judged by the same criteria as everything else here, its weakness is a smaller install base and a shorter track record than WP Mail SMTP or FluentSMTP, both of which are free, mature and do this job well — if you already run one of them, there is no reason to switch. What matters is that something authenticates your outgoing mail, not which of the three you pick.
Which WooCommerce backup approach to pick
Sort by order volume, because that is what sets the cost of the gap.
- Under 10 orders a day. Host snapshots plus a free backup plugin writing to storage you control. Daily files, and the database more often than daily if the plugin allows it. Rehearse once a quarter.
- 10 to 50 orders a day. This is where nightly full copies start timing out and where a lost afternoon becomes real money. Move to incremental backups or a managed service, and get the database down to hourly.
- Over 50 orders a day. Point-in-time restore stops being a luxury. Pay for a service that holds copies outside your hosting account and can restore without wp-admin, because at that volume a four-hour outage costs more than a year of the subscription.
- Any volume, with shell access and someone who enjoys this. The WP-CLI script above, hourly, to object storage — plus a calendar reminder to verify it, because the whole risk of rolling your own is that nothing tells you when it stops.
Whichever you choose, the decision that matters is not the tool. It is whether the database runs on a tighter schedule than the files, whether the copy leaves your hosting account, and whether you have restored it recently enough to know how long it takes.
Frequently asked questions
Is my host’s backup enough for a WooCommerce store?
As the only backup, usually not — for three reasons rather than any doubt about quality. Retention is often measured in days, so a problem you notice two weeks later is already past the oldest copy. Restores are frequently whole-account, which means rolling back a day of orders to fix one broken table. And the copy lives with the provider whose outage or account suspension you might be recovering from. Keep host snapshots. Add something that restores a database on its own and stores the archive somewhere else.
How often should a WooCommerce store back up?
Work backwards from what you can afford to lose. Multiply your orders per hour by your average order value, and that is the hourly cost of your backup interval. For most stores the answer is the database hourly during trading hours and the uploads folder daily, because those two have very different sizes and very different replacement costs. A store taking two orders a day can sit comfortably on daily backups; a store taking sixty cannot.
Will restoring a backup delete orders placed since it was taken?
Yes, if you restore the database. This is the single most expensive surprise in store recovery and it catches experienced people. Before you restore, export every successful payment from your processor’s dashboard for the period between the backup and now, and take a fresh backup of the broken site so those orders still exist somewhere in WooCommerce’s own format. You can re-enter them afterwards. You cannot invent them from nothing.
Which database tables can I safely exclude from a store backup?
Very few, and never by wildcard. Caching plugin tables and verbose log tables are genuinely disposable. Everything with wc_ or woocommerce_ in the name should stay, including wp_woocommerce_sessions, which looks like throwaway data and is in fact every cart currently open on your site. Excluding wp_options transients row by row is a false economy: the table is small, and getting the pattern slightly wrong takes your site configuration with it.
My backup plugin fails halfway through every night. What is wrong?
Almost always a resource limit rather than a bug: PHP’s max_execution_time, the memory limit, or a host-level process cap ending the job before the uploads folder finishes. The fix is to stop asking for a full copy every night. Split files from database, run the database far more often and the files far less, and switch to incremental file backups if your plugin offers them. If the plugin is also throwing errors into the site, work through it as a plugin conflict before assuming the backup tool itself is at fault.
Do I need a backup if my host offers staging?
Staging and backups solve different problems. Staging lets you test a change before it reaches customers; a backup lets you undo a change that already did, or recover from something you never chose — a bad update, a compromised account, a database that corrupts at 3am. Use staging to avoid needing the backup, and keep the backup for the times staging would not have helped.
The short version
Back the database up far more often than the files, send the archive to a provider that is not your host, and restore it onto staging once a quarter with a stopwatch running. Do those three things and the choice between a plugin, a host snapshot and a managed service stops being a difficult decision — any of them will get you back. Skip them, and the most expensive option on the market still will not.

Leave a Reply to This Post