Skip to content

System Design

Unique ID Generator (Snowflake-Style)

O(1) time and space per ID generated — just a few shifts and an OR.

The idea, in plain English

Think of a car license plate. It packs a state code, a year, and a serial number into one plate. No two cars ever collide, even ones made in different states at the same time. A Snowflake-style ID does the same trick for database rows. It combines three things into one number: the current time, which server made the ID, and a small counter. The counter ticks up if the same server makes more than one ID in the same instant. Combine all three, and every server can hand out IDs at the same moment — without ever handing out the same one twice.

How it works

  1. 1Reserve some bits of the final number for a timestamp. Reserve more bits for a machine ID — which server made it — and the rest for a sequence counter.
  2. 2Shift the timestamp left, past the machine-ID and sequence bits. Shift the machine ID left, past the sequence bits. Then combine all three into one number with a bitwise OR.
  3. 3If two IDs are requested at the exact same timestamp, bump the sequence counter so they still come out different. When the timestamp changes, reset the counter to 0.

When you'd use it

Use this when you generate IDs across many servers at once, so you can't just use an auto-incrementing database column. You still want IDs that sort roughly by creation time. This is common in large-scale systems, like chat messages, orders, or analytics events.

Common beginner mistakes

  • Reading the real system clock inside the core logic. This makes the code hard to test, and the clock can even go backwards if the server's clock gets adjusted. Instead, pass the timestamp in as a value, like this example does.
  • Forgetting to reset the sequence counter when the timestamp moves forward. Without the reset, the counter keeps climbing forever instead of starting fresh each 'tick.'

Try it — edit and run

Click the code to edit · press ⌘/Ctrl+↵ to run

Editable code. Tab and Shift+Tab indent. Press Escape, then Tab, to move focus out of the editor.

Expected output — hit Run to try it
t=100: id=3279872
t=100: id=3279873
t=100: id=3279874
t=101: id=3312640
t=101: id=3312641
t=205: id=6720512
All IDs unique: yes

Not sure this is the right topic? See the learning paths → or where this leads →