Amazon Cognito user pool limits that trigger a migration

Some Cognito user pool settings are fixed at creation and cannot be changed later. This page explains which limits force a new pool, and when a self-hosted IdP is the better rebuild.

On this page

Amazon Cognito user pool limits that trigger a migration: the short answer

A new user pool is often the only way out once a team finds that the sign-in mode, required attributes or custom attribute schema of an Amazon Cognito user pool cannot be changed. This tends to surface late, when the login flow is already wired into apps, Lambda triggers and user data. If the rebuild is going to happen anyway, a self-hosted identity provider such as Keycloak, ZITADEL or Ory is a legitimate target. The decision is less about whether Cognito can do the job and more about whether you want to recreate fixed settings in a system you control.

This topic is limited to settings that Cognito fixes when a pool is created: whether usernames or aliases drive sign-in, which attributes are required, custom attributes that can never be changed or removed, and usernames that cannot be renamed. It does not compare Cognito's pricing, features or service limits in general, and it does not argue that Cognito is a poor product. Those questions have their own pages. Before you commit to a rebuild, list every fixed setting in your current pool, confirm each one against the current Amazon Cognito documentation, and decide which of them your applications truly depend on. Settings that only reflect an early guess can usually be replaced without a rebuild of the whole identity layer.

The real question is cost of change. Moving to a new pool means users must be migrated, the sub value that applications store may change unless you plan for it, and every app client must be reconfigured. A self-hosted IdP moves that work into a single, deliberate project rather than a rushed pool swap. Ask your team to map which applications read the sub claim, which custom attributes are used in authorization, and whether password hashes can be carried across, because Cognito does not export them in a standard user export. Those answers determine whether a forced password reset or a sign-in-time migration is the realistic path.

Which Cognito settings are fixed once the pool exists

Some Cognito user pool choices cannot be edited after creation, so a change to them can mean building a new pool and moving every user into it. The cards below cover the settings most likely to force that decision, and what to confirm in the AWS documentation before you rely on current behavior.

Required attributes at creation

Attributes marked as required when the pool is created, such as email or name, become part of every user record and sign-up flow. Adding or removing a required attribute later is the setting teams most often find blocked, so a pool built with too many required fields can force a rebuild just to relax the sign-up form. Check whether your current pool's required attributes can still be changed, and list which app clients and sign-up flows depend on them before planning any move.

Username versus alias sign-in

Choosing whether users sign in with a username or with an alias such as an email address or phone number is a pool-level decision. Teams that later want email-based sign-in on a pool created with usernames, or the reverse, may find the setting cannot be switched in place. Confirm in the AWS Cognito documentation which sign-in options can be changed after creation, and map each app's login form to the identifiers users actually type.

Custom attributes that stay forever

Custom attributes cannot be removed once added, and their data type and mutability are fixed when they are defined. A poorly typed attribute, such as a number stored as a string, keeps its shape in every user record, and apps must keep reading it. Inventory every custom attribute, its type and who writes it, and confirm in the AWS documentation what can be changed on an existing attribute before you decide to keep or rebuild.

Usernames that cannot change

A Cognito username is the identifier that stays with the account, and it cannot be renamed for an existing user. If a business rename, a domain change or a corrected spelling needs a new login name, support staff may have to create a second account and migrate data by hand. Ask AWS to confirm current behavior for username changes and whether alias updates can cover the case. Then check how many applications store the username rather than the stable subject identifier.

When a rebuild beats a workaround

A new pool is not always the only path, since some settings can be worked around with app-side logic, extra attributes or a parallel pool. A self-hosted IdP such as Keycloak, ZITADEL or Ory moves the identity store into your own infrastructure, so the rebuild also changes who operates and patches it. Weigh the cost of the workaround against a migration that preserves the subject identifier, and ask whether the project needs a new hosting model in any case.

When a fixed limit forces a new user pool anyway

