What I found so far is that certain actions are unsafe to be performed inside hook_update_N(), but I didn't find any documentation saying which those actions are.

When should I implement hook_post_update_NAME() instead of hook_update_N()?


2 Answers 2


Normally when you update Drupal core locally you perform the following:

composer update
drush updb
drush cex

Let's say that there's a core module implementing hook_update_N() to update some content or config – an update that triggers entity load and entity save somehow. Now let's say that in some other core module inside some other hook_update_N() are updates to the database schema which in the end handles how this content or config is actually stored. How can you reliably ensure that the schema updates run before the content/config updates, especially when some users update their site skipping some few minor releases at once?

So hook_post_update_NAME() was introduced to guarantee all schema/structure/format updates have run first and now can be relied on when needing to update content or config on top of them.

Now let me also tell you that the most reliable hook for simple content updates from a custom module is hook_deploy_NAME(). This hook was introduced in Drush 10.3.0 together with the new drush deploy command. Using this new command to replace the old drush updb && drush cim deployment routines all hook_deploy_NAME() implementations will be picked up after configuration import. Which totally makes sense when you want to populate a new field which has only been created and added to config in the same release.

  • 1
    Thank you - linking to the issue where the post_update hook was added certainly helps understand this further.
    – Brian
    Commented Dec 11, 2020 at 18:42

According to the documentation (https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension%21module.api.php/function/hook_post_update_NAME/8.4.x) hook_post_update_NAME is for content updates.

Compared to hook_update_N: that is for database changes. The two provide a solid way to upgrade your webapplication. I'm only missing a pre-config-update hook and a post-config-update hook. I solve that now using exceptions. When you trow an exception in hook_update or hook_post_update it will mark the update as unprocessed, and will retry to run it the next time you run the drush updb command.

Solving those 2 problems:

  1. When update logic for content depends on update logic for database: use hook_post_update
  2. When update logic for content depends on configuration import: retry the hook_update and hook_post_update run.
# first try hook_update_N and hook_post_update_NAME
# Add validation to see if the configuration has been updated.
$ drush updb -y

# configuration changes
$ drush config-import sync -y

# update again, it will retry the hook_post_update_NAME
# that failed during the first run.
$ drush updb -y
  • 2
    If you want to write a hook_update_N that depends on updates from other modules, you can do that using hook_update_dependencies. You do not need hook_post_update. Why do you say hook_update_N is for database/filesystem while the other is not though?
    – Brian
    Commented Oct 17, 2019 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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