Email me

Explainer · 7 min read

Filed under App development Rust

Snowflake ID vs UUID: which should you use?

Short answer

Use a Snowflake ID when you need small, fast 64-bit integer keys and can give every generator a unique machine number. Use UUIDv7 when you want IDs any server, phone or browser can mint with no coordination. Both are time-ordered. In our 2-million-row SQLite test, Snowflake keys inserted in 1.37 seconds against 2.18 to 2.64 for UUIDv7, and the database was 36 MB against 56 to 198 MB.

Glowing bar chart titled Snowflake ID vs UUIDv7: 2 million inserts, SQLite, ID as primary key, seconds, lower is faster: Snowflake 64-bit integer 1.4 s, UUIDv7 16-byte blob WITHOUT ROWID 2.2 s, UUIDv7 16-byte blob 2.6 s, UUIDv7 36-character text 2.6 s.
Both IDs are time-ordered, so both append to the end of the index. The 64-bit Snowflake still inserted about twice as fast because SQLite stores it as the row ID itself. Our benchmark, Oct 24 2026. Rendered by Tensorust with the Proof Engine from our benchmark.

Part of the article Pick a UUIDv7 library that keeps order: 10 tested, .NET fails 50%. This page answers one question from it in depth.

On this page · 9 sections
  1. Key numbers
  2. How each one is built
  3. The benchmark
  4. Try it: decode a Snowflake
  5. Common misconceptions
  6. Our take
  7. Related
  8. FAQ
  9. Sources

Key numbers

What Snowflake ID UUIDv7 Source (checked Oct 24 2026)
Size 64 bits (8 bytes) 128 bits (16 bytes; 36 characters as text) Twitter Snowflake README; RFC 9562
Timestamp 41-bit ms since a custom epoch 48-bit Unix ms same
What makes it unique 10-bit machine ID + 12-bit sequence 74 random bits same
Max IDs per ms 4,096 per machine, 1,024 machines no hard limit same
Runs out July 10 2080 (Twitter epoch) about year 10889 our math
2M inserts, SQLite 1.37 s 2.18 s (blob, WITHOUT ROWID) to 2.64 s our benchmark
Database size, 2M rows 36.2 MB 55.5 MB (blob, WITHOUT ROWID) to 197.9 MB (text) same
100,000 point lookups 3.36 s 3.59 to 4.02 s same

Download the data (CSV): all four layouts with insert time, file size and lookup time.

How each one is built

Diagram drawn to scale, 1 bit = 11 pixels. Snowflake, 64 bits: 1 sign bit, 41-bit milliseconds since 2010-11-04, 10-bit node, 12-bit sequence. UUIDv7, 128 bits: 48-bit Unix milliseconds, 4 version bits, 12 random bits rand_a, 2 variant bits, 62 random bits rand_b.
Same idea, a timestamp up front so IDs sort by time, but a Snowflake spends its remaining bits on "who made it", while UUIDv7 spends them on randomness. Sources: Twitter Snowflake README; RFC 9562 section 5.7.

Snowflake comes from Twitter, which needed IDs "under 64bits" when it moved off MySQL in 2010 and published the design as twitter/snowflake (Ryan King and team). A generator stamps the current millisecond, its own machine number and a counter that resets every millisecond. Two generators can't collide unless they share a machine number. Discord uses the same format with a 2015 epoch and splits the 10 machine bits into a 5-bit worker and a 5-bit process.

Screenshot of the twitter-archive/snowflake README on GitHub. Compact: there are many otherwise reasonable solutions that require 128bit numbers; for various reasons, we need to keep our ids under 64bits. Solution: Thrift server written in Scala; id is composed of time, 41 bits, millisecond precision with a custom epoch gives us 69 years; configured machine id, 10 bits, up to 1024 machines; sequence number, 12 bits, rolls over every 4096 per machine.
The original 2010 design note: 41 bits of time, 10 of machine, 12 of sequence, and the reason, "we need to keep our ids under 64bits". Screenshot: github.com/twitter-archive/snowflake, captured October 24, 2026.

UUIDv7 was standardized in RFC 9562 in May 2024 (Kyzer Davis, Brad Peabody and Paul Leach). It puts a 48-bit Unix millisecond timestamp first and fills the rest with random bits, so any process anywhere can make one. PostgreSQL 18 ships a built-in uuidv7() function. Our UUIDv7 vs UUIDv4 test shows why the time prefix matters so much for database inserts.

The benchmark

We generated 2 million IDs of each type and inserted them into SQLite 3 with Python, in 50,000-row transactions, then timed 100,000 random lookups. One run each on a Windows 11 desktop, so read the ratios, not the exact seconds.

Glowing bar chart titled Database size with 2 million rows, SQLite file in megabytes: Snowflake 64-bit integer 36.2, UUIDv7 16-byte blob WITHOUT ROWID 55.5, UUIDv7 16-byte blob 111.7, UUIDv7 36-character text 197.9.
Storing UUIDv7 as 36-character text made the file 5.5 times bigger than Snowflake integers. Storing it as 16 raw bytes in a WITHOUT ROWID table closed most of the gap. Our benchmark, Oct 24 2026.

Three things explain the gap:

  • Snowflake rides the row ID. In SQLite an INTEGER PRIMARY KEY is the table's internal row ID, so there is no separate index at all. Postgres and MySQL get a similar win from a native bigint key.
  • UUIDs need a second structure unless you avoid it. A BLOB or TEXT primary key in a normal SQLite table means the table plus a separate index, which doubled the file (111.7 MB). WITHOUT ROWID stores rows in the key's own B-tree: 55.5 MB and the fastest UUID inserts.
  • Text is the worst of both. 36 characters per ID instead of 16 bytes: 197.9 MB. Store UUIDs as binary or a native uuid type.

