WordPress auto-update audit: a plugin you can build today

· 5 min read

WordPress has had automatic updates since version 3.7. The assumption most site owners and administrators operate on is that the setting is on and the updates are happening. That assumption breaks the moment a developer sets WP_AUTO_UPDATE_CORE to false in wp-config.php, a step that is common during initial build phases and that does not get reversed on launch day. The site looks maintained. The dashboard shows a version number. Nothing indicates that the machinery behind auto-updates has been switched off.

DISABLE_WP_CRON creates the same outcome from a different direction. When a hosting environment promises to handle cron jobs at the server level, a developer often disables WordPress's built-in cron to avoid duplicate runs. If the server cron is never actually configured, no scheduled tasks run, including the update check. The result is identical to having auto-updates disabled: the site stops updating, silently.

A plugin that reads these constants and the current version state puts the actual configuration on the dashboard, where it is visible without opening wp-config or running a WP-CLI command.

What one build gives you

  • Whether WP_AUTO_UPDATE_CORE is set and what its value means in plain language
  • Whether AUTOMATIC_UPDATER_DISABLED is blocking all automatic updates
  • Whether WP-Cron is disabled, which would prevent the update check from running
  • Whether the installed WordPress version matches the latest available from the update API
  • All four checks in a single dashboard widget with no configuration required

What it does not do

  • Plugin and theme auto-update settings, which are stored separately in site options
  • Whether a server cron is actually configured when DISABLE_WP_CRON is true
  • Multisite networks: the plugin audits the site it is installed on, not the whole network
  • Email alerts or scheduled notifications when the site falls behind
  • Any remediation: the plugin reads and reports configuration, it does not change it

ManageWP does these. This covers the part most sites use.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin called Update Config Audit. Plugin Name: Update Config Audit. Description: Dashboard widget showing your WordPress auto-update configuration at a glance. Single PHP file. No dependencies beyond WordPress core. Register a dashboard widget using wp_add_dashboard_widget with id uca_dashboard_widget, title Update Configuration, callback uca_render_widget. Hook the registration into wp_dashboard_setup. In uca_render_widget, output a table element with style width:100%;border-collapse:collapse. The table has a thead row with two th cells: Check and Status, both left-aligned. The tbody has four rows. Row 1 - Check cell: Core auto-updates. Status cell: Read WP_AUTO_UPDATE_CORE. If not defined: output Minor updates only (WordPress default) in color #46b450. If true (boolean true, string true, or string 1): output All updates enabled in color #46b450. If the string minor: output Minor updates only in color #46b450. If false (boolean false, string false, or string 0 or integer 0): output Disabled (WP_AUTO_UPDATE_CORE is false) in color #d63638. Row 2 - Check cell: Updater disabled. Status cell: Read AUTOMATIC_UPDATER_DISABLED. If defined and evaluates to true: output Yes - all automatic updates are blocked in color #d63638. Otherwise: output No in color #46b450. Row 3 - Check cell: WP-Cron. Status cell: Read DISABLE_WP_CRON. If defined and evaluates to true: output Disabled - verify a server cron is calling wp-cron.php in color #dba617. Otherwise: output Enabled in color #46b450. Row 4 - Check cell: WordPress version. Status cell: Call get_site_transient('update_core') into $update_data. Get current version with get_bloginfo('version') into $current. If $update_data is empty or $update_data->updates is empty or not set: output Current: [version] - update check has not run yet in color #dba617. Otherwise read $update_data->updates[0]->current into $latest. If $latest equals $current: output Up to date ([version]) in color #46b450. Otherwise output Current: [current] / Latest: [latest] - update available in color #d63638. Apply inline style color:[hex] to each status td. Escape all dynamic values with esc_html. Give each tr a style border-bottom:1px solid #f0f0f0 and each td and th a style padding:6px 4px.

Build this pluginAbout 55 credits · the free plan includes enough for one

Why the dashboard does not tell you auto-updates are off

The WordPress dashboard distinguishes between available updates and the mechanism that applies them. Dashboard > Updates shows plugins, themes, and a core version when one is available. It does not show whether auto-updates will ever fire. Two sites can display the same update screen: one where auto-updates will apply overnight, and one where they have been disabled since the site launched.

WP_AUTO_UPDATE_CORE is a constant that lives in wp-config.php, outside the database and outside anything WordPress reads when building the dashboard. Setting it to false at build time is a reasonable choice during development: you want control over when core updates land. The problem is that the constant travels with the wp-config.php file into production and stays there unless someone explicitly removes it.

DISABLE_WP_CRON is a separate problem. WordPress's cron system runs on page load, which is inefficient on high-traffic sites. Hosts and developers disable it in favour of a proper server cron, which is the right call. When the server cron is never set up, or is removed during a migration, the update check simply never runs. No error, no notice, no indication in the admin.

What the plugin reads and what it shows

The plugin adds one dashboard widget titled Update Configuration. It reads four things: the WP_AUTO_UPDATE_CORE constant and its effective meaning, whether AUTOMATIC_UPDATER_DISABLED is set, whether WP-Cron is disabled, and whether the currently installed WordPress version matches the latest available from the WordPress update API.

