<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: engr anees</title>
    <description>The latest articles on DEV Community by engr anees (@engranees61).</description>
    <link>https://dev.to/engranees61</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3924504%2F157f5790-b026-4a94-80bd-1f9d8a4be52e.png</url>
      <title>DEV Community: engr anees</title>
      <link>https://dev.to/engranees61</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/engranees61"/>
    <language>en</language>
    <item>
      <title>Stop using UUID v4 for database primary keys — UUIDv7 is the 2026 default</title>
      <dc:creator>engr anees</dc:creator>
      <pubDate>Tue, 12 May 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/engranees61/stop-using-uuid-v4-for-database-primary-keys-uuidv7-is-the-2026-default-2f4b</link>
      <guid>https://dev.to/engranees61/stop-using-uuid-v4-for-database-primary-keys-uuidv7-is-the-2026-default-2f4b</guid>
      <description>&lt;p&gt;Your B-tree indexes hate UUID v4. They've hated it for years. You probably haven't noticed because the slowdown is gradual — until your table hits 10 million rows and inserts start taking 200ms instead of 5ms.&lt;/p&gt;

&lt;p&gt;UUIDv7 fixes this. RFC 9562 made it official in May 2024. PostgreSQL 18 ships native support. MySQL 8.4 has a helper. Most ORM and language libraries added v7 in 2024–2025. By 2026, &lt;strong&gt;v4 should be the exception, not the default&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This post is the "why", the "when", and the "how to migrate without breaking things".&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem with v4
&lt;/h2&gt;

&lt;p&gt;A v4 UUID is 122 bits of pure randomness:&lt;/p&gt;

&lt;p&gt;e7d1a8c4-9fe5-4a32-8c7e-3f9d2e8a1c4b&lt;/p&gt;

&lt;p&gt;Looks fine. Random is what we want, right? Yes — for things that need to be &lt;strong&gt;unguessable&lt;/strong&gt;. No — for things that go into a B-tree index.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why B-trees hate randomness
&lt;/h3&gt;

&lt;p&gt;Database indexes (B-tree, which is what Postgres, MySQL, SQLite, MSSQL all use for primary keys by default) work best when new entries arrive &lt;strong&gt;in roughly sorted order&lt;/strong&gt;. The tree can append to the rightmost leaf page, keeping the structure compact and writes localized.&lt;/p&gt;

&lt;p&gt;When you insert 1 million v4 UUIDs, each one lands in a &lt;strong&gt;random page&lt;/strong&gt; of the index. The result:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Random page splits as the tree rebalances&lt;/li&gt;
&lt;li&gt;Buffer cache thrashing — random pages keep getting evicted&lt;/li&gt;
&lt;li&gt;Increased WAL/redo log volume — random pages mean random disk writes&lt;/li&gt;
&lt;li&gt;Eventually: index fragmentation, slower queries, larger storage&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Public benchmarks on InnoDB (MySQL 8.0) at 10 million rows show v4 UUID inserts roughly 3× slower than auto-increment integer keys, with index size around 40% larger. The exact numbers vary by database, hardware, and workload, but the pattern is universal: &lt;strong&gt;random keys destroy B-tree performance at scale&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  "But I'm not at scale yet"
&lt;/h3&gt;

&lt;p&gt;True. At 100K rows, nobody notices. At 1M rows, you might notice slow inserts on bulk operations. At 10M rows, your DBA writes you a long Slack message.&lt;/p&gt;

&lt;p&gt;The cost of using v7 from day one: zero. Same UUID format, same byte length, same tooling.&lt;/p&gt;

&lt;p&gt;The cost of migrating from v4 to v7 at 100M rows: you don't migrate. You live with it forever.&lt;/p&gt;




&lt;h2&gt;
  
  
  What UUIDv7 Actually Is
&lt;/h2&gt;

&lt;p&gt;UUIDv7 keeps the same &lt;code&gt;xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx&lt;/code&gt; format as v4 but rearranges the bytes:&lt;/p&gt;