Lookups barely differed (3.36 to 4.02 seconds per 100,000), because all four are B-tree searches of similar depth. The difference is size and write speed, and size is what decides how much of your index fits in memory.

Try it: decode a Snowflake

Paste a Snowflake ID (for example a Discord message ID or an X post ID) to see when it was made. Runs in your browser; for the full breakdown use our Snowflake ID decoder.

The creation time under the Twitter/X and Discord epochs shows up here.

That last line is the most common Snowflake bug: JavaScript numbers are exact only up to 2^53 - 1 (9,007,199,254,740,991), so a 19-digit Snowflake parsed with JSON.parse loses its last digits. Discord returns every ID as a string for exactly this reason.

Common misconceptions

Myth

"UUIDs are always slow as primary keys."

The recordThe record: random UUIDv4 keys are slow because they scatter inserts across the index (in our UUIDv7 vs UUIDv4 test, v4 was 16 times slower over 5 million rows). Time-ordered UUIDv7 was within 2x of a 64-bit integer here.

Myth

"Snowflake IDs are guaranteed unique automatically."

The recordThe record: only if every generator has its own machine ID and its clock never runs backwards. Twitter's design refuses to issue IDs while the clock is behind; homemade versions often skip that check.

Myth

"Snowflake IDs reveal nothing."

The recordThe record: the timestamp is in plain sight. Anyone can read when a Discord message or X post ID was created, and, from the sequence, roughly how busy that machine was. UUIDv7 leaks the creation time too; only random IDs like UUIDv4 or NanoID hide it.

FAQ

What is the difference between a Snowflake ID and a UUID?

A Snowflake ID is a 64-bit integer made of a millisecond timestamp (41 bits), a machine ID (10 bits) and a per-millisecond sequence (12 bits), a format Twitter published in 2010. A UUID is 128 bits; version 7 (RFC 9562, 2024) holds a 48-bit Unix millisecond timestamp and 74 random bits. Snowflakes need a unique machine ID for every generator; UUIDv7 needs no coordination.

Is a Snowflake ID faster than UUIDv7 in a database?

Usually yes, because it is half the size and fits a native 64-bit integer column. In our 2-million-row SQLite test a Snowflake primary key inserted in 1.37 seconds versus 2.18 to 2.64 seconds for UUIDv7, and the database was 36.2 MB versus 55.5 to 197.9 MB. Point lookups were close: 3.36 versus 3.59 to 4.02 seconds per 100,000.

Why do APIs send Snowflake IDs as strings?

JavaScript numbers are exact only up to 2^53 - 1, and a Snowflake can use up to 63 bits, so parsing one as a number silently changes its last digits. Discord's API returns every Snowflake as a string for this reason, and Twitter's API added id_str fields.

How long do Snowflake IDs last?

Twitter's 41-bit millisecond timestamp covers about 69.7 years from its custom epoch of November 4, 2010, so it runs out in July 2080. UUIDv7's 48-bit Unix millisecond timestamp lasts until about the year 10889.

Can two Snowflake generators produce the same ID?

Only if they share a machine ID or a clock goes backwards. Each generator must have a unique 10-bit machine ID (1,024 in total), and Twitter's design refuses to generate IDs when the clock moves back. UUIDv7 avoids both problems by using random bits instead of a machine ID.

Sources

All checked October 24, 2026.

Specs and docs

Our data

  • data.csv: our benchmark, October 24, 2026. 2,000,000 IDs per layout inserted with executemany in 50,000-row transactions; tables t(id <type> PRIMARY KEY, n INTEGER), plus a WITHOUT ROWID variant for the 16-byte blob; then 100,000 random point lookups. Python 3.12 sqlite3, journal_mode=off, synchronous=off, one run each, Windows 11 desktop. Snowflakes from a single-worker generator (Twitter epoch, worker 1); UUIDv7 from our own RFC 9562 generator (48-bit ms timestamp, 74 random bits). The run-out dates (2^41 ms after the Twitter epoch, 2^48 ms after 1970) are our math.

Images

  • Benchmark charts rendered by Tensorust with the Proof Engine. Bit-layout diagram drawn by Tensorust from the README and RFC 9562. README screenshot: github.com, captured October 24, 2026.

Next question

Every number on this page links to its source and was checked on Oct 24, 2026. Spot an error or a newer figure? Email matt@tensorust.com and it gets fixed. Related: Snowflake ID decoder, UUIDv7 generator and decoder.

Read next

Back to The Manual →   All articles →

Get the next one by email.

What my AI agents tried this week, with the real numbers: what worked, what flopped, what made money. One email when there is something worth reading.

No spam, never sold. Every email has a one-click unsubscribe.

Up next

The article this answer comes fromPick a UUIDv7 library that keeps order: 10 tested, .NET fails 50%We tested 10 UUIDv7 libraries with 1M IDs each and a clock jump. .NET put 50% out of order, uuid6 ran 16.6 min ahead. The 2 that passed, plus free data.Read it next →

Get the receipts by email.

What my AI agents tried this week, with the real numbers: what worked, what flopped, what made money. One email when there is something worth reading.

No spam, never sold. Every email has a one-click unsubscribe.

Cite this

Free to cite and reuse under CC BY 4.0 with a link back. How it was collected: methods. Spotted an error? Corrections.

Did this answer your question?

Popular in the shop

All 124 tools →

Browse: Bundles and kitsHome, family and schoolMoney and businessAI toolsSports and fitnessMaking and hobbiesFood and drinkIndie dev and launchTrading and quant

Free: Landing page teardown iPhone app cost calculator LLM API cost calculator Paid online: $49 Launch Check App builds Articles FAQ

Disagree, or have a number to add? Discuss this on The Floor →