Each check shows green for a healthy state and a coloured warning for anything that would prevent updates from running. No settings screen, nothing to configure. The widget reads the current environment and reports it.

The version comparison uses the same transient WordPress itself populates when it checks for updates. If the transient is empty, the widget reports that the update check has not run, which itself indicates a WP-Cron problem.

The most common scenario the plugin catches

A developer sets WP_AUTO_UPDATE_CORE to false during a build. The site launches. The constant remains. Two years later, the site is running a version of WordPress that stopped receiving auto-updates on day one, and nobody has noticed because the dashboard version number looks like any other version number.

This is not a hypothetical. It happens whenever a developer builds on a staging environment with auto-updates disabled to avoid surprise changes, and the wp-config.php from staging becomes the wp-config.php in production. It happens when a hosting migration script copies configuration files without reviewing them. It happens when a developer leaves and the next person inherits a site without documentation.

The plugin makes the configuration visible in under a minute. For anyone who manages client sites or has inherited a site from another developer, running it once is a faster audit than reviewing wp-config manually.

When ManageWP or MainWP is the better answer

This plugin runs on one site and reports that site's configuration. If you manage ten or fifty sites, checking a dashboard widget on each one is not efficient. ManageWP and MainWP are both built for the multi-site case: they aggregate update state across a portfolio and let you apply or ignore updates from a single screen.

ManageWP also provides update scheduling, staging environments, and backup integration around the update workflow. If you are in an agency context with clients expecting managed updates, that infrastructure is worth the overhead. A single-site owner checking whether their configuration is correct is the case this plugin is actually for.

For anyone already paying for ManageWP or MainWP, the audit this plugin provides is a small subset of what those tools show. Run it during a site audit if you do not have those tools installed on the site you are checking, then uninstall it.

Questions

Does the plugin change any settings?

No. It reads constants and the update transient and displays them. It does not modify wp-config.php, change any options, or apply any updates.

Does it check plugin and theme auto-update settings?

No. The plugin audits WordPress core update configuration only. Plugin auto-updates are stored in a separate site option and are toggled per plugin from Dashboard > Plugins.

What should I do if WP_AUTO_UPDATE_CORE shows as disabled?

Open wp-config.php and find the line that sets the constant. Either remove it to restore default behaviour (minor updates on), or change the value to true to enable all core updates. After saving the file, the widget will reflect the new state on the next page load.

WP-Cron is showing as disabled. Is that a problem?

Only if no server-level cron is calling wp-cron.php on a schedule. DISABLE_WP_CRON is correct when your host or a developer set up a server cron job as a replacement. If no server cron exists, scheduled tasks including the WordPress update check will never run. Check with your host or look for a crontab entry pointing to your site's wp-cron.php file.

Does this work on a WordPress Multisite install?

The plugin installs and runs on a single site within a network. It shows the configuration for that site only. For update auditing across all subsites in a network, ManageWP or MainWP are the appropriate tools.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin called Update Config Audit. Plugin Name: Update Config Audit. Description: Dashboard widget showing your WordPress auto-update configuration at a glance. Single PHP file. No dependencies beyond WordPress core. Register a dashboard widget using wp_add_dashboard_widget with id uca_dashboard_widget, title Update Configuration, callback uca_render_widget. Hook the registration into wp_dashboard_setup. In uca_render_widget, output a table element with style width:100%;border-collapse:collapse. The table has a thead row with two th cells: Check and Status, both left-aligned. The tbody has four rows. Row 1 - Check cell: Core auto-updates. Status cell: Read WP_AUTO_UPDATE_CORE. If not defined: output Minor updates only (WordPress default) in color #46b450. If true (boolean true, string true, or string 1): output All updates enabled in color #46b450. If the string minor: output Minor updates only in color #46b450. If false (boolean false, string false, or string 0 or integer 0): output Disabled (WP_AUTO_UPDATE_CORE is false) in color #d63638. Row 2 - Check cell: Updater disabled. Status cell: Read AUTOMATIC_UPDATER_DISABLED. If defined and evaluates to true: output Yes - all automatic updates are blocked in color #d63638. Otherwise: output No in color #46b450. Row 3 - Check cell: WP-Cron. Status cell: Read DISABLE_WP_CRON. If defined and evaluates to true: output Disabled - verify a server cron is calling wp-cron.php in color #dba617. Otherwise: output Enabled in color #46b450. Row 4 - Check cell: WordPress version. Status cell: Call get_site_transient('update_core') into $update_data. Get current version with get_bloginfo('version') into $current. If $update_data is empty or $update_data->updates is empty or not set: output Current: [version] - update check has not run yet in color #dba617. Otherwise read $update_data->updates[0]->current into $latest. If $latest equals $current: output Up to date ([version]) in color #46b450. Otherwise output Current: [current] / Latest: [latest] - update available in color #d63638. Apply inline style color:[hex] to each status td. Escape all dynamic values with esc_html. Give each tr a style border-bottom:1px solid #f0f0f0 and each td and th a style padding:6px 4px.

Build this pluginAbout 55 credits · the free plan includes enough for one

Read next

Other plugins you can build this way

Each loads into the composer, ready to edit.