Use one test before you accept a Cognito limit as a constraint to work around: if a required attribute, the sign-in alias model or an immutable custom attribute no longer matches how your identity model works, the fix is a new user pool and a move of every user into it. Cognito does not let you alter these settings on an existing pool, so the question is not whether the change is possible but whether the cost of rebuilding is lower than the cost of living with the old model. Write down the specific setting, the identity rule it conflicts with, and the number of applications and integrations that depend on the current pool before you decide.

The operational consequences of a new pool reach well beyond the user records. Every app client has to be recreated or re-pointed, and each client's redirect URIs, scopes and token settings need to be checked against the new pool. Lambda triggers attached to the old pool do not carry over, so their logic must be re-implemented or deliberately dropped. Tokens issued by the old pool stop being valid for the new one, which means sessions end and the sub claim that downstream services store will change unless you plan for it. Ask your team to inventory which services key on sub, which store the pool's user pool ID, and which depend on custom attributes, because those are the places where a rebuild breaks things silently.

A new pool is also the moment to ask whether a self-hosted identity provider is the better rebuild. Moving to a self-hosted provider changes who operates the identity service, where the database lives and how the cost recurs, so it deserves its own comparison rather than being treated as a pool replacement by default. The mechanics of exporting profiles, handling passwords that cannot be exported and mapping triggers are covered on the sibling pages on exporting users from Amazon Cognito and the migration guides for Keycloak and ZITADEL, so read those before you set a date. Confirm each limit against current AWS documentation for your region, since the settings that are fixed can change over time.

Which open-source IdP fits each rebuild

Keycloak is the broadest fit when the rebuild needs standard protocols and connections to existing directories. It is licensed under the Apache License 2.0 and is a Cloud Native Computing Foundation incubating project. It supports OpenID Connect, OAuth 2.0 and SAML 2.0, and has built-in user federation with existing LDAP and Active Directory servers, which matters if some users remain in a corporate directory after the move.

  • Protocols and federation: OIDC, OAuth 2.0 and SAML 2.0 are supported, with LDAP and Active Directory federation built in.
  • Realm model: Users, clients and roles live in realms, so you map each Cognito user pool to a realm and decide how many realms you need.
  • Export and import: Realms export and import as JSON with kc.sh export and kc.sh import. The documentation warns this is limited as a backup method and that all nodes must be stopped while it runs, so plan a maintenance window.
  • Database: Production deployments support PostgreSQL 14 to 18, along with several other databases. The default development file database is not for production.
  • Operations: You run the upgrade cadence, high availability and patching yourself, or through a supported distribution such as the Red Hat build of Keycloak.

Before committing, confirm that Keycloak can represent your custom attributes, password policy and token claims, including the sub value your applications depend on.

What moving out of Cognito takes with you

The most consequential limit for a rebuild is what Cognito will not release. Cognito user exports do not include password hashes, so whatever you move to a self-hosted IdP, the users' passwords do not come with them. That leaves two paths: a forced password reset for every user, or a sign-in-time migration where the new IdP checks the old credential on first login and imports it. The sibling page on exporting users from Cognito covers what the export does contain, including the paging limit and attribute list. Read it before you choose, because the answer determines how much of the user base you can move without friction.

Choose between those two paths by looking at your user population and your support capacity, not at the platform. A forced reset is simple to reason about but generates help-desk volume on cutover day and interrupts users who only signed in occasionally. A sign-in-time migration keeps users moving but requires a bridge that validates the legacy credential, usually through an event or trigger that calls Cognito while the pool still exists. Confirm with your team how long the Cognito pool can stay live during the transition, and whether the sign-in bridge can run until dormant accounts are either migrated or retired.

The limit also shapes what must be preserved. Applications often key their data on the Cognito sub claim, so the new IdP must either issue the same identifier or your applications need a mapping step before cutover. Groups, app client settings and attribute names also need a documented mapping, because none of them transfer automatically. Ask any implementation partner to write down, per application, which identifier the app stores, which claims it reads and how the cutover will handle users who have never signed in on the new platform.

How to deploy the chosen IdP alongside the old pool

