A WordPress backup has two halves that live in completely different places: the files on disk — core, themes, plugins, uploads — and the database, which holds every post, page, comment, user, and setting. Copy one without the other and you have half a site and no way to know it until you try to restore.
That split is the reason so many backups turn out to be useless at exactly the wrong moment. Somebody downloads the wp-content folder, feels covered, and discovers during an incident that every post lived in MySQL. The good news is that both halves are straightforward, and once you understand what is where, choosing a backup method becomes a question of how much you want to automate.
Table of contents
- What is actually in each half
- Method 1: the host’s own backups
- Method 2: a backup plugin
- Method 3: doing it by hand
- Restoring, which is the part that counts
- A schedule that is proportionate
- How this fits the rest of the stack
- FAQ
What is actually in each half
The files. Everything under the WordPress root directory:
- WordPress core — replaceable, since you can download the same version again.
wp-content/themes— your active theme, plus any customisations made directly in files.wp-content/plugins— replaceable from the repository, except anything premium or custom.wp-content/uploads— not replaceable. Every image, PDF, and media file you have ever uploaded. This is usually the biggest directory and the one you cannot rebuild.wp-config.php— database credentials, salts, and constants. Small and critical.
The database. Every table, but the ones that matter most:
wp_postsandwp_postmeta— posts, pages, and every custom post type. Nearly all your content.wp_options— site settings, plus most plugin configuration.wp_usersandwp_usermeta— accounts and roles.wp_termsand friends — categories and tags.- Plugin tables — WooCommerce orders, form submissions, membership records. Business data, frequently.
The practical implication: uploads and the database are the irreplaceable parts. Core and repository plugins can be re-downloaded. If you are ever forced to economise on backup storage, that is the priority order.
Method 1: the host’s own backups
If your host takes automatic daily backups of files and database and lets you restore from a control panel, use it. It is the least effort and the least likely to be silently broken, because it is exercised by other customers constantly.
The questions worth asking before relying on it:
- How long are they retained? Seven days is common and is not enough to catch a problem introduced three weeks ago.
- Can you restore just the database, or is it all or nothing? Granularity matters when a plugin update corrupted one table.
- Can you download a copy? A backup you can only restore in place is not protection against losing the account itself.
- Have you actually tried a restore? Not on the live site. Clone to staging and restore there.
The failure mode of host backups is not that they do not exist. It is that they are all in the same place as the site, so anything affecting the account affects both. That is why a downloadable off-site copy matters even when host backups are good.
Method 2: a backup plugin
The standard approach when the host does not cover it or you want your own copy. A plugin packages files and database into an archive and pushes it to remote storage.
Setting one up sensibly:
- Install and activate the plugin from the dashboard.
- Set the schedule. A common starting point is a daily database backup and a weekly file backup, since the database changes constantly and the files rarely do.
- Configure remote storage — object storage or a cloud drive. This is the important step. A backup stored on the same server as the site protects you from a bad plugin update and from nothing else.
- Run one manually and confirm it completes and the archive appears in remote storage.
- Restore it to a staging site. This is the step everyone skips, and it is the only one that proves anything.
One practical caveat: on a large site, backup plugins run inside PHP and are subject to execution time and memory limits. A backup that keeps timing out at 60% is a very common support ticket, and the usual answers are increasing limits, excluding large directories, or moving to a method that runs outside PHP.
Frequency should match how much work you can afford to lose. A brochure site that changes monthly is fine on weekly. A shop taking orders needs the database backed up far more often, because every hour of gap is orders you cannot recover.
Method 3: doing it by hand
Worth knowing even if you automate, because it is what you fall back on when the automation is what broke.
Files, over SFTP or a file manager:
# from a shell, if you have one
tar -czf site-files-$(date +%F).tar.gz /var/www/html
# or just uploads and config, the irreplaceable parts
tar -czf uploads-$(date +%F).tar.gz wp-content/uploads wp-config.php
Database, with mysqldump or WP-CLI:
mysqldump -u dbuser -p --single-transaction --quick \
wordpress_db > wp-db-$(date +%F).sql
# WP-CLI reads credentials from wp-config.php for you
wp db export wp-db-$(date +%F).sql
--single-transaction takes a consistent snapshot without locking tables, which matters on a live site. --quick streams rows instead of buffering the whole result in memory, which matters on a large one.
WP-CLI is the better route where available, because it reads the credentials from wp-config.php and you cannot get the wrong database. wp db import file.sql is the matching restore.
If neither shell nor WP-CLI is available, phpMyAdmin’s Export tab produces the same SQL file through a browser. It struggles on very large databases, where the export times out partway and produces a truncated file that looks fine until you restore it.
Restoring, which is the part that counts
The documented order matters, because restoring files onto a database that expects a different schema causes confusing errors.
- Put the site into maintenance mode if it is live.
- Restore the database first — create an empty database, import the SQL dump.
- Restore the files second, keeping
wp-config.phppointing at the right database. - Check
siteurlandhomein thewp_optionstable if the domain has changed. - Flush permalinks by re-saving them in Settings, which regenerates rewrite rules.
- Clear every cache — plugin cache, object cache, CDN.
That fourth step is the most common restore problem. If you restore to a different domain, the database still contains the old URL in siteurl, home, and serialised data throughout wp_options and wp_postmeta. A plain find-and-replace corrupts serialised arrays, because the strings carry their own length prefixes. Use wp search-replace old.com new.com which handles serialisation correctly, or a plugin built for the job.
And test the restore before you need it. A backup nobody has restored is a hypothesis. The teams that discover their backups were empty all discover it during the incident, which is the one moment when finding out is most expensive.
A schedule that is proportionate
- Static brochure site, changes monthly — weekly full backup, thirty day retention.
- Active blog or business site — daily database, weekly files, thirty day retention.
- Shop or membership site — database backed up several times a day at minimum, files weekly, longer retention.
- Before any risky change — a manual backup immediately before a core update, a major plugin update, or a theme change. Thirty seconds that has saved an enormous number of afternoons.
The old advice of three copies on different media has aged into something simpler: keep it somewhere other than the server, keep more than one, and keep them long enough to cover a problem you did not notice immediately. Corruption introduced by a plugin update is often discovered a fortnight later, by which time a seven day retention window has already rotated the clean copy away.
How this fits the rest of the stack
How painful all of this is depends heavily on whether you can reach your files and database without an SFTP client and a database GUI. Managed WordPress on RunxBuild puts a file manager in the dashboard — browse, edit, upload, unzip, download — and a database browser beside it for tables, rows, SQL, export, and import, which turns both halves of a backup into something you can do from a browser rather than assembling a toolchain first. Plans start at $3 a month. WordPress files on RunxBuild and WordPress database on RunxBuild cover both tools, and when you are sizing a site plus its storage and bandwidth, the RunxBuild hosting calculator shows those as separate line items.
Useful related references:
- WordPress 6.9 Broke My Site: Getting Back Up Before Debugging
- WordPress Hosting for Agencies: White-Label, Multi-Site, and the Reseller Model
- Downloading a Full WordPress Site: What the Plugins Actually Do
- Databases on RunxBuild
FAQ
What do I need to back up on a WordPress site?
Two things: the files (core, themes, plugins, and critically wp-content/uploads plus wp-config.php) and the database, which holds all posts, pages, users, settings, and plugin data. Core and repository plugins can be re-downloaded; uploads and the database cannot.
How often should I back up WordPress?
Match it to how much work you can afford to lose. A brochure site is fine weekly. An active blog wants a daily database backup and weekly files. A shop needs the database captured several times a day, because every hour of gap is orders you cannot recover. Always take a manual backup before a core or major plugin update.
Can I back up WordPress without a plugin?
Yes. Archive the site directory over SFTP or a file manager, and export the database with mysqldump --single-transaction --quick or wp db export. WP-CLI is preferable where available because it reads credentials from wp-config.php, so you cannot dump the wrong database.
What order do I restore a WordPress backup in?
Database first, then files, keeping wp-config.php pointed at the right database. Then check siteurl and home in wp_options, re-save permalinks to regenerate rewrite rules, and clear every cache including the CDN.
Why does my site break after restoring to a new domain?
The database still contains the old URL in wp_options and in serialised data across postmeta. A plain SQL find-and-replace corrupts serialised arrays because they store string lengths. Use wp search-replace old.com new.com, which understands serialisation, or a plugin designed for the job.