Support

Documentation

Caveats of using WP-CRON for backup scheduling

Executive summary (TL;DR)

The default configuration of WP-CRON runs tasks based on visitors coming to your site. This may cause the backups to run at unexpected times (or not at all), take too long to complete (or fail to complete), makes your site feel slower, and creates data consistency issues in backups. The reason for that is, per WordPress' own admission, that “WP-Cron does not run continuously, which can be an issue if there are critical tasks that must run on time”. You can follow the instructions on the linked page to make WP-CRON run reliably, or you can use a different scheduling method. If you decide to use WP-CRON in its default configuration your backups might be unreliable and we will be less likely to be able to help you.

Why backups need to be split in many steps

Taking a backup is a long process which involves reading the entirety of your site's database contents and files, compressing them, and putting them into a backup archive file. By the very definition of what a backup is, it requires a not insignificant amount of time and resources (CPU compute, memory, disk) to execute.

Commercial servers are inherently “stingy” with the resources they allow a script to consume. They will only allow a script to use a limited amount of memory, and usually have an upper limit of CPU time which may be used by the script. The former is controlled at both the server Operating System and PHP level. The latter is controlled at the server Operating System, PHP, and web server (Apache, NginX, LiteSpeed, …) level. If a script tries to use more resources than the server allows it is terminated (“killed”) before reaching completion.

As a result, trying to execute a full site backup on anything but the tiniest sites on the fastest hosts would mathematically result in exceeding the resource allowance imposed by the server, the backup script would be terminated before reaching completion, thus the backup would fail.

To address this conundrum, Akeeba Backup splits the backup process into several discrete Steps. Each step uses resources within the resource budget afforded by the server's limitations and executes in a separate page load. Each step essentially acts as its own partial backup script, completing a fractional part of the backup process without getting terminated by the server.

Backups need something to tell them to execute — and how it relates to backup speed

However, this also means that there needs to be something which tells each step to execute after the previous step finishes, let's call it the controller. The controller in the case of backups taken from the web interface is the JavaScript running on your browser. When scheduling backups with a third party service, the controller is the third party service itself. When using WP-CRON for backup scheduling the controller is WordPress' WP-CRON.

It is absolutely critical that the controller executes reliably and consistently. If the controller stops executing before the backup even starts then the first Step of the backup will never run, i.e. the backup never starts. If the controller stops executing the backup will finish its latest Step and then stay there, unfinished, waiting. If the controller takes a long time between successive executions this "dead" time will be added to the total time it takes to execute the backup, prolonging the backup.

For example, let's say that each step takes an average of 10 seconds. If the controller executes continuously —as is the case with the JavaScript controller in backend backups— as soon as one Step finishes, the controller will immediately launch the next Step. The "dead" time will be in the order of a few millionths of a second. If the backup needs ten steps to complete the backup will finish in 100 seconds — just under two minutes.

Let's take the same backup, but using a controller which executes once every 60 seconds. Once a Step finishes after an average of 10 seconds there is an average of 50 seconds of "dead" time until the controller executes again. With 10 steps to complete the backup the total time to run the backup is now 600 seconds — ten minutes, five times as much as the backend backup.

If we have an unreliable controller which may take several minutes to several hours between subsequent executions this "dead" time will be added to the total time to back up the site. Our backup which normally takes under two minutes may now take hours to execute.

As you understand, having an unreliable controller with a large site backup —which typically takes several hundred steps to complete— may result in the backup taking days or weeks to finish! This is disastrous. It's impossible to guarantee backup consistency over such a long period of time.

The default WordPress configuration for WP-CRON makes for an unreliable controller

Per WordPress' own admission “WP-Cron does not run continuously, which can be an issue if there are critical tasks that must run on time”.

What this says is that WP-CRON is not a controller which runs all the time. It is only executed when there is traffic to your site, i.e. when there are site visitors. Even then, WP-CRON only executes once every 60 seconds (this can be overridden by setting the WP_CRON_LOCK_TIMEOUT constant in your wp-config.php file).

In this configuration, critical tasks such as running backups or sending time-sensitive marketing newsletters are NOT guaranteed to run at the time they are scheduled. They may run much later, or never, depending on when and whether your site receives traffic. A further complicating factor is that WP-CRON may have other overdue tasks to execute before the abwp_cron_scheduling task — the task used by Akeeba Backup to schedule its backups. This means that the backup will be further delayed.