This sequence moves Cognito sign-in to a self-hosted IdP one application at a time, so the old user pool keeps serving logins until each app is verified on the new platform.

  1. Define the target identity model

    Before any install, the identity owner and application leads write down the target model: which users live in which realm or instance, how tenants or organizations map, which claims applications read (including the sub claim), and which sign-in methods, MFA rules and password policies carry over. Cognito settings fixed at pool creation, such as required attributes and username versus alias sign-in, are the ones most likely to be rebuilt here, so record them first. The step is done when a signed-off one-page model lists every application and the claims it depends on.

  2. Choose the IdP and database

    Select Keycloak, ZITADEL or Ory based on the target model and the protocols your applications use, then pick a supported production database. For Keycloak, the supported list includes PostgreSQL 14 to 18 and several others, and the dev-file database is for development only. For ZITADEL, self-hosting uses PostgreSQL 14 through 18. Confirm high availability needs with the vendor, since Keycloak's supported multi-site designs require a synchronously replicated database. The step is done when the decision, the database version and the hosting target are recorded in the architecture document.

  3. Stand up a non-production instance

    Deploy the chosen IdP in a non-production environment inside your own cloud account, data center or air-gapped network. For Keycloak on Kubernetes, install the Operator through Operator Lifecycle Manager and set operator updates to manual approval mode, because the Keycloak Operator documentation strongly recommends it to avoid unintended automatic upgrades. Keycloak migrates its database schema automatically at startup by default, so test that behavior against a copy of the database before production. The step is done when the instance starts cleanly and a test login succeeds.

  4. Map attributes and app clients

    Recreate each Cognito app client as a client, application or project in the new IdP, with matching redirect URIs, scopes and token lifetimes. Map custom attributes and group membership to the new model, and rebuild Lambda trigger logic as the IdP's extension mechanism, such as Keycloak SPIs or ZITADEL Actions. Keep Cognito custom attributes in view as a reference, because they cannot be changed or removed in the old pool. The step is done when a mapping sheet lists every attribute, group and client with its new equivalent, and the reviewers have signed it.

  5. Run a parallel sign-in path

    Keep the Cognito pool live and route a limited set of test users to the new IdP. Use just-in-time migration where the target supports it, so a user's record is moved on first sign-in, which avoids forced resets when the old pool cannot export password hashes. Confirm with AWS how your pool's exports and password handling work, and plan forced password resets for accounts that cannot migrate. Back up the new realm or instance with your standard database tooling, because the Keycloak realm export is not a backup mechanism. The step is done when test accounts sign in on both paths and the restore procedure has been rehearsed.

  6. Cut over app by app

    Move applications to the new IdP one at a time, starting with the lowest-risk application and ending with those that have the most users or the most claim dependencies. For each app, switch the issuer and client configuration, verify token contents against the mapping sheet, and confirm logout and session behavior. Keep a rollback route to Cognito until the app has run cleanly for a period your owner sets. The step is done when each app has a signed cutover record showing that its claims and sign-in flows match the target model.

  7. Retire the old pool

    Once every application has cut over and the rollback window closes, stop routing traffic to the Cognito pool and export a final record of its configuration and users for your retention obligations. Remove app clients, Lambda triggers and the pool itself, and confirm that no integration still calls its endpoints. Update runbooks, monitoring and access reviews to cover the new IdP, including its operator update and backup procedures. The step is done when the pool is deleted or archived and the runbooks name the new platform as the system of record.

Evidence to keep when the pool is rebuilt

A rebuilt identity store changes who can sign in, what each token says and who can administer the system. The records below show those changes were planned, tested and reversible, and they tie each Cognito limit you worked around to a decision someone signed off.

Change records

Keep a dated record for each decision that replaced a fixed Cognito setting, such as the sign-in alias choice, a required attribute that was dropped or a username that could not change. Record who approved it, the reason, and the rollback point. Assessors usually ask first for this trail, because it shows the new pool was a deliberate rebuild and not an informal copy. Check that each record names the Cognito pool it replaces.

