Ahosting Logo
Knowledge Base

How to Back Up a Store That Takes Orders Continuously

A store backup is a moving targetA brochure site· files and database change rarely· so capturing them minutes apart is fineA store· an order can be written between the two captures· leaving a database referencing a file that is not there, or the reverse· and the inconsistency only shows on restoreWhat that means for schedulingBack up more often than a content site, keep more versions, and verify by restoring to a testlocation rather than by checking the file exists.

Backing up a brochure site is copying files and a database that barely change. Backing up a store means copying something that is being written to while you copy it, and that difference is where the failures come from.

The timing problem

A typical backup dumps the database, then copies the files. Say the dump finishes at 02:00 and the file copy at 02:12.

An order placed at 02:05 is in the files. An uploaded receipt, a generated invoice, and not in the database. Or the reverse, depending on the order of operations.

Restore that and you have a state the site was never in: an order record referencing files that do not exist, or files belonging to an order nobody has.

On a site with a few orders a day this is unlikely. On a busy store it is close to certain.

Dump the database consistently

mysqldump --single-transaction --routines --quick dbname > store.sql

--single-transaction gives a consistent view of the whole database at one instant without locking tables, so the site keeps taking orders while the dump runs. It requires InnoDB tables, which WooCommerce uses.

Without it, tables are dumped one after another and an order can be half-present, in the order table but not in the items table, which is a genuinely confusing thing to inherit.

Order the steps deliberately

Copy files first, database last, with as little time between as possible.

That way the database is the newer half. A database referencing a file that was not captured is a missing attachment; a file with no database record is invisible. The first is a small problem and the second is a silent one, so prefer the arrangement that produces the first.

What actually needs backing up

The database, in full. It holds orders, customers, products and settings.

From the files: wp-content/uploads, the theme, and wp-config.php. WordPress core and plugins can be reinstalled and are the bulk of the size, excluding them makes backups small enough to keep more of.

Not the caching directories, and not backup archives from other tools, which is how a store's backups end up containing previous backups.

Every restore loses recent orders

This is unavoidable and worth planning for rather than discovering.

Restoring last night's backup means orders placed since are gone from the store. The customers who placed them still paid, and the payment provider still has the record.

So the recovery procedure has two steps, not one: restore, then reconcile against the payment provider's transaction list for the gap and re-enter what is missing. Written down in advance, that is an afternoon. Improvised during an outage, it is how orders get lost permanently.

The same reasoning applies to inventory. Inventory and stock management explains stock counts that a restore moves backwards.

Store copies away from the server

A backup on the same account is not a backup against the failure that matters. It shares the disk, the account, and any compromise.

Send copies somewhere else, and prefer a destination that pulls instead of one the server can write to. A server that can delete its own backups will, if something on it decides to.

Managing WordPress backups explains scheduling and retention.

Restore before you need to

A backup nobody has restored is an assumption.

Restore one to a staging site and check the specific things a store needs to be right: recent orders present with their line items, product images loading, payment settings intact, customer accounts working.

Doing this once tells you how long a restore takes, which is the number you will want during an outage and cannot estimate under pressure. Restoring a WordPress site from backup explains the mechanics.

Before anything risky

Take a fresh backup immediately before an update or a migration, rather than relying on last night's.

The difference is the orders taken today, which is exactly the data you would most regret losing, and exactly what a nightly backup does not contain. Updating WooCommerce safely deals with where in the sequence it belongs.

Take a copy without stopping the shop

The consistent dump is the important half, and there is a second technique worth knowing when the database is large enough that even a consistent dump takes a while.

mysqldump --single-transaction --routines --quick --lock-tables=false dbname | gzip > store.sql.gz

--quick streams rows rather than buffering the whole table in memory, which matters on an order table with hundreds of thousands of rows, without it the dump can exhaust the machine's memory on a shared server.

Compressing in the pipeline rather than afterwards halves the disk written and avoids a large temporary file inside the account, which on a store approaching its quota is the difference between a backup and a failed one.

Exclude what you can regenerate

Some tables are large and disposable, and excluding them makes backups fast enough to run often, which matters more than completeness.

Session tables, transient rows and scheduled-action history for completed jobs can all be recreated. Orders, customers and products cannot.

mysqldump --single-transaction --quick \
 --ignore-table=dbname.wp_woocommerce_sessions dbname | gzip > store.sql.gz

Be precise about which tables those are on your store rather than copying a list, excluding the wrong one produces a backup that restores into a broken shop. WooCommerce database growth goes over which are which.

Verify the backup, not just its existence

A backup that exists and cannot be read is the failure people discover at the worst moment.

gzip -t store.sql.gz && echo "archive intact"
zcat store.sql.gz | tail -5
zcat store.sql.gz | grep -c 'INSERT INTO `wp_posts`'

The first confirms the archive is not truncated: a dump interrupted by a full disk produces a file that looks fine until it is opened. The second checks the dump completed, since a complete dump ends with a recognisable line. The third confirms it actually contains data rather than structure only.

Three commands, automatable, and they turn "the backup ran" into "the backup is usable".

Know how far back you can go

Retention decides which problems are recoverable, and stores have a specific version of this: a fault noticed on Friday that began on Monday needs a backup from before Monday.

Data corruption, a bad import or a plugin quietly writing wrong values are all discovered days after they start. A rotation keeping only three days cannot help with any of them, and that is the common arrangement.

Keep daily copies for a fortnight and a weekly copy for a few months. The cost is storage; the alternative is a restore point that does not reach back far enough. Managing WordPress backups deals with arranging the rotation.