Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If you only want new rows to use UUIDv7, keep existing UUIDv4 primary keys and change the ID generator. PostgreSQL 18 added the native uuidv7() function, and a PostgreSQL uuid column can store both versions. Replacing UUIDs already stored is a separate, higher-risk data migration: every dependent foreign key and external use of each ID must be accounted for.

Choose whether to change existing IDs

A UUID column does not have to contain just one UUID version. The right approach depends on whether your goal is to generate time-ordered IDs for new rows or to replace every UUIDv4 already in the database.

Approach What changes Main consideration
Use UUIDv7 for new rows Change the relevant default or application-side generator; retain existing primary keys and references. Existing UUIDv4 values remain in place, so the column contains mixed versions. They do not acquire UUIDv7 ordering.
Replace existing UUIDs Assign new IDs and update dependent database references and any persisted external identifiers. Requires a schema-specific migration plan, a stable old-to-new mapping, and coordinated application changes.

Use UUIDv7 for new rows without re-keying

PostgreSQL 18 introduced uuidv7(), which generates a version 7, time-ordered UUID. Its timestamp uses Unix time at millisecond precision along with sub-millisecond timestamp and random components. The UUID functions reference describes it as generating a “version 7 (time-ordered) UUID.”

If your table already has a UUID primary key, you can set a default for future inserts on PostgreSQL 18. For example, replace your_table and id with your actual table and column names:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ALTER TABLE your_table
  ALTER COLUMN id SET DEFAULT uuidv7();

This default is used when an insert omits the column or explicitly requests its default; a writer that supplies its own ID can still insert a different UUID. Check every ID-producing path, including application code, ORM configuration, bulk loaders, ingestion jobs, and other services, before relying on a database default. This route avoids changing existing primary keys or their foreign-key references.

PostgreSQL 18 was released on September 25, 2025. On an earlier PostgreSQL version, this native function is not available; choose a compatible generator or wait to change the generator until the server version supports it. Do not treat UUIDv7 as a cast or conversion of an existing UUIDv4 value: it is a newly generated identifier.

Understand what a full re-key changes

A primary key must be unique and non-null. PostgreSQL creates a unique B-tree index for a primary key, and foreign keys can reference a primary key, unique constraint, or qualifying unique index. Changing a primary-key value therefore affects more than the row that owns it: every reference must continue to point to the same logical row.

An ON UPDATE CASCADE foreign-key action propagates a changed referenced value only for relationships configured with that action. It does not update identifiers stored outside the database, and it does not remove the need to inventory dependencies. Applications, integrations, exports, URLs, event streams, or other systems may have retained the old ID.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Plan a full UUIDv4-to-UUIDv7 re-key

The following is a planning sequence, not a universal SQL recipe. The safe implementation depends on the PostgreSQL version, table type and size, write rate, schema, and deployment constraints.

  1. Inventory dependencies. Identify the primary-key column, every foreign key that references it, self-references, related unique constraints and indexes, partitioning, triggers, and application or integration paths that persist the ID. Record each relationship’s update behavior.
  2. Choose a cutover and write strategy. Decide whether writes can pause for a controlled change or whether the application needs an expand-and-contract rollout with temporary old and new columns. Define how inserts and updates during the migration will receive IDs and maintain one stable old-to-new mapping.
  3. Create and verify the mapping. Assign exactly one new UUIDv7 to each old key. Use that mapping to update referencing columns. Before cutover, check for missing mappings, duplicate new IDs, and references that do not match the intended parent row.
  4. Prepare constraints and indexes for the target version and table type. PostgreSQL documents building a unique index with CREATE UNIQUE INDEX CONCURRENTLY and attaching it as a primary-key constraint with ALTER TABLE ... ADD CONSTRAINT ... PRIMARY KEY USING INDEX. This can help avoid blocking table updates for a long time, but it does not eliminate operational constraints. In PostgreSQL 17 documentation, this approach is not supported for partitioned tables; adding a primary key can also require a full scan if the column is not already marked NOT NULL.
  5. Stage and validate foreign keys where appropriate. PostgreSQL documents adding foreign-key constraints as NOT VALID and validating them later with VALIDATE CONSTRAINT. The initial addition avoids scanning existing rows; validation checks them later and takes a SHARE UPDATE EXCLUSIVE lock on the altered table. PostgreSQL 17 documentation says foreign keys on partitioned tables cannot currently be declared NOT VALID. Confirm the rules for your server version and table type.
  6. Cut over only after checks pass. Confirm uniqueness, non-nullness, reference consistency, application compatibility, and the defined rollback point. Retire old columns and constraints only after the new identifiers have been exercised through the full application and integration path.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Account for availability, rollback, and performance

Availability and locking

Concurrent index creation and staged constraint validation can reduce some disruption, but neither makes a re-key lock-free or removes scans and version-specific restrictions. Review the exact commands and lock behavior for the PostgreSQL version and table types you operate. Test the migration and recovery procedure against a representative schema and workload before production cutover.

Rollback

Keep the old-to-new mapping, and decide whether the old values themselves must remain available during the rollback window. The migration plan should specify how to restore references consistently if the application or integration path fails after cutover; simply switching the primary-key column back is not sufficient if dependent values have already changed.

Expected benefit

UUIDv7 is time-ordered, but the reviewed PostgreSQL documentation does not quantify a performance improvement from rewriting existing UUIDv4 keys. If performance is the reason for re-keying, measure the relevant workload before and after; do not assume a specific speedup from the UUID version alone.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.