Automatic Updates in WordPress

This week, the topic of automatic updates in WordPress came up. Here’s a bit of a guide on how it all works, how to disable them, and so forth.

Automatic Updates?

First, “automatic” is a very problematic term given the history, so let’s define terms a bit.

In The Beginning…

When WordPress first came out, whenever you wanted to update to the next version of things, you had to manually download and install the update. This changed in WordPress 2.5 (March 2008) with, what was often referred to as, “automatic updates”. This post isn’t talking about these “one-click updates“.

The Humanless Era Begins For Minor Updates & Developers

The era of “background updates“, those updates that are possible without human interaction, began in WordPress 3.7.

WordPress 3.7 (October 2013) was billed as a very developer-heavy release. There weren’t really any splashy features—background updates, improved password meter, improved search. Under the hood, this release laid the groundwork for a ton of stuff.

The most visible impact of 3.7, at the time, in regards to updates was that now WordPress could update itself in the background and would start doing so for maintenance releases (e.g. 3.7 to 3.7.1 to 3.7.2).

In addition to the ability to update Core itself, the underlying guts for themes or plugins to background update were in place. There was no user interface for this—had to add a bit of code to activate.

The guts that allowed for plugin background updates also allowed for “background security updates” or “forced updates”. More on this in a bit.

Humanless Reaches The Masses

By WordPress 5.6 (December 2020), the underlying guts had seen various improvements over the years and now the ability to modify background updates expanded to everyone.

WordPress 5.6 included the user interface to enable site owners to indicate individual plugins could background update or even WordPress itself with major updates.

Generally speaking, this was adding UI to the existing framework, but the actual process is the same.

Summary of Terms

In short, “automatic” updates could refer a few different things:

One-Click Updates, with the wp-admin ability to upgrade, added in WP 2.5.

Background Updates added in WP 3.7 with expanded UI added in 5.6.

Forced Updates also added in 3.7 with no UI.

A Special Note About Forced Updates

What Is A Forced Update?

Forced Updates aren’t really a different thing than Background Updates. When a site checks for updates, it informs the API of the current version, the version of WordPress, and the version of PHP running on the site. The API then responds with what upgrade that site is being offered. If you’re running a modern version of WP and PHP, usually, it is the latest stable version of the plugin.

If you’re running an older version of PHP or WordPress that is older than the minimum supported version for the latest version of the plugin, it won’t offer you an upgrade at all.

For a Forced Update, the API responds a little differently. First, if you’re on an older version, it will only offer you the immediate patch for the security issue. For example, if Cool Plugin 2.0 is the latest version and you’re running Cool Plugin 1.5, the API will see that and respond with Cool Plugin 1.5.1 for your update (as opposed to 2.0) and mark it as a forced update (or autoupdate in the response). The overall mechanism is the same for regular upgrade offerings and a forced upgrade offering.

How Does An Update Become Forced?

Jetpack is one of the most installed plugin in the WordPress ecosystem and, as such, anytime there is a potential security issue discovered, it’s a Big Deal by way of the number of sites potentially impacted. We take that responsibility seriously, so we’ve had three “Forced Updates” since this became possible in 2013.

The process has been we discover an issue. This is often from our internal security folks trying to find issues or from a responsible person disclosing to us via our HackerOne bounty program (yes, we pay people who find security issues and report them directly to us).

Once we validate the proof of concept and confirm there is an issue, we determine the severity and the scope of the issue. How bad is it and how many people could it impact? At the same time, we determine the smallest possible solution to mitigate the issue. Generally, this is not the time to do a whole-hog refactor or something.

With all that information in place, if we think the issue is potentially serious, we will contact the WordPress Plugins Team. These folks, none of whom work for Automattic, can help advise us on next steps.

If they concur the issue is serious, they advise on if the fix should be backported to older versions or not. In such a case, there are some very important and firm guidelines:

To the extent feasible, we need to fix everyone possible. If the problem exists in five versions (e.g. 1.1, 1.2, 1.3, 1.4, 1.5), then we should provide patched versions for each of those versions.

The updated versions can only contain the smallest change possible to mitigate the issue. This is not a time to fix other bugs, add features, or anything. It is exclusively to fix the issue discussed.

After that, we go back and fix everything and prepare releases.

When everything is ready, we check-in the new versions to the plugins repo and the WordPress Meta Team updates the API to give the modified response for these versions.

Disclaimer: I suppose I could be considered on the Meta team since I help maintain parts of WordPress.org. I don’t have the authorization nor the access rights to modify the API.

How To Control These Updates?

One-Click Updates

If you want to really lock down your site and disallow, basically, everything, you can do that with a single line in your wp-config.php file:

define( 'DISALLOW_FILE_MODS', true );

This will disable all updates—background, one-click, or manual. You will not be able to install new plugins or themes. It’ll actually disable the Upgrader completely to the point that you won’t be able to see pending upgrades.

I do not suggest using this unless you have extremely specific needs and have the resources to ensure your site is up to date manually.

