The definitive guide to disabling auto updates in WordPress 3.7

There are a lot of ways to adjust automatic background updates. A number of constants and filters offer a range of control, from the fine-grained to the heavy-handed. I will readily admit there are a few compelling reasons to disable auto updates, including:

  • You manage your site using version control
  • You implement your own deployment mechanism (potentially to multiple servers)
  • You are a managed WordPress host and feel confident in pushing timely updates yourself

I’d argue that “I don’t want them” is not a compelling reason for disabling updates. If you don’t keep your site up to date, you are making the web a less safe place for you and everyone who visits your website.

Background updates are incredibly, incredibly safe. Sites already running WordPress 3.7 have attempted more than 110,000 updates without a single critical failure, thanks to a number of verification steps that have made updates that much more reliable. A background update for a minor or security release (which is all they are enabled for, by default) means downloading and copying over just a few files. We’ve gotten really good at that. We’ve also spent years honing our craft of shipping stable and targeted fixes in minor releases — we don’t indiscriminately backport bug fixes. They must be serious bugs, and fixes go through additional levels of review, including at least two lead developers. And, we have the ability to roll out an automatic update over a period of hours or days. For 3.7.1, we’ll likely see how a few hours of user-initiated updates go before telling about 1% of sites to update, then steadily increase that percentage.

Automatic updates also support older branches. If the current version is 3.8.1, and we release a new 3.8.2 security release, we now have the option to release a 3.7.2 package with those fixes so 3.7 and 3.7.1 installs can automatically update to a secure version. (You’ll still be told to update to 3.8.2, of course.) Yes, automatic updates will definitely change how we approach maintenance releases and security fixes. We’d love the opportunity to keep lagging installs secure. I’d also expect more frequent maintenance releases for the current branch of WordPress, since update fatigue is much less of an issue now.

Updates are also really fast. Installs take about 24 seconds to update on average, but that includes downloading and unzipping the package. A core update should put your site into maintenance mode for only a few seconds.

What if you want automatic updates, but your site is telling you it is unable to apply these updates automatically? [Updated:] There is a new plugin, Background Update Tester, that will explain exactly why your site doesn’t support automatic background updates, and if necessary, what to ask your web host. This didn’t ship in core because it’s a pretty complicated flowchart and most options for recourse are complicated and technical. We think about 80 percent of installs support automatic updates. Most common reasons why they don’t work: your install’s file permissions require us to use FTP, and we don’t know your password; you have it disabled (or are using version control, see below); the WordPress cron (which also handles things like scheduled posts) doesn’t work on your server; or your install doesn’t allow for secure communication with WordPress.org. There are also situations (like inconsistent file permissions) where WordPress thinks it can do an update, but when it tries to, it finds out it can’t. (Your install will email you in that case.)

It’s worth noting that the “automatic updater” controls more than just WordPress core. If the updater finds it can’t or shouldn’t update, it’ll still send site administrator an email. (Want to disable only that? It’s also covered in this post.) The automatic updater also supports themes and plugins on an opt-in basis. And by default, translations (for themes, plugins, and eventually core) are updated automatically. At some point in the future, the WordPress.org plugin security team will be able to suggest that installs automatically update malicious or dangerously insecure plugins. That’s a huge win for a safer web.

It’s pretty clear that disabling the entire updater also disables some pretty nice features! Selectively disabling only what you want is going to be best. So, here’s the different ways to disable automatic background updates:

1. Use version control.

If WordPress detects a version control system, it recognizes you know what you are doing and avoids automatic updates of any kind. It looks for Subversion, Git, Mercurial, and Bazaar, and it looks everywhere.

It works by searching two directories (ABSPATH and whatever you are updating, like WP_PLUGINS_DIR, or WP_LANG_DIR) for VCS directories (.svn, .git, .hg, .bz). And it looks a level up, too — and keeps looking until it reaches the root of the drive. So if you are running a single Subversion checkout at / or /var/www/ or /var/www/mysite.com/, the WordPress install at /var/www/mysite.com/public_html/wordpress/ will be blocked from receiving updates. Clearly, it errs on the site of caution.

There is a filter, automatic_updates_is_vcs_checkout. If you’d like to use automatic updates anyway, you can just return false through that filter. The filter is also passed the directory it is searching in addition to ABSPATH, so if you wanted to update languages even though you were running a Subversion checkout, this would work:

function update_languages_vcs( $checkout, $context ) {
	if ( $context == WP_LANG_DIR )
		return false;
	return $checkout;
}
add_filter( 'automatic_updates_is_vcs_checkout', 'update_languages_vcs', 10, 2 );

If WordPress can’t update due to version control, the admin email will still get notified of new minor releases.

One technique that may interest some is to allow automatic updates even when using version control, with the intention of then checking in the changes once you get around to it. For the personal site of a busy developer, it’s an intriguing idea.

2. Disallow all file changes, period.

Most people are not going to want to use this one (honestly, please don’t), but if you are already doing your own deployments or are managing multiple servers, you might already be.

The DISALLOW_FILE_MODS constant blocks any kind of filesystem changes, not just by background updates but by all users as well. So, gone are the file editors; the ability to update core, themes, or plugins; and the ability to install new themes or plugins. This is crazy stupid to use unless you know exactly what you are doing. I am only mentioning it because I wanted to make it clear that automatic updates is smart enough to avoid breaking any custom deployments.

