Skip to main content
Docs

Migrating

Migration tooling

To aid in basic migrations, Clerk provides an open-source script that takes a JSON file as input, containing a list of users, and creates a user in Clerk using the Backend API. The script respects the backend rate limits and gracefully handles errors. We suggest you customize the Zod schema to your application's needs.

To use Clerk's migration script, clone the repository and follow the instructions in the README.

Migration strategies

There are typically two main strategies for migrating your existing user management from a different platform into Clerk:

Each of these have trade-offs you'll need to consider for your application and its users.

Basic export/import

With basic export/import, you're taking an export from your previous tool and importing data into Clerk. The most common way to handle this is by making use of the CreateUser Backend API endpoint. It's important to note that the CreateUser endpoint is rate limited. For more information, see the guide on rate limits.

You'll also need to provide your password_hasher value (the hashing algorithm used to generate the password digest) and in some instances Clerk will transparently upgrade your users' password hashes to the more secure Bcrypt hashing algorithm. More details on this topic are available in the Backend API reference docs.

Note

If you are expecting to import 100k+ users, we recommend reaching out to where we can coordinate increases to the rate limits and ensure a seamless import of your data.

Considerations

Data consistency

Consider that any export of your data will be a snapshot in time. This means that there is a potential of your data being out of sync at the time of import. To work around this you might script and coordinate the export and import actions to be as close in time as possible, or you might schedule some kind of downtime or maintenance window to complete this action. Be sure to consider Clerk API rate limits when evaluating a potentially time-sensitive migration approach.

Active sessions/session management

Another consideration is centered around how you handle session management. While most authentication providers don't provide session management out-of-the-box, Clerk does. This means that when you switch over to using Clerk, you'll be changing the system that handles your users' active sessions. This will likely end any currently active sessions initiated by your previous session management service (unless you are able to gracefully handle this somehow within your architecture).

Foreign keys

In your previous system, you likely had some kind of ID/foreign key that you were using. As you migrate data into Clerk, you might want to continue referencing that previous ID alongside Clerk's provided user IDs. While each use case might have some variation, a common strategy is to store previous IDs as an external_id. You can then use Clerk's JWT customization to enrich a userId value with the external_id when present, or fallback to using Clerk's native ID when dealing with new users who don't have an external_id from your legacy system. You can configure this in the Sessions page in the Clerk Dashboard. Under Customize session token, in the Claims editor, enter the following JSON and select Save. If you have already customized your session token, you may need to merge this with what you currently have.

{
  "userId": "{{user.external_id || user.id}}"
}

Trickle migration

With a trickle migration, you are slowly migrating your users from your previous system into Clerk. Depending on your application's needs, this can be a great way to accomplish migration in a gradual and more controlled way. With a trickle migration, you are keeping both systems running for some period of time, handling the transition between systems behind the scenes, and then eventually cutting over fully to Clerk as your user and session management system of record. By handling this transition gradually, you'll maintain more control and put less pressure on a single coordinated event.

Considerations

The cost and overhead of running two systems in parallel

Because you'll need both systems available when doing a gradual migration, there is naturally additional short-term costs related to having both running systems at the same time.

Note

It's important to note that Clerk only charges by Monthly Active Users and never based on your total number of Users in the user table – so during this period you'll only be charged for users who create an active session within Clerk. Head to our pricing page to get the full details on how Clerk charges.

Determining the appropriate length of time

As part of the trickle migration, you'll need to determine an appropriate length of time for the migration to take place. For some applications this might be a few weeks, but for others it might be more appropriate to run this for months. Your hard-costs, coordination costs, underlying complexity, and the amount of active users you expect in your migration time-window should guide your decision here.

Dealing with inactive users

A trickle migration is great for upgrading active users and sessions to take advantage of Clerk, but there will always be some users who won't create an active session within the migration window and will need to be migrated by other means, typically via basic export/import. A trickle migration lowers coordination risk because the remaining inactive users are fewer, so data de-synchronization risk drops, too.

Migrating from Clerk

There are two main ways to migrate away from Clerk:

Export your users' data from the Clerk Dashboard

Users who are either admins or are in their personal workspace can export and download a CSV file containing a list of their application's users that includes their hashed passwords. Users can also view detailed export and download history logs. These logs offer a record of previous export actions, ensuring visibility and traceability of data exports.

To export your users' data:

  1. In the Clerk Dashboard, navigate to the application's Settings.
  2. In the User Exports section, select Export all users.
  3. A new entry in the export history will appear. Select the Download button to download the CSV file.

Access user data in the backend

You can programmatically retrieve a list of your user's and their information by using the GetUserList Backend API endpoint, or the JS Backend SDK's method which is a wrapper around the Backend API endpoint.

Feedback

What did you think of this content?

Last updated on