Another complicating factor for scheduling backups with WP-CRON using its default configuration is that even if everything else goes optimally, to the Universe's and Murphy's Law's chagrin, you are still stuck with running backups when there is site traffic. This is bad for two reasons. One is data consistency: your site visitors may be modifying the site's database and/or file contents e.g. submitting posts, uploading media, submitting comments and contact forms, making purchases on WooCommerce and so on and so forth. The other reason is that taking a backup does use a lot of server resources which means that your site will appear to be slow, fail to load, or the backup may fail because the server is running out of resources trying to handle both the backup and the site visitors.

Therefore, the default configuration of WP-CRON will lead to backups possibly starting at the wrong time (or not at all), taking too long to complete, possibly not have very good data consistency (or even become corrupt), and is generally a bad idea.

[Warning]Warning

Using the WP-CRON in its default WordPress configuration (using site traffic to trigger scheduled tasks) for scheduling backups can only ever be done AT YOUR OWN RISK.

Due to the objective limitations (explained above) inherently imposed by the design of WP-CRON's default configuration (executing only when there is site traffic) we cannot guarantee the reliability or consistency of the backups, nor can we guarantee that we will be able to assist you should you have a backup or restoration issue beyond asking you to read this documentation and follow one of the two solutions provided below.

If you do, however, follow the Solution 1 stated below we will consider your use of WP-CRON to be FULLY SUPPORTED, your backups will be reliable, and we will be able to help you.

We kindly remind you that the aforementioned issues affect all WordPress backup plugins, not just ours, and they all have a similar policy on the matter for objective and fairly obvious reasons (none of us is in control of WordPress' code or your server's setup). We are the only ones who state this upfront. We hope that you appreciate our honesty.

Solution 1: Schedule wp-cron.php per the official WordPress documentation

The only solution for WP-CRON to become a reliable controller, as per its official documentation, is to not use its default configuration! Instead, you should schedule a CRON job on your server to execute wp-cron.php every minute. This does, indeed, solve most of the aforementioned problems. The backups can be scheduled to run when the site is less busy, thereby guaranteeing data consistency. For the same reason, your site will not appear to be slower when it's busy and backups are less likely to fail due to lack of server resources. The WP-CRON scheduling executes as a predictable controller every 60 seconds, making the backup time predictable as a result.

Solution 2: Don't use WP-CRON

Of course this raises the question: why should you use WP-CRON if you have to schedule a CRON job anyway? The only benefit is that you have the scheduling in the backend of your site, at the expense of backups running slower (we'll get to that).

If the cons outweigh the pros, we strongly recommend using a real, server-side CRON job with the CLI backup script or the WP-CLI integration to take a backup at full speed, with fewer restrictions.

If you are on a server which does not support CRON jobs you can use third party services such as WebCRON.org (schedule backups using the front-end backup URL), or Watchful (schedule backups using the JSON API) to automate your backups. Alternatively, you could use Akeeba Remote CLI on a different server which does support CRON jobs to take remote backups using the JSON API.

Backups run slower with WP-CRON

As explained at the first few paragraphs of this section, WP-CRON executes with a coarse granularity — at best once every minute, when using Solution 1 above. This adds a lot of "dead" time between consecutive backup steps, which increases the total backup time.

To avoid this issue, Akeeba Backup for WordPress will try to automatically adjust the Fine-tuning settings of your backup before starting a scheduled backup, trying to maximise the amount of time each step can take. This tries to take into consideration the WP-CRON frequency, your PHP maximum execution time (if it's set), and the server's configured CPU usage limit (on Linux, *BSD, and macOS servers only). Not all of these data points may be available on your server. It finds the maximum amount of time which satisfies all conditions and caps it to 60 seconds, in an attempt to avoid abusing the resources of your server.

In most practical uses cases and servers this reduces the "dead" time between backup steps from an average of 50 seconds to an average of 5 seconds. Your backups will still take longer (for a typical large site backup: about 5 minutes longer) than taking a backup from the backend of your site but it won't be as egregious as if we did not do this (for a typical large site backup: 1–2 hours longer).

The downside is that if your server does not report all of these pieces of information correctly, or at all, the choices made by Akeeba Backup may result in the backup inadvertently running out of server resource and getting terminated by the server.

If this happens log into WordPress, go to Akeeba Backup, scroll all the way down, click on System Configuration and set the “Override time limits in WP-CRON” option to “Conservative”. This will halve the maximum time used for the backup, making the backup much slower (typical large site backup: 30–60 minutes) but also less likely to fail. If this still doesn't help please send us a support request. We will ask you to set this option to No and give you Fine Tuning settings to apply to your backup profile's Configuration based on our analysis of the backup log file of your last failed backup attempt.