8.5.x module.api.php hook_update_N(&$sandbox)
8.0.x module.api.php hook_update_N(&$sandbox)
8.1.x module.api.php hook_update_N(&$sandbox)
8.2.x module.api.php hook_update_N(&$sandbox)
8.3.x module.api.php hook_update_N(&$sandbox)
8.4.x module.api.php hook_update_N(&$sandbox)
8.6.x module.api.php hook_update_N(&$sandbox)
4.7.x install.php hook_update_N()
5.x install.php hook_update_N()
6.x install.php hook_update_N(&$sandbox)
7.x system.api.php hook_update_N(&$sandbox)

Perform a single update.

For each change that requires one or more actions to be performed when updating a site, add a new hook_update_N(), which will be called by update.php. The documentation block preceding this function is stripped of newlines and used as the description for the update on the pending updates task list. Schema updates should adhere to the Schema API.

Implementations of hook_update_N() are named (module name)_update_(number). The numbers are composed of three parts:

  • 1 digit for Drupal core compatibility.
  • 1 digit for your module's major release version (e.g., is this the 6.x-1.* (1) or 6.x-2.* (2) series of your module?).
  • 2 digits for sequential counting, starting with 00.


  • mymodule_update_5200()

    • This is the first update to get the database ready to run mymodule 5.x-2.*.
  • mymodule_update_6000()
    • This is the required update for mymodule to run with Drupal core API 6.x.
  • mymodule_update_6100()
    • This is the first update to get the database ready to run mymodule 6.x-1.*.
  • mymodule_update_6200()
    • This is the first update to get the database ready to run mymodule 6.x-2.*. Users can directly update from 5.x-2.* to 6.x-2.* and they get all 60XX and 62XX updates, but not 61XX updates, because those reside in the 6.x-1.x branch only.

A good rule of thumb is to remove updates older than two major releases of Drupal. See hook_update_last_removed() to notify Drupal about the removals. For further information about releases and release numbers see: Maintaining a drupal.org project with Git

Never renumber update functions.

Implementations of this hook should be placed in a mymodule.install file in the same directory as mymodule.module. Drupal core's updates are implemented using the system module as a name and stored in database/updates.inc.

Not all module functions are available from within a hook_update_N() function. In order to call a function from your mymodule.module or an include file, you need to explicitly load that file first.

During database updates the schema of any module could be out of date. For this reason, caution is needed when using any API function within an update function - particularly CRUD functions, functions that depend on the schema (for example by using drupal_write_record()), and any functions that invoke hooks.

If your update task is potentially time-consuming, you'll need to implement a multipass update to avoid PHP timeouts. Multipass updates use the $sandbox parameter provided by the batch API (normally, $context['sandbox']) to store information between successive calls, and the $sandbox['#finished'] value to provide feedback regarding completion level.

See the batch operations page for more information on how to use the batch API: http://drupal.org/node/180528


$sandbox: Stores information for multipass updates. See above for more information.

Return value

An array with the results of the calls to update_sql(). An update function can force the current and all later updates for this module to abort by returning a $ret array with an element like: $ret['#abort'] = array('success' => FALSE, 'query' => 'What went wrong'); The schema version will not be updated in this case, and all the aborted updates will continue to appear on update.php as updates that have not yet been run. Multipass update functions will also want to pass back the $ret['#finished'] variable to inform the batch API of progress.

Related topics

93 functions implement hook_update_N()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

blogapi_update_6000 in modules/blogapi/blogapi.install
Inform users about the new permission.
blogapi_update_6001 in modules/blogapi/blogapi.install
Add blogapi_files table to enable size restriction for BlogAPI file uploads.
book_update_6000 in modules/book/book.install
Drupal 5.x to 6.x update.
book_update_bid in modules/book/book.module
Update the bid for a page and its children when it is moved to a new book.
color_update_6001 in modules/color/color.install
Warn site administrator if unsafe CSS color codes are found in the database.

... See full list


developer/hooks/install.php, line 278
Documentation for the installation and update system.


function hook_update_N(&$sandbox) {

  // For non-multipass updates, the signature can simply be;
  // function hook_update_N() {
  // For most updates, the following is sufficient.
  $ret = array();
  db_add_field($ret, 'mytable1', 'newcol', array(
    'type' => 'int',
    'not null' => TRUE,
  return $ret;

  // However, for more complex operations that may take a long time,
  // you may hook into Batch API as in the following example.
  $ret = array();

  // Update 3 users at a time to have an exclamation point after their names.
  // (They're really happy that we can do batch API in this hook!)
  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['current_uid'] = 0;

    // We'll -1 to disregard the uid 0...
    $sandbox['max'] = db_result(db_query('SELECT COUNT(DISTINCT uid) FROM {users}')) - 1;
  $users = db_query_range("SELECT uid, name FROM {users} WHERE uid > %d ORDER BY uid ASC", $sandbox['current_uid'], 0, 3);
  while ($user = db_fetch_object($users)) {
    $user->name .= '!';
    $ret[] = update_sql("UPDATE {users} SET name = '{$user-&gt;<span class="php-function-or-constant property member-of-variable">name</span>}' WHERE uid = {$user-&gt;<span class="php-function-or-constant property member-of-variable">uid</span>}");
    $sandbox['current_uid'] = $user->uid;
  $ret['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['progress'] / $sandbox['max'];
  return $ret;


mikeytown2’s picture

These are the 2 update functions In core that use the "Multi-part update" logic.

Found one in contrib

Granjow’s picture

If present for custom modules (e.g. if the module does not show up on update.php), see Updating tables: hook_update_N() functions.

bleen’s picture

If you need to update a whole bunch of nodes in one shot then this example should be helpful:

Andrew Udvare’s picture

If you define new columns with hook_update_N(), also be sure to update your fields definitions in the tables you have changed in hook_schema(). Clear all caches to see the new schema as defined.


sharplesa’s picture

This point should be listed as an important point in the main description, not just as a user comment.

mikey_p’s picture

The code comment for each function is what will be displayed on update.php, so you may want to skip the standard "Implementation of hook..." and use a short one line description of the update does. For examples see http://api.drupal.org/api/drupal/modules--system--system.install/6/source

skomorokh’s picture

When making changes to a module the defines a custom content type, it becomes necessary at times to migrate node records based on their previous values.

The best approach I've happened upon is to query for a list of affected nids (eg. all nids of that content type) and loop through them to node_load(), perform your change, and node_save().

hook_update_N expects a return value from update_sql. In this case we can follow best practices and use that to log a description of the change in place of the query:

return array('success' => TRUE, 'sql' => 'What changed...');

confiq’s picture

Just wanted to clear things up. When you installing module, drupal will not run any hook_update_n() hooks....

steinmb’s picture

Where you add the update description.

* My description of this update.
function hook_update_7001()
  // update code

Drush will then display this like:
7001 - My description of this update.

Thomas_Zahreddin’s picture

for the updates to be processed in the intended order, the updates have to be in the sequence the number (_n) suggestes (at least there was an issue for simplenews
dealing with this):

if one mixes up the sequence

mymodule_update_6001() {
  … }

mymodule_update_6000() {
  … }

Then the mymodule_update_6001 is processed and this one is higher than 6000 so the mymodule_update_6000 funciton is never executed - But the developers belived it had been executed, which leaded to a lot of strange errors.

Therefor keep the sequence of the functions in an ascending order in the code like:

mymodule_update_6000() {
  … }

mymodule_update_6001() {
  … }

Then all functions are called as expected.