How to schedule automatic WordPress backups
A backup schedule can live at your host, in a backup plugin or in a cron job on the server. Whichever you use, it has to copy the database and the files, send them off the server, and be restored once to a staging copy as proof.
- By
- WP Ministry
- Published
In short
- A full backup is the database and the files, made around the same time.
- The schedule can live at the host, in a backup plugin or in a cron job on the server.
- A plugin's schedule runs on WP-Cron, which only wakes when someone loads a page. On a quiet site it runs late.
- A real cron job that calls wp-cron.php, with DISABLE_WP_CRON set, puts that schedule on a clock.
- Send every backup somewhere other than the site's server, and decide how many to keep.
- A backup is proven only by restoring it to a staging copy.
An automatic backup needs three things: something that copies the site on a schedule, somewhere off the server to send each copy, and a rule for deleting old ones. The schedule can live in one of three places: your host's own backup system, a backup plugin, or a cron job on the server that runs WP-CLI.
Whichever you choose, each backup has to hold both the database and the files, and you have to restore one to a private copy of the site. Until a backup has been restored, you do not know that it works.
What a full backup holds
WordPress's documentation splits a site into two parts and says you need both to restore it.
- The database. Every post, page and comment, and the other data the site generates, such as the orders on a store. It lives in MySQL or MariaDB, outside the site's folder, so copying the folder does not copy it.
- The files. WordPress itself, the themes, the plugins, your uploads,
wp-config.phpand.htaccess.
Treat the two as one set, made around the same time. The documentation's order is database then files when backing up, and files then database when restoring.
How often, and how many to keep
The gap between two backups is the most work you can lose. WordPress suggests once a week for a small site with few posts and daily for a busy one. The database changes with every comment and order. The files change only when you upload, update or edit something, so the database is the part to back up more often.
| Kind of site | Database | Files |
|---|---|---|
| Pages that change a few times a month | Weekly | Weekly |
| New posts or comments on most days | Daily | Daily or weekly |
| A store, a membership site, or forms that keep entries | Several times a day | Daily |
For how many to keep, WordPress's guidance is at least three to five recent backups, with copies in different places. A longer history helps when a problem is found late: damage noticed after three weeks needs a backup older than three weeks. Two weeks of daily backups is a sensible floor.
Where the schedule can live
| Place | What runs it | What you need | Weak point |
|---|---|---|---|
| The host's backups | The host's own systems | A plan that includes them | You may not set the schedule, and the copies sit with the same company as the site |
| A backup plugin | WordPress, through WP-Cron | A storage account outside the server | Runs late on a quiet site, and not at all when WordPress cannot run |
| A cron job with WP-CLI | The server's clock | SSH access and WP-CLI | You write it and watch it yourself |
Start with the host. Add a plugin or a cron job for whatever the host leaves out.
The host's backups
WordPress's documentation notes that most hosts back up the whole server, and that asking them for a copy of your site takes time. Find out what yours does before you add anything. WordPress backup plugins compared lists what to ask: where the copies are stored, how often they are taken, how long each is kept, whether they hold both parts, and whether you can restore and download one yourself.
If the answers are daily, away from the site's server, kept for weeks and restorable by you, that may be the whole schedule you need. Add two things. Download a copy once a month and keep it elsewhere, so that not everything depends on one company. And restore one to a staging copy, as described below.
A backup plugin's schedule
A plugin builds the backup inside WordPress and sends it to storage you choose. The comparison linked above covers which plugin offers which schedule and which storage. The setup has the same outline in each.
Step 1: Set the schedule
Use the table above. Some plugins take one schedule for the database and another for the files: UpdraftPlus has a setting for each on its Settings tab. BackWPup sets a frequency on each backup job.
Step 2: Send each backup to storage outside the server
Connect the plugin to a storage account that is not on the site's server. A backup left only in a folder on that server is lost along with it. A backup holds the whole database, user accounts and customer details included, so give that account a strong password and two-step login.
Step 3: Set how many to keep
Look for the retention setting. UpdraftPlus, for one, takes a maximum number of backups to keep, separately for the files and the database, and deletes the oldest when the number is reached. On a daily schedule, 14 keeps two weeks.
Step 4: Run one now and find it in the storage
Start a backup by hand from the plugin's screen. Then open the storage account itself and look for files with today's date. Look again after the first scheduled run.
Why a plugin's schedule can run late
WordPress has its own scheduler, WP-Cron. It does not run on a clock. On every page load it checks a list of scheduled tasks and runs the ones that are due. If a backup is set for 2:00 and nobody loads a page until 5:00, the backup starts at 5:00.
UpdraftPlus's and BackWPup's documentation both say their scheduled backups run through this scheduler. UpdraftPlus's adds what else stops it: maintenance mode, a password on the whole site at the server, and a host that blocks the site's requests to itself.
Two places show whether scheduled tasks are running on your site:
- Site Health. Go to Tools, then Site Health. A notice that reads "A scheduled event is late" or "A scheduled event has failed" means tasks are not running when they should. "Your site could not complete a loopback request" means WordPress cannot make the request to itself that starts them.
- WP-CLI.
wp cron testtries to start WP-Cron over HTTP. When that works, it prints "Success: WP-Cron spawning is working as expected."
Put WP-Cron on a real clock
The fix in WordPress's Plugin Handbook is to have the server's scheduler, cron, call wp-cron.php at a fixed interval, and then to stop WordPress checking on every page load. You need SSH access, or a screen for cron jobs in your hosting control panel.
Step 1: Open your list of cron jobs
This opens your user's crontab, the list of commands cron runs for you, in a text editor.
crontab -lprints the list without editing it.bashcrontab -eStep 2: Add a line that calls WordPress every 15 minutes
Use your own domain. The five fields before the command are minute, hour, day of the month, month and day of the week. An asterisk means every value, and
*/15in the first field means every 15 minutes.-qkeeps wget silent and--delete-afterthrows away the page it downloads. Save and close the editor.text*/15 * * * * wget -q --delete-after https://example.com/wp-cron.phpStep 3: Switch off the check on page loads
Add this line above the line that says "That's all, stop editing!". From now on only the cron job starts scheduled tasks.
wp-config.phpdefine( 'DISABLE_WP_CRON', true );Step 4: Check that tasks still run
Wait half an hour, then list what is scheduled. The table shows each task's hook and when it runs next. A task whose time passed long ago means the cron job is not reaching WordPress: take the line out of
wp-config.phpuntil you have found out why.wp cron testcannot help here, because it reports an error as soon as it finds the constant.bashwp cron event list
To undo it, remove the line from wp-config.php first, then remove the line from the crontab.
If requests to wp-cron.php are blocked
WP-CLI can run the due tasks with no web request, so a password or a firewall in front of the site does not get in the way. Use this line in place of the wget line. Change both paths to yours: command -v wp prints the first, and the second is the folder that holds wp-config.php.
*/15 * * * * /usr/local/bin/wp cron event run --due-now --path=/home/example/public_html --quietA cron job that makes the backup itself
With SSH access and WP-CLI, the server can make the backup with no plugin and no WP-Cron. wp db export writes the database to a file, using the database name and password already in wp-config.php, and tar packs the files.
Step 1: Find the path to WP-CLI
Cron starts commands with
/bin/shand a few settings of its own, not with the setup of your login. A command that works when you type it may not be found there, so the script names WP-CLI by its full path. This prints it.bashcommand -v wpStep 2: Save the script
Save this in your home folder. Set
WPto the path from the last step andSITEto the folder that holdswp-config.php. The backups go to a folder in your home folder and not in the site's folder, where anyone could download them.wp-backup.sh#!/bin/sh set -eu WP=/usr/local/bin/wp SITE="$HOME/public_html" DEST="$HOME/backups" STAMP=$(date +%Y-%m-%d-%H%M) mkdir -p "$DEST" "$WP" db export "$DEST/$STAMP-database.sql" --path="$SITE" --quiet gzip "$DEST/$STAMP-database.sql" tar -czf "$DEST/$STAMP-files.tar.gz" -C "$SITE" . find "$DEST" -type f -name '*.gz' -mtime +13 -deleteStep 3: Run it once by hand
The script prints nothing when it works. The listing should show two new files named with today's date and the time, one ending in
-database.sql.gzand one in-files.tar.gz, each of a believable size.bashsh ~/wp-backup.sh ls -lh ~/backupsStep 4: Schedule it
Run
crontab -eand add these lines. The second runs the script at 2:30 every night by the server's clock, which may not be in your time zone. Cron mails whatever a job prints, and this script prints only when something goes wrong. Whether that mail leaves the server depends on the host.textMAILTO=you@example.com 30 2 * * * sh $HOME/wp-backup.shStep 5: Send the copies off the server
Add this as the last line of the script, with the address of a machine or storage service you can reach over SSH with a key. It copies the contents of the backups folder there.
wp-backup.shrsync -a "$DEST/" backups@backup.example.com:wordpress/
What to know about the script:
- It stops at the first command that fails.
set -edoes that, so nothing old is deleted on a night when the new backup was not made. - It keeps two weeks on the server. The
findline deletes archives that are 14 days old or older. Each run writes a full copy of the site, so check that the account has room for 14. - The far side keeps everything. rsync does not delete files at the destination unless told to. Set a rule for old backups there too.
- Keep the date format in the script. In a crontab line, cron turns a
%into a line break unless it has a backslash in front.
A store needs the database more often than nightly. Put the wp db export and gzip lines in a second script and schedule it with 0 * * * *, which is every hour on the hour.
To undo all of this, remove the lines from the crontab and delete the script.
Prove that a backup restores
Do not test by restoring over the live site. A restore replaces everything added since the backup was taken. Restore to a private copy, which how to set up a WordPress staging site covers making.
For a plugin's backup, use the plugin's restore screen on that copy. For a host's, ask whether a backup can be restored to a staging copy and not over the live site. For the archives the script above makes, the steps are these.
Step 1: Make an empty staging site
Create a subdomain with its own folder and a new, empty database, as the staging guide describes.
Step 2: Unpack the files into it
Use the name of the archive you are testing and the staging folder.
bashtar -xzf ~/backups/2026-10-07-0230-files.tar.gz -C ~/staging.example.comStep 3: Point the copy at the staging database
Change the database name, user and password in the copy's
wp-config.php, as the staging guide shows. Then check from inside the staging folder. This must print the staging database's name, not the live one.bashcd ~/staging.example.com wp config get DB_NAMEStep 4: Import the database
Still in the staging folder. The first line unpacks the export and keeps the compressed file. WP-CLI answers "Success: Imported from" and the file's name. Delete the unpacked
.sqlfile afterwards.bashgzip -dk ~/backups/2026-10-07-0230-database.sql.gz wp db import ~/backups/2026-10-07-0230-database.sqlStep 5: Finish the copy and look at it
Follow the rest of the staging guide: change the address in the database, and keep the copy private and unable to send email or take payments. Then log in, open a post from the past few days and an image from the media library, and on a store look for a recent order. Note how long the restore took.
Repeat the restore monthly, with the other checks in the WordPress maintenance checklist.
What not to rely on
- A copy that exists only on the site's server. It is lost with the server.
- A schedule nobody looks at. A schedule can stop without saying so, and no mail from cron can mean the job never ran. Read the date of the newest backup in the storage every week. WordPress's documentation also recommends a backup made by hand once in a while.
- Last night's backup before an update. Take a fresh one first, as how to safely update WordPress describes.
If you would rather not run this yourself, our WordPress backup service takes a daily backup as part of a care plan, stores it offsite and keeps it for 30 or 90 days depending on the plan.
Common questions
My site gets few visitors. Will scheduled backups still run?
They run late, not never. WP-Cron keeps a due task in its queue and runs it at the next page load. On a site that goes a day without a visit, a daily backup can slip by a day. A cron job that calls wp-cron.php every 15 minutes, as described above, removes the wait.
Can I schedule backups without SSH access?
Yes. A host's backups and a backup plugin need no SSH. For the cron job that calls wp-cron.php, look for a cron jobs screen in your hosting control panel, or ask the host to add the line for you.
What time should backups run?
At the hour when the site is quietest. A backup made by a plugin or a cron job is built by your own server, so it competes with visitors for the server while it runs.