Attribute mapping sheets

List every Cognito attribute, including custom attributes that can never be removed from the old pool, and state where each one lands in the new realm, client or organization. Note the data type, whether it is required, and whether it is sent in tokens. Mark attributes that are retired rather than migrated, and get the data owner to confirm each retirement. This sheet is the reference when someone asks why a profile field is missing.

Sign-in test results

Record the test cases you ran against the new identity provider: password sign-in, forced reset or sign-in-time migration, MFA enrollment, account recovery and sign-out. Include the account types used, the application client and the result. Keep failed cases with their fixes. These results show that users can still reach each application after cutover, which is the first question operations teams raise.

Token claim checks

Capture decoded ID and access tokens from the old and new systems for the same test user, then compare them claim by claim. Confirm that the sub claim has the same value wherever applications store it, because a changed subject can orphan user records. Also check custom claims, audience, issuer and expiry. Store the comparison with the application owner's sign-off.

Access reviews for admin roles

List every person and service account that can administer the new identity system, including realm or instance admins, client secret holders and users who can change federation settings. Review each grant against current job duties and remove dormant accounts. Record the review date and reviewer. Assessors typically test whether administrative access was limited and reviewed after the migration, not just at setup.

Backup and restore tests

Restore the identity database to a separate environment and confirm that users, clients, roles and signing keys come back intact. Keycloak's export and import of realms is documented as having limits as a backup mechanism, so test the process you actually plan to use, not just the one that is easiest to run. Record the restore time, the steps and any gaps found.

Questions teams ask before a Cognito rebuild

Does moving off Cognito always require a new user pool?

Not always, but often. Settings such as required attributes, username versus alias sign-in and custom attributes cannot be changed or removed once a pool exists, so a change to any of them usually means creating a new pool. Usernames also cannot change. Before deciding, list which fixed settings are wrong for your product and whether you could work around them in the app instead. If the pool must be rebuilt anyway, a move to a self-hosted IdP is a natural point to rebuild the data model as well, since the same export and mapping work is needed either way.

What makes a Cognito migration larger or smaller?

Five components drive most of the effort: the number of users, the number of app clients that depend on the current sub claim, the Lambda triggers that run during sign-up and sign-in, the federated identity providers connected to the pool, and the MFA configuration. Each adds mapping and testing work. Cognito exports do not include password hashes, so the choice between forced password resets and migrating users at sign-in time also changes the amount of user-facing work. Ask your team to inventory these five items first, because the inventory sets the scope.

Can an internal team rebuild the pool without outside help?

Often yes, if the team has experience with OpenID Connect, a database operations practice and time to test login flows end to end. The work includes standing up the platform, exporting users, rebuilding triggers as provider logic, testing every app client and operating the system afterward. Teams with limited identity experience usually find the testing and cutover planning are where the risk sits. Whichever path you choose, decide early who owns patching, backups and on-call for the new platform.

How long does a Cognito rebuild take?

No general duration applies. The scope sets it: user count, number of applications, how many triggers and federated providers must be rebuilt, the chosen migration method and the testing required before cutover. A rebuild with one app client and no triggers differs greatly from one with many applications and MFA policies. DeployOpen agrees timelines in the written scope before work starts, so the way to get a reliable figure is to complete the inventory above and share it when requesting a scope.

What should a written scope for a Cognito rebuild include?

Ask for a scope that names each item it covers: the target platform and version, the hosting environment, the user export and import method, the handling of password hashes, the mapping of app clients and the sub claim, the rebuilt trigger logic, federated identity providers, MFA, cutover and rollback steps, backup and restore design, documentation and handover, and acceptance tests. Also ask what is excluded, such as changes to client applications. Confirm who performs each task and what evidence you will receive. DeployOpen fixed-scope engagements are agreed this way in writing before work starts.

How do Keycloak, ZITADEL and Ory compare for this rebuild?