&lt;p&gt;0190a4b3-1c2d-7e85-a734-2c8e9f1d4a5b&lt;br&gt;
└────timestamp────┘ ││ │└──random──┘&lt;br&gt;
│└── version (7)&lt;br&gt;
└─── variant&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First 48 bits&lt;/strong&gt; (&lt;code&gt;0190a4b3-1c2d&lt;/code&gt;) — Unix milliseconds timestamp&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next 4 bits&lt;/strong&gt; — Version marker (always &lt;code&gt;7&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next 12 bits&lt;/strong&gt; — Sub-millisecond ordering or random&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next 2 bits&lt;/strong&gt; — Variant marker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Last 62 bits&lt;/strong&gt; — Pure random&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key insight: the &lt;strong&gt;timestamp is in the most significant bits&lt;/strong&gt;, so v7 UUIDs sort chronologically by string OR byte comparison.&lt;/p&gt;

&lt;p&gt;Insert 1 million v7 UUIDs sequentially, and the B-tree is happy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All inserts land near the rightmost page&lt;/li&gt;
&lt;li&gt;Buffer cache stays warm&lt;/li&gt;
&lt;li&gt;WAL volume stays low (sequential writes)&lt;/li&gt;
&lt;li&gt;Index size matches ordered-key efficiency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same uniqueness guarantee as v4 (74 bits of randomness — collision probability still effectively zero at realistic scale). Same length, same character set, same APIs. &lt;strong&gt;Just better-shaped randomness.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  When to Use v7 vs v4
&lt;/h2&gt;

&lt;p&gt;This is the entire decision tree:&lt;/p&gt;

&lt;p&gt;Is the UUID stored in a B-tree index?&lt;br&gt;
(database PK, MongoDB _id, any indexed FK)&lt;br&gt;
│&lt;br&gt;
├── YES → use v7&lt;br&gt;
│ Examples: user_id, order_id, post_id&lt;br&gt;
│&lt;br&gt;
└── NO → does the UUID need to NOT leak time information?&lt;br&gt;
│&lt;br&gt;
├── YES → use v4&lt;br&gt;
│ Examples: password reset tokens, share-by-URL&lt;br&gt;
│ secrets, anti-CSRF tokens, webhook signatures&lt;br&gt;
│&lt;br&gt;
└── NO → use v7 anyway (slightly cheaper to generate)&lt;/p&gt;

&lt;p&gt;That's it. v7 is the default; v4 is the security exception.&lt;/p&gt;
&lt;h3&gt;
  
  
  "But v7 leaks the creation timestamp!"
&lt;/h3&gt;

&lt;p&gt;Yes — the leading 48 bits are a millisecond timestamp. Anyone who sees a v7 UUID can read off when it was generated.&lt;/p&gt;

&lt;p&gt;For a database primary key, this is &lt;strong&gt;fine&lt;/strong&gt; (rows usually have a &lt;code&gt;created_at&lt;/code&gt; column anyway). For a sharing token where guessability of "when this was created" enables an attack, v4 stays correct.&lt;/p&gt;

&lt;p&gt;Don't use v7 for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Password reset tokens (timestamp narrows brute-force window)&lt;/li&gt;
&lt;li&gt;Email verification links (same)&lt;/li&gt;
&lt;li&gt;Anti-CSRF tokens&lt;/li&gt;
&lt;li&gt;Webhook signatures&lt;/li&gt;
&lt;li&gt;API keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For everything else: v7.&lt;/p&gt;


&lt;h2&gt;
  
  
  Generating UUIDv7 in 2026
&lt;/h2&gt;
&lt;h3&gt;
  
  
  JavaScript / Node.js (uuid v10+)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;v7&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;uuidv7&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uuid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;uuidv7&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// '0190a4b3-1c2d-7e85-a734-2c8e9f1d4a5b'&lt;/span&gt;

&lt;span class="nx"&gt;Python&lt;/span&gt; &lt;span class="mf"&gt;3.13&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stdlib&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;

&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uuid7&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nc"&gt;Go &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;google&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt; &lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;github.com/google/uuid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NewV7&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nc"&gt;Rust &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt; &lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now_v7&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;PostgreSQL&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;native&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;extension&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;SELECT&lt;/span&gt; &lt;span class="nf"&gt;uuidv7&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0190a4b3-1c2d-7e85-a734-2c8e9f1d4a5b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;CREATE&lt;/span&gt; &lt;span class="nx"&gt;TABLE&lt;/span&gt; &lt;span class="nf"&gt;users &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt; &lt;span class="nx"&gt;PRIMARY&lt;/span&gt; &lt;span class="nx"&gt;KEY&lt;/span&gt; &lt;span class="nx"&gt;DEFAULT&lt;/span&gt; &lt;span class="nf"&gt;uuidv7&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="nx"&gt;TEXT&lt;/span&gt; &lt;span class="nx"&gt;NOT&lt;/span&gt; &lt;span class="nx"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;created_at&lt;/span&gt; &lt;span class="nx"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="nx"&gt;DEFAULT&lt;/span&gt; &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;MySQL&lt;/span&gt; &lt;span class="mf"&gt;8.4&lt;/span&gt;
&lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;native&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;as&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2026&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Generate&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="nx"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;stored&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="nx"&gt;DELIMITER&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="nx"&gt;CREATE&lt;/span&gt; &lt;span class="nx"&gt;FUNCTION&lt;/span&gt; &lt;span class="nf"&gt;uuid_v7&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;RETURNS&lt;/span&gt; &lt;span class="nc"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;BEGIN&lt;/span&gt;
  &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="nx"&gt;bits&lt;/span&gt;
  &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="nx"&gt;Implementation&lt;/span&gt; &lt;span class="nx"&gt;omitted&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;brevity&lt;/span&gt;
  &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="nx"&gt;See&lt;/span&gt; &lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;MichaelDimmitt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;uuidv7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mysql&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;working&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt;
&lt;span class="nx"&gt;END&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;No install — just need one quickly&lt;/strong&gt;&lt;br&gt;
Generate one in your browser: &lt;a href="https://freedevtool.org/uuid-generator" rel="noopener noreferrer"&gt;UUIDv7 Generator&lt;/a&gt;. Supports v1, v4, v5, and v7. All client-side, no upload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migrating an Existing v4 Table&lt;/strong&gt;&lt;br&gt;
Short answer: don't, unless you have measured proof of pain.&lt;/p&gt;

&lt;p&gt;Migrating primary keys is one of the most expensive database operations you can do — every foreign key, every join, every index gets rebuilt.&lt;/p&gt;

&lt;p&gt;Pick the strategy that matches your real constraint:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: New tables only (recommended)&lt;/strong&gt;&lt;br&gt;
Use v7 for new tables going forward. Leave v4 tables alone. After a few years, v7 tables dominate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Add a v7 secondary key&lt;/strong&gt;&lt;br&gt;
Keep v4 as the primary key. Add a secondary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="nv"&gt;`ALTER TABLE users
  ADD COLUMN public_id UUID DEFAULT uuidv7() UNIQUE;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use v4 internally, v7 externally for new query patterns that need range scans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 3: Full migration (only if performance is on fire)&lt;/strong&gt;&lt;br&gt;
This is a 6–12 month project on a real application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add id_v7 UUID column to all tables
Backfill v7 IDs in batches (timestamps reflecting created_at)
Update all foreign keys to point at id_v7
Switch the primary key — the painful part
Drop the old v4 column
Don't do this without benchmarks proving v4 fragmentation is the actual bottleneck. Often the real culprit is missing indexes or N+1 queries.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other Ordered ID Formats (and Why v7 Won)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Format Year    2026 status&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;UUIDv7    2024 (RFC 9562) Standard, native in Postgres 18, libraries everywhere&lt;/li&gt;
&lt;li&gt;ULID  2016    Still common; v7 is the spec'd successor&lt;/li&gt;
&lt;li&gt;CUID2 2022    Niche; works if already using&lt;/li&gt;
&lt;li&gt;NanoID    2017    Different use case (short URL slugs)&lt;/li&gt;
&lt;li&gt;Twitter Snowflake 2010    Specific to high-throughput distributed systems&lt;/li&gt;
&lt;li&gt;MongoDB ObjectID  2009    MongoDB-specific&lt;/li&gt;
&lt;li&gt;Starting a project in 2026: v7. Already using ULID and it works: keep it. Using v4 because that's what crypto.randomUUID() returns: switch the import.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TL;DR&lt;br&gt;
B-tree indexes hate randomness. v4 UUIDs cause page splits, cache thrashing, and bloat as tables grow.&lt;br&gt;
UUIDv7 fixes this by putting a millisecond timestamp in the leading 48 bits, so inserts land in monotonic order.&lt;br&gt;
Same format, same uniqueness guarantee — drop-in replacement for new tables.&lt;br&gt;
Use v4 only when timestamp leakage is a security issue (password reset, anti-CSRF, share-by-URL secrets).&lt;br&gt;
Don't migrate existing v4 tables unless you have measured proof of fragmentation pain.&lt;br&gt;
Postgres 18, MySQL 8.4, all major UUID libraries support v7 natively or via a one-line update.&lt;br&gt;
What's your team's default in 2026 — still v4, switched to v7, or something else (ULID, Snowflake)? Curious to hear the migration stories in comments.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>database</category>
      <category>postgres</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
