Clerk logo

Clerk Docs

Ctrl + K
Go to
Check out a preview of our new docs.

User metadata

User objects hold a set of metadata that can be used internally to store arbitrary information.


Metadata allows for custom data to be saved on the User object. There are three types of metadata: "unsafe", "public", and "private." Choosing which metadata field you should use for setting custom attributes on your users becomes a matter of access and visibility.

Metadata Frontend API Backend API
private - Read/Write
public Read Read/Write
unsafe Read/Write Read/Write

Metadata is limited to 8kb maximum

Backend metadata

Both public and private metadata are set from the Backend API, but public metadata can be accessed from the Frontend API and Backend API. These types of metadata can be used to access non-sensitive information about a user, such as their profile picture or their name. They can be used to build UIs where a user might not be signed in, but you still want to show some of their profile info.

There are two Backend endpoints that can be used to update the metadata.

Public metadata

The publicMetadata property should be used if you need to set some metadata from your back-end and have them displayed as read-only on the front-end.

await users.updateUser(userId, { publicMetadata: { } });

Private metadata

The privateMetadata property should be used if custom attributes contain sensitive information that should not be displayed on the front-end.

await users.updateUser(userId, { privateMetadata: { } });

Unsafe metadata

If you need to implement custom fields that will be attached to the User object from the front-end (using our ClerkJS library or the Frontend API), you should choose the unsafeMetadata property.

One common use case for this attribute is to use it to implement custom fields that will be attached to the User object.

Please note that there is also an unsafeMetadata attribute in the SignUp object. The value of that field will be automatically copied to the user's unsafe metadata once the sign up is complete.

We've named this type of metadata "unsafe" since it can be set and accessed by both the Frontend API and the Backend API. This provides a quick method to add custom attributes to a user. These attributes will be stored on the User object and will be available for access at all times.

The "unsafe" custom attributes can be set upon sign-up when creating or updating a SignUp object. After a successful sign-up, these attributes will be copied to the User object. From that point on they can be accessed as a direct attribute of the User object.

import { useUser } from '@clerk/nextjs';
const updateMetadata = async () => {
const { user } = useUser();
const data = 'Data to store unsafely';
try {
const response = await user.update({
unsafeMetadata: { data }
if (response) {
console.log('res', response)
} catch (err) {
console.error('error', err)

Looking for inspiration on how to set custom user attributes? Our Clerk Widget starter repo demonstrates storing additional user info like their company, country, and whether they accept the terms and conditions.

Was this helpful?

Clerk © 2023