---
title: "How to schedule automatic WordPress backups | WP Ministry"
url: https://wpministry.co/blog/schedule-automatic-wordpress-backups/
description: "Schedule backups at your host, in a plugin or with a cron job. Each must copy the database and files, send them off the server, and be restored once as proof."
lang: en-US
---

Skip to content

# 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

October 7, 2026

## 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.php` and `.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 (https://wpministry.co/blog/best-wordpress-backup-plugins/) 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.

1. ### 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.
2. ### 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.
3. ### 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.
4. ### 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" (https://wpministry.co/errors/could-not-complete-a-loopback-request/) means WordPress cannot make the request to itself that starts them.
- **WP-CLI.** `wp cron test` tries 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.

1. ### 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 -l` prints the list without editing it.
   bash Copy

   ```
   crontab -e
   ```

2. ### Step 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 `*/15` in the first field means every 15 minutes. `-q` keeps wget silent and `--delete-after` throws away the page it downloads. Save and close the editor.
   text Copy

   ```
   */15 * * * * wget -q --delete-after https://example.com/wp-cron.php
   ```

3. ### Step 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.php Copy

   ```
   define( 'DISABLE_WP_CRON', true );
   ```

4. ### 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.php` until you have found out why. `wp cron test` cannot help here, because it reports an error as soon as it finds the constant.
   bash Copy

   ```
   wp 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`.

text

```
*/15 * * * * /usr/local/bin/wp cron event run --due-now --path=/home/example/public_html --quiet
```

## A 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.

1. ### Step 1: Find the path to WP-CLI
   Cron starts commands with `/bin/sh` and 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.
   bash Copy

   ```
   command -v wp
   ```

2. ### Step 2: Save the script
   Save this in your home folder. Set `WP` to the path from the last step and `SITE` to the folder that holds `wp-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 Copy

   ```
   #!/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 -delete
   ```

3. ### Step 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.gz` and one in `-files.tar.gz`, each of a believable size.
   bash Copy

   ```
   sh ~/wp-backup.sh
   ls -lh ~/backups
   ```

4. ### Step 4: Schedule it
   Run `crontab -e` and 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.
   text Copy

   ```
   MAILTO=you@example.com
   30 2 * * * sh $HOME/wp-backup.sh
   ```

5. ### Step 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.sh Copy

   ```
   rsync -a "$DEST/" backups@backup.example.com:wordpress/
   ```

What to know about the script:

- **It stops at the first command that fails.** `set -e` does that, so nothing old is deleted on a night when the new backup was not made.
- **It keeps two weeks on the server.** The `find` line 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 (https://wpministry.co/blog/set-up-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.

1. ### Step 1: Make an empty staging site
   Create a subdomain with its own folder and a new, empty database, as the staging guide describes.
2. ### Step 2: Unpack the files into it
   Use the name of the archive you are testing and the staging folder.
   bash Copy

   ```
   tar -xzf ~/backups/2026-10-07-0230-files.tar.gz -C ~/staging.example.com
   ```

3. ### Step 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.
   bash Copy

   ```
   cd ~/staging.example.com
   wp config get DB_NAME
   ```

4. ### Step 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 `.sql` file afterwards.
   bash Copy

   ```
   gzip -dk ~/backups/2026-10-07-0230-database.sql.gz
   wp db import ~/backups/2026-10-07-0230-database.sql
   ```

5. ### Step 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 (https://wpministry.co/blog/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 (https://wpministry.co/blog/how-to-safely-update-wordpress/) describes.

If you would rather not run this yourself, our WordPress backup service (https://wpministry.co/services/wordpress-backups/) 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.

## More on this subject

- WordPress maintenance and care plans: https://wpministry.co/topics/wordpress-maintenance/
- Error fix How to fix "Another update is currently in progress" in WordPress: https://wpministry.co/errors/another-update-is-currently-in-progress/
- Error fix How to fix "Update failed: Download failed." in WordPress: https://wpministry.co/errors/download-failed/
- Resource A sample WordPress maintenance report: what ours says, line by line: https://wpministry.co/resources/sample-wordpress-maintenance-report/
- Glossary term Post revisions: https://wpministry.co/glossary/post-revisions/
- Glossary term Shortcode: https://wpministry.co/glossary/shortcode/
- Glossary term Staging site: https://wpministry.co/glossary/staging-site/

## Would you rather we looked after it?

The Essential plan is $39 a month. Updates, backups, monitoring and security scanning. No edit time. No minimum term.

More about this work: WordPress maintenance service (https://wpministry.co/services/wordpress-maintenance/)

May we measure how this site is used?

A yes notes the pages of this visit and loads Google Analytics. A no keeps and loads nothing. See the cookies page (https://wpministry.co/legal/cookies/).

If you say yes, we note the pages you look at during this visit and load Google Analytics. If you say no, nothing is kept and nothing is loaded. The site works the same either way. The cookies page (https://wpministry.co/legal/cookies/) has the details.

## Structured data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://wpministry.co/#organization",
      "name": "WP Ministry",
      "url": "https://wpministry.co/",
      "logo": "https://wpministry.co/brand/logo.png",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "1309 Coffeen Ave STE 1200",
        "addressLocality": "Sheridan",
        "addressRegion": "WY",
        "postalCode": "82801",
        "addressCountry": "US"
      },
      "sameAs": [
        "https://www.linkedin.com/company/wp-ministry/",
        "https://x.com/wpministryco",
        "https://www.instagram.com/wpministryco/",
        "https://www.facebook.com/wpministryco",
        "https://www.tiktok.com/@wpministryco",
        "https://www.pinterest.com/wpministryco/",
        "https://www.youtube.com/channel/UCOZRuAukk5QSTRPG6BaHl3Q"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://wpministry.co/#website",
      "name": "WP Ministry",
      "url": "https://wpministry.co/",
      "inLanguage": "en-US",
      "publisher": {
        "@id": "https://wpministry.co/#organization"
      }
    },
    {
      "@type": "Article",
      "@id": "https://wpministry.co/blog/schedule-automatic-wordpress-backups/#article",
      "headline": "How to schedule automatic WordPress backups",
      "description": "Schedule backups at your host, in a plugin or with a cron job. Each must copy the database and files, send them off the server, and be restored once as proof.",
      "url": "https://wpministry.co/blog/schedule-automatic-wordpress-backups/",
      "mainEntityOfPage": "https://wpministry.co/blog/schedule-automatic-wordpress-backups/",
      "inLanguage": "en-US",
      "image": "https://wpministry.co/og/blog/schedule-automatic-wordpress-backups.png",
      "author": {
        "@id": "https://wpministry.co/#organization"
      },
      "publisher": {
        "@id": "https://wpministry.co/#organization"
      },
      "datePublished": "2026-10-07T00:00:00.000Z",
      "dateModified": "2026-10-07T00:00:00.000Z"
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://wpministry.co/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Guides",
          "item": "https://wpministry.co/blog/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "How to schedule automatic WordPress backups"
        }
      ]
    }
  ]
}
```