I've researched this a few times, yet my searching does not reveal much except custom code which may or may not be good WordPress practice.

As of the latest releases (WordPress 3.9 "Smith"), has a hook been added to the plugin update process? I'm asking because its a very basic need, yet I do not see it added to the codex (yet). If not, what is the common and best practice developers employ?

EDIT: Just to clarify, I'm not talking about activation, but about updating, that way, if there are changes in database or otherwise it can be addressed.

  • duplicate of wordpress.stackexchange.com/questions/61456/… – drzaus Sep 9 '14 at 9:03
  • @drzaus answer provided there is not a good practice. – Rens Tillmann Aug 5 '16 at 16:32
  • @RensTillmann asides from this being 2 years out of date anyway, the linked q/a has basically the same answer but predates this question by another 2 years, hence the 'duplicate'. – drzaus Aug 8 '16 at 19:45

I don't think an action has been added. You can look at version details for any version and see any new actions added.

The WordPress Way to run code on plugin update is what is described here:

The proper way to handle an upgrade path is to only run an upgrade procedure when you need to. Ideally, you would store a “version” in your plugin’s database option, and then a version in the code. If they do not match, you would fire your upgrade procedure, and then set the database option to equal the version in the code. This is how many plugins handle upgrades, and this is how core works as well.

and with code example here:

function myplugin_update_db_check() {
    global $jal_db_version;
    if (get_site_option( 'jal_db_version' ) != $jal_db_version) {
add_action( 'plugins_loaded', 'myplugin_update_db_check' );
  • Thank you - I'll simply use that method then. WP really has to add an action for this :D – user1915665 May 20 '14 at 2:20
  • 9
    technically you're supposed to use register_activation_hook, since in most cases a plugin gets deactivated/activated whenever you update it from the admin. Hooking to plugins_loaded will do your check on every page load (including frontend). There was talk about introducing register_update_hook, but it was marked as WONTFIX a while ago. The discussion there is helpful. – drzaus Sep 9 '14 at 9:10
  • 4
    It's important to understand that a mass plugin update does NOT run activation hooks - it SHOULD, but doesn't at 3.9.2. By "mass update" I mean an update done from the Dashboard update page. Individual updates done from within the plugin page run the hooks just fine. – Brian C Sep 21 '14 at 0:26
  • 5
    The thing is plugins can also be updated via FTP which means that the hook will not be fired in any case. That's why you need to resort to the option stored in the database. – giraff Sep 1 '15 at 16:37
  • 4
    To expand on @giraff's comment, the same is true for people who manage their code with source control like SVN or Git. Because of that, this answer is the best way to handle upgrades. – doublesharp Sep 10 '15 at 16:53

Since WordPress 3.9 you can use upgrader_process_complete hook.
See reference 1, 2

Here is an example code:

 * Plugin Name: Test plugin 1
 * Plugin URI: http://rundiz.com
 * Description: A very simple plugin for testing. This plugin do nothing.
 * Version: 0.1.8
 * Author: Vee Winch
 * Author URI: http://rundiz.com
 * License: MIT
 * License URI: https://opensource.org/licenses/MIT
 * Text Domain: test-plugin1
 * Domain Path: 

$wppstp1_version = '0.1.8';

add_action('upgrader_process_complete', 'wppstp1_upgrade', 10, 2);// will working only this plugin activated.
function wppstp1_upgrade(\WP_Upgrader $upgrader_object, $hook_extra)
    global $wppstp1_version;

    if (is_array($hook_extra) && array_key_exists('action', $hook_extra) && array_key_exists('type', $hook_extra) && array_key_exists('plugins', $hook_extra)) {
        // check first that array contain required keys to prevent undefined index error.
        if ($hook_extra['action'] == 'update' && $hook_extra['type'] == 'plugin' && is_array($hook_extra['plugins']) && !empty($hook_extra['plugins'])) {
            // if this action is update plugin.
            $this_plugin = plugin_basename(__FILE__);

            foreach ($hook_extra['plugins'] as $each_plugin) {
                if ($each_plugin == $this_plugin) {
                    // if this plugin is in the updated plugins.
                    // don't process anything from new version of code here, because it will work on old version of the plugin.
                    file_put_contents(WP_CONTENT_DIR . '/test.txt', 'v'.$wppstp1_version."\r\n", FILE_APPEND); // you will always get the previous version even you update to the new version.
                    // set transient to let it run later.
                    set_transient('wppstp1_updated', 1);
            }// endforeach;
        }// endif update plugin and plugins not empty.
    }// endif; $hook_extra
}// wppstp1_upgrade

add_action('plugins_loaded', 'wppstp1_runUpdatedPlugin');
function wppstp1_runUpdatedPlugin()
    global $wppstp1_version;

    if (get_transient('wppstp1_updated') && current_user_can('manage_options')) {
        // if plugin updated and current user is admin.
        file_put_contents(WP_CONTENT_DIR . '/test-update-by-transient.txt', 'v'.$wppstp1_version."\r\n", FILE_APPEND);// you will always get the updated version here.

        // update code here.

        // delete transient.
}// wppstp1_runUpdatedPlugin

Once plugin updated, it will set the task into db using set_transient() function. It is not recommend to add update code while calling upgrader_process_complete hook.
Next, if you browse to other admin page, the plugins_loaded hook will work and the update code will be working there.

Please note that this plugin must be activated to make update hook working.
This is not working on activate plugin so, if you want the code that works on activate the plugin you have to code it in register_activation_hook() function.


From the discussion where they decided not to add a custom hook/function specific to upgrade, it sounds like "most people" (as of 4 years ago) use register_activation_hook, since it's called when a plugin is upgraded through the admin page; most examples I've seen since then follow that trend.

For most usage I would suggest not hooking through plugins_loaded, as it would get called on every page load. The exception to this is mentioned in the discussion: upgrade paths via FTP/SVN are 'edge cases', since WP wouldn't have a mechanism to know that the plugin was changed, in which case the previous answer might be more relevant.

See https://gist.github.com/zaus/c08288c68b7f487193d1 for a 'simple framework' example using register_activation_hook.


You can hook into the upgrader_pre_install and upgrader_post_install filters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.