This will also block the update notifications sent via email for minor core releases.

3. Disallow the entire automatic updater.

The constant AUTOMATIC_UPDATER_DISABLED can be used to disable the automatic updater entirely. It’s like DISALLOW_FILE_MODS — no changes allowed at all — but it’s specific to the auto updater.

Don’t use this to block only core updates! You’ll also be blocking a lot of other functionality. You won’t get translation updates (language packs) for core, themes, and plugins. You won’t receive update notifications sent via email to alert you of new WordPress releases. It also disables all opportunity for fine-grained control.

There are very limited use cases for disabling the automatic updater but not disabling all file changes with DISALLOW_FILE_MODS. Just remember it disables everything, not just core updates, which are just one component.

There’s also a filter by the same name, automatic_updater_disabled. (It overrides the constant.)

4. Disable only core updates.

The easiest way to manipulate core updates is with the WP_AUTO_UPDATE_CORE constant:

# Disables all core updates:
define( 'WP_AUTO_UPDATE_CORE', false );

# Enables all core updates, including minor and major:
define( 'WP_AUTO_UPDATE_CORE', true );

# Enables core updates for minor releases (default):
define( 'WP_AUTO_UPDATE_CORE', 'minor' );

There are also some filters you can use for even finer control, which override the constant if used: allow_dev_auto_core_updates (like updating from 3.7-RC to 3.7-RC2), allow_minor_auto_core_updates (updating from 3.7 to 3.7.1), allow_major_auto_core_updates (3.7 to 3.8). Return true through these filters to allow such updates, false to disallow.

5. Manipulate core, plugin, theme, and translation updates as they are prepared to be run.

The previous configuration options are all-or-nothing. You may, however, want something more fine-grained. The auto_update_$type filter (auto_update_core, auto_update_plugin, auto_update_theme, auto_update_translation) is fired for specific updates, as they are ready to be updated. This filter is passed the actual update object that describes what WordPress is about to update. This means you can selectively enable individual plugins or themes to update, for example, or whitelist upcoming core updates.

6. Manipulate whether notification emails are sent

Emails are sent in three situations: a result email after a core auto update, a notification email when WordPress can’t update irself, and a debugging email when running a development version of WordPress (alpha/beta/RC).

The result email comes in three forms:

  • A successful update. Nice!
  • An update that couldn’t occur. As in, WordPress tried to update, but failed early, like an inconsistent permissions error it was able to catch.
  • A critical failure, when the update failed in the middle of copying files.
  • (Note, we’ve yet to see a single critical failure in the wild. Yeah, it’s that reliable.)

    You can stop these emails from being sent by returning false via the auto_core_update_send_email filter:

    /* <a href='http://profiles.wordpress.org/param' class='mention'>@param</a> bool   $send        Whether to send the email. Default true.
     * <a href='http://profiles.wordpress.org/param' class='mention'>@param</a> string $type        The type of email to send.
     *                            Can be one of 'success', 'fail', 'critical'.
     * <a href='http://profiles.wordpress.org/param' class='mention'>@param</a> object $core_update The update offer that was attempted.
     * <a href='http://profiles.wordpress.org/param' class='mention'>@param</a> mixed  $result      The result for the core update. Can be WP_Error.
     */
    apply_filters( 'auto_core_update_send_email', true, $type, $core_update, $result );
    

    Next, the core notification email is controlled by the send_core_update_notification_email filter. By default, administrators are notified when the update offer received from WordPress.org sets a particular flag — of course, only if the install is unable to update. It’ll only email you once per new version, unless the admin email changes. Returning true means the install will always email you when there is a new update, even if the API has not yet instructed the install to do so. Returning false prevents the email from ever being sent.

    Finally, the debugging email is a complete log output of all auto updates performed — core, translations, plugins, and themes. It is as if you clicked update yourself and watched the text scroll by; it also includes additional error data if something went wrong. This email controlled by the automatic_updates_send_debug_email filter. Returning false will prevent this email from being sent when running a development install, while returning true will send this email to all versions, including when you’re on a stable release.

    ***

    In the end, please choose wisely. If you’re going to block core updates, use WP_AUTO_CORE_UPDATE.

    I’ve gotten this question a few times now: should hosts that offer WordPress update services be disabling self-updates? I have no qualms with hosts who plan to reliably provide their own updates in a timely manner to do updates on their own. Because they have full, unadulterated access to the server, they can do it much more effectively than WordPress can. They can also offer support services. It’s also much more awesome to have a hosting company on board, than to lean back and rest on WordPress’s laurels. Many hosting companies are also setting the bar high and paving the way forward by pushing out major releases after a few weeks of testing, which is fantastic. Of course, this means the host must act immediately and responsibly to push out maintenance and security releases. This is something most of them are already doing, even inside the first 12 hours. (That’s how often installs check WordPress.org to see if there is a pending update.) Honestly, I’m just really excited about how much the community is embracing all of this!

    So, if you’re a managed host that handles your own updates, consider using WP_AUTO_CORE_UPDATE versus completely disabling the entire automatic updater. (If you want to send your own emails, block the ones WordPress sends using the send_core_update_notification_email filter.) There’s a lot more to come here, and it would be a shame if users were cut off from its full potential.

    If you are a developer who wants to learn more, start with the WP_Automatic_Updater class in wp-admin/includes/class-wp-upgrader.php. Also check out @dd32‘s previous post.