update_user_meta( int $user_id, string $meta_key, mixed $meta_value, mixed $prev_value = '' ): int|bool
- Since
- 3.0.0
- Source
wp-includes/user.php:1325
Writes a value to a user's meta key, creating the row if none exists yet. Pass $prev_value to target one entry among several rows that share the same key for a user, since otherwise every matching row is updated. The return value is an int (new meta ID), true, or false depending on whether the row was added, changed, or already matched what's stored, so check the type rather than assuming a plain boolean. Pair it with get_user_meta() to read the value back after writing it.
Description
Use the $prev_value parameter to differentiate between meta fields with the same key and user ID.
If the meta field for the user does not exist, it will be added.
For historical reasons both the meta key and the meta value are expected to be "slashed" (slashes escaped) on input.
Compatibility
- WordPress
- since 3.0.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$user_idint- User ID.
$meta_keystring- Metadata key.
$meta_valuemixed- Metadata value. Must be serializable if non-scalar.
$prev_valuemixedoptional- Previous value to check before updating.
If specified, only update existing metadata entries with this value. Otherwise, update all entries. Default empty.Default:''
Return value
int|bool- Meta ID if the key didn't exist, true on successful update, false on failure or if the value passed to the function is the same as the one that is already in the database.
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Save a per-user preference flag
The sandbox has an administrator already logged in, so its user ID can be used directly without creating a new user.
$user_id = get_current_user_id();
$result = update_user_meta( $user_id, 'newsletter_opt_in', '1' );
$value = get_user_meta( $user_id, 'newsletter_opt_in', true );
printf( 'update_user_meta() returned: %s, stored value: %s', esc_html( var_export( $result, true ) ), esc_html( $value ) );The first call on a fresh install returns the new meta ID rather than true, since the row does not exist yet.
Update one entry when a user has several meta rows sharing the same key
A second user is created with two 'shift_note' meta rows under the same key, then $prev_value is used to update only the matching one.
$user_id = (int) get_option( 'meta_demo_user_id' );
$updated = update_user_meta( $user_id, 'shift_note', 'evening shift, updated', 'evening shift' );
$notes = get_user_meta( $user_id, 'shift_note' );
printf( 'Update result: %s', esc_html( var_export( $updated, true ) ) );
echo '<pre>' . esc_html( print_r( $notes, true ) ) . '</pre>';Without the $prev_value argument, update_user_meta() would overwrite every 'shift_note' row for this user with the same new value.
Common problems and fixes · 4
- Why does update_user_meta() return false even though I passed a real value?
- Why did update_user_meta() overwrite all my meta rows for that key instead of one?
- Why is the return value sometimes a number instead of true?
- Do I need to escape my meta value before passing it in?
Why does update_user_meta() return false even though I passed a real value?
Why did update_user_meta() overwrite all my meta rows for that key instead of one?
Why is the return value sometimes a number instead of true?
Do I need to escape my meta value before passing it in?
Alternatives and related functions
update_metadata- When the meta type isn't a user, since this is the shared function behind update_user_meta(), update_post_meta(), and update_term_meta().
get_user_meta- When you need to read a value back rather than write one.
add_user_meta- When you want to add another row under the same key instead of updating an existing one.
delete_user_meta- When you need to remove a meta entry rather than change its value.
Performance profile
How much work a call to update_user_meta() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Light
- Scaling
- Constant
- Instructions
- 12
- Plugin surface
- None
- Called by
- 39
Only touches the object cache, via wp_cache_delete().
No loop in the body: the same number of instructions runs whatever you pass in.
Executed per call on PHP 8.5. The body compiles to 12.
Nothing here hands control to plugin code.
39 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- hookthird-party callbacks
apply_filters()one call below update_user_meta() - serializeserialisation
maybe_serialize()one call below update_user_meta() - cacheobject cache
wp_cache_delete()one call below update_user_meta()
Further down the call graph this can also reach query, option and transient. Those are the worst case, several calls deep and usually down an error path, not what a normal call pays.
What one call costs · 1 distinct outcome
One number would be a lie: the work depends on which branch runs. These are every distinct cost update_user_meta() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
| always | 12 | update_metadata() |
Across PHP versions
Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 12 instructions, 12 executed per call, 0 branches. The work does not change between versions.
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Uses · 1
- update_metadata()Updates metadata for the specified object. If no value already exists for the specified object ID and metadata key, the metadata will be added.
Used by · 39
- WP_Application_Passwords::set_user_application_passwords()Sets a user's application passwords.
- WP_Plugin_Install_List_Table::prepare_items()
- WP_Screen::render_meta_boxes_preferences()Renders the meta boxes preferences.
- WP_User::add_cap()Adds capability and grant or deny access to capability.
- WP_User::add_role()Adds role to user.
- WP_User::remove_cap()Removes capability from user.
- WP_User::remove_role()Removes role from user.
- WP_User::set_role()Sets the role of the user.
- WP_User::update_user_level_from_caps()Updates the maximum user level for the user.
- WP_User_Meta_Session_Tokens::update_sessions()Updates the user's sessions in the usermeta table.
- add_new_user_to_blog()Adds a newly created user to the appropriate blog
- add_user_to_blog()Adds a user to a blog, along with specifying the user's role.
Show all 39
- choose_primary_blog()Handles the display of choosing a user's primary site.
- default_password_nag_edit_user()
- default_password_nag_handler()
- get_active_blog_for_user()Gets one of a user's active blogs.
- populate_network()Populate network settings.
- register_new_user()Handles registering a new user.
- remove_user_from_blog()Removes a user from a blog.
- reset_password()Handles resetting the user's password.
- send_confirmation_on_profile_email()Sends a confirmation request email when a change of user email address is attempted.
- set_screen_options()Saves option for number of rows when listing posts, pages, comments, etc.
- update_user_option()Updates user option with global blog capability.
- upgrade_160()Execute changes made in WordPress 2.0.
- wp_ajax_closed_postboxes()Handles closed post boxes via AJAX.
- wp_ajax_dismiss_wp_pointer()Handles dismissing a WordPress pointer via AJAX.
- wp_ajax_get_community_events()Handles Ajax requests for community events
- wp_ajax_hidden_columns()Handles hidden columns via AJAX.
- wp_ajax_meta_box_order()Handles saving the meta box order via AJAX.
- wp_ajax_save_user_color_scheme()Handles auto-saving the selected color scheme for a user's own profile via AJAX.
- wp_ajax_save_wporg_username()Handles saving the user's WordPress.org username via AJAX.
- wp_ajax_update_welcome_panel()Handles updating whether to display the welcome panel via AJAX.
- wp_initial_nav_menu_meta_boxes()Limit the amount of meta boxes to pages, posts, links, and categories for first time users.
- wp_initialize_site()Runs the initialization routine for a given site.
- wp_insert_user()Inserts a user into the database.
- wp_install()Installs the site.
- wp_install_defaults()Creates the initial content for a newly-installed site.
- wp_localize_community_events()Localizes community events data that needs to be passed to dashboard.js.
- wp_nav_menu_setup()Register nav menu meta boxes and advanced menu items.
Source code
function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) { return update_metadata( 'user', $user_id, $meta_key, $meta_value, $prev_value );}Changelog
Introduced in 3.0.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
About this page
- Parsed data
- Generated from the wordpress-develop 7.1.0 tag, from
src/wp-includes/user.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.