A common use of this, though, is to mark your production site with DISALLOW_FILE_MODS while running a staging site without it. You can make changes to the staging site, then deploy them to production when you’re ready.

Background Updates

There are a few different ways to control Background Updates.

Via UI

Via the wp-admin user interface, you can control WordPress Core updates via the Dashboard->Updates page.

For plugins, visit Plugins->Installed Plugins and select “Enable auto-updates” option for each individual plugin you’d like to background update.

For themes, visit Appearance->Themes, then choose “Theme Details” for each theme you’d like to background update. On the details page that opens, you’ll see an option to enable updates under the title and author.

The UI options have no effect on Forced Updates.

The UI options have no effect on Forced Updates. You can think of this as replacing the need for One-Click Updates.

Via Code

The DISALLOW_FILE_MODS constant mentioned above will still work, but you have a lot more granular control too.

For the sake of being complete, if your server’s user does not have permission to access the file system or you’re on a version-controlled setup, background updates won’t work. For Core updates, you’ll get an e-mail about them.

Segment | Method | Possible Values | Notes
All | Constant: AUTOMATIC_UPDATER_DISABLED | boolean | False also disables update notification e-mails for Core.

All

Filter:
automatic_updater_disabled

boolean

Default: Value of AUTOMATIC_UPDATER_DISABLED

False will disable notifications too. Overrides the constant above. The below values do not override this. This would still allow UI updates without allowing any background updates. See below the table, though, for an alternative.

Core

Constant: WP_AUTO_UPDATE_CORE

false (bool) – No background updates for Core
minor – Only security/maintenance updates for Core
true (bool) or beta, rc, development, branch-development – All updates allowed.

Filters can still override this behavior.

Core

Filter: allow_dev_auto_core_updates

boolean

Default: False unless WP_AUTO_UPDATE_CORE is set to allow all updates.

If the site is currently on a dev version (alpha/beta), should it background update Core.

3.7-alpha-2500->3.7-alpha-25678->3.7-beta1, etc.

Core

Filter:
allow_minor_auto_core_updates

boolean

Default: True unless WP_AUTO_UPDATE_CORE is false.

3.7.0->3.7.1->3.7.2

Core

Filter:
allow_major_auto_core_updates

boolean

Default: False, unless WP_AUTO_UPDATE is set to allow all updates.

3.7.0->3.8.0->3.9.1

Themes

Filter:
themes_auto_updates_enabled

boolean

Default: Generally true, unless the automatic_updater_disabled constant/filter are false.

This is more the themes system being enabled. This doesn’t mean it will upgrade individual plugins. This can be overridden by Forced Updates.

Plugins

Filter:
plugins_auto_updates_enabled

boolean

Default: Default: Generally true, unless the automatic_updater_disabled constant/filter are false.

This is more the plugins system being enabled. This doesn’t mean it will upgrade individual plugins. This can be overridden by Forced Updates.

Plugins/Themes

Filters against the auto_update_themes and auto_update_plugins options

Individual plugin and theme background update settings are stored in these options. If you wanted a confusing experience, you could filter these options. I wouldn’t personally.
This can be overridden by Forced Updates.

———– | Important Note! | Everything above allowing a background update can be overridden by the the API to disable a background update. | I’m not sure how/if this has been used, but it is possible. I would guess this is a way that WordPress.org can throttle the rate of downloads by marking something as disable_autoupdate for a percentage of sites. Just a guess.

All

Filters:
auto_update_core
auto_update_plugin
auto_update_theme
auto_update_translation

boolean

These filters also pass $item which is the upgrade object response from the API. You can use these filters to more selectively control updates via code. Want to allow only plugins whose slug begins with a, this is your filter. Or a more realistic setup would be to allow background updates only from a select allow list.

As you can see, there is a lot of flexibility for site owners who wish to have a very specific background update solution. While Forced Updates are given a lot of preference, you can still disable them via the auto_update_{$type} filters.

One idea, if you’re concerned about an autoupdate, but want to be aware, is to hook into those filters and if $item->autoupdate is true, send you an e-mail, before returning false. That way you’d know you’re missing the update but you can completely control when your site’s code is modified.

When do these updates happen?

Generally, every 12 hours. There are wp_update_plugins, wp_version_check and wp_update_themes cron events that are set to run twice daily. There’s not a set time—on every page load, WordPress checks to see if the check is scheduled. If it isn’t, it schedules it for immediately and then every 12 hours thereafter.

One more note about Jetpack

While I’m here, before Core added the UI for background updates, Jetpack had one that was accessible via WordPress.com for connected sites. For while there, this system did not use the same filters as above. With WordPress 5.6 bring a renewed focus to background updates, we modified our system to use the same options and filters as Core’s. The above should all still work the same for any autoupdates selected via the WordPress.com interface for connected Jetpack sites.

I hope this help explains things a bit more with a bit more specificity than a lot of the conversations around “automatic updates” .