Keycloak supports OpenID Connect, OAuth 2.0 and SAML 2.0 and has built-in user federation with LDAP and Active Directory, and it is Apache 2.0 licensed. ZITADEL implements OIDC, OAuth 2.0 and SAML 2.0, provides SCIM 2.0 and is AGPL-3.0 for its core, and it documents migration guides from Auth0 and Keycloak. Its instance and organization model suits multi-tenant products. Ory is API-first, so it fits teams that want to build their own login interface. The right choice depends on protocol needs, licensing tolerance, whether you need a hosted login page and how much custom UI work your team can carry. Compare them against the inventory from your scope.

What operating work does a self-hosted identity platform add?

Once live, the platform needs database operations, upgrades, backups, monitoring and high availability design. Keycloak, for example, documents a need for a synchronously replicated database in its high availability designs, and it recommends manual approval mode for Operator updates to avoid unintended upgrades. ZITADEL requires PostgreSQL 14 or later for self-hosting. These tasks recur, so include them in your cost comparison alongside the one-time migration work, and confirm with the vendor which release line and support model fit your environment.

Where to confirm the platform facts

Before you plan a rebuild, confirm the capabilities and limits of each candidate platform against its own documentation, not against this page. Start with the Keycloak documentation on the Keycloak site, including the server administration guide and the upgrading guide, which set out realm, client and federation behavior and the upgrade path between releases. For ZITADEL, check the ZITADEL GitHub repository and its self-hosting and organizations documentation, since its tenant model (instances, organizations and projects) determines whether your current user pool structure maps cleanly. For authentik, read the authentik pricing page to confirm which features sit in the free edition and which need an enterprise license. If you are comparing against Auth0 as well, the Auth0 bulk user exports documentation shows what that platform will and will not release.

Cognito behavior needs the same discipline. The settings this topic covers, such as required attributes, username versus alias sign-in and custom attribute definitions, are documented by AWS for the Cognito user pool API and console. Confirm them in your own account and Region rather than assuming the defaults you remember. Open the existing pool's configuration, record every attribute schema entry and sign-in option, and check whether any app client, Lambda trigger or domain setting depends on them. Ask AWS support or your account team to confirm any behavior you cannot verify in the documentation, and write down the answers, because they will drive the new-pool-versus-migration decision.

Treat the vendor documentation as a dated source. Platform versions, supported database versions and license terms change, so record the version you tested against and the date you checked it. Re-verify the specific claims your decision depends on just before any design review or contract signature, and keep the printed or exported configuration as evidence for the design record.

How DeployOpen rebuilds an identity pool under a fixed-settings constraint

When a Cognito setting is fixed at pool creation, the fix is often a new pool and a planned user migration. DeployOpen plans, builds, documents and hands over that rebuild in the client's own infrastructure, with the written scope setting out which limits force a new pool and which can be handled another way.

How we scope

  • We inventory the existing user pool settings that are fixed at creation, such as required attributes and username versus alias sign-in.
  • We record which custom attributes, app clients and Lambda triggers the applications depend on before any build starts.
  • The written scope fixes deliverables, the target platform, the migration approach and the timeline, and engagements are fixed-scope.

How we build

  • We deploy the chosen self-hosted identity platform in your cloud account, data center or air-gapped network, with its database and high availability design.
  • We map Cognito app clients, groups and token claims to the target realms, organizations or applications, keeping the subject identifier applications rely on.
  • We build the user migration path you chose, then test sign-in, token issuance and attribute flows before cutover, including security testing.

How we hand over

  • We document the configuration, migration runbook, rollback steps and evidence that compliance assessors may ask for.
  • We train your operators on backup, export limits, upgrades and access control for the new identity system.
  • Independent auditors and certification bodies issue any audit reports or certifications; we prepare the systems, controls and evidence for them.

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer after handover.
  • We can plan upgrades around the platform's release cadence and confirm breaking changes before they reach your environment.
  • Ask for the support scope, response commitments and upgrade responsibilities in the written quote, since these vary by engagement.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.