Design a Unique ID Generator (Distributed Systems)
Thank you for studying with us
The website closes on August 31st and the chapter audio moves to YouTube, free. Everything here is unlocked until then.
If you've supported us already — thank you, genuinely. If this helped you and you'd like to put something toward the last of the running costs, it means a lot.
ⓘ This audio and summary are simplified educational interpretations and are not a substitute for the original text.
Key Takeaways
- Twitter Snowflake partitions 64 bits into timestamp, datacenter, machine, and sequence components for distributed ID generation
- 41-bit millisecond timestamp enables chronological sorting and supports approximately 69 years before migration needed
- 12-bit sequence counter allows 4,096 unique IDs per millisecond per machine, exceeding 10,000 per second requirement
- 5-bit datacenter and 5-bit machine fields support up to 32 datacenters with 32 servers each
- Network Time Protocol synchronization ensures clock consistency across geographically distributed servers
- Snowflake's flexible architecture permits customization based on application-specific datacenter, density, and throughput requirements
Chapter Transcript
Read a transcript excerpt below, or use Study Mode for synchronized audio follow-along.
0:18Welcome to the Deep Dive. So today we're tackling a topic that, it seems simple on the surface, giving every piece of data a unique name. Right. But it becomes one of the most foundational and complex challenges in distributed systems, generating a unique identifier or UID at a massive scale. It's the digital version of trying to issue serial numbers for, I don't know, every single transaction, every user, every tweet.
0:44All at the same time. All happening simultaneously across the globe without some single central registry. You know, historically we just rely on the database's primary key, that simple, comforting auto increment. And that comfort is the first thing to go when you scale up. The moment you move from one database server to dozens, maybe hundreds, all over the world. That one central counter becomes an immediate paralyzing bottleneck.
1:08You just kill performance with coordination delays. Absolutely.
1:11Our source material lays this out beautifully. The moment you go distributed, the old tools break. So our mission today is to analyze the trade -offs of the most common approaches. And then do a really deep architectural dive into the one solution that satisfies a set of extremely demanding criteria. Exactly. So let's unpack those criteria first. The source has really stressed that the first step is always defining the scope.
1:36And we've got five non -negotiable requirements for this generator. Right, so the first one is, well, it's the obvious one, but it's absolutely critical. Uniqueness. The IDs have to be unique across the entire system forever. You violate that. Your entire database schema just collapses. It's that fundamental. Okay, so requirements two and three. These seem to set some really tight constraints that just eliminate a lot of options right off the bat.
2:02They do. The IDs must be numerical only. No letters, no special characters. Just numbers. And they must strictly fit within a 64 -bit integer. That's a hard limit you often see imposed by existing database designs. And the final two points are about usability and, of course, scale. Requirement four is order. The IDs have to be chronologically sortable. So an ID generated at 5 p .m. has to be mathematically larger than one from 9 a .m.
2:27Even if they were made on totally different servers. Exactly, we don't need them to go up by exactly one every time, just reliable chronological order. And finally, the big one. The system has to be truly high -scale. It needs to handle the load. We need to be able to generate over 10 ,000 unique IDs per second across the whole cluster. Okay, so if a design fails, even one of these five rules, it's out.
2:53It's not suitable for this architecture. So now we can start running the gauntlet. The source material outlines four primary designs, and we'll see pretty quickly why the first three just don't make the cut. Okay, so first up is the attempt to kind of patch the old system. Multi -master replication is where we stick with auto -increment, but try to sync multiple databases. Yeah, the trick here is that if you have, say, K servers, you set the increment step size to K.
3:19So with three servers, server A gets IDs one, four, seven. And B gets two, five, eight, and C gets three, six, nine. Right, they stay unique. But what's the fatal flaw? Well, we're back to geography, aren't we? It's gotta be a nightmare to manage and keep that consistent across different data centers. That's the administrative headache for sure, but the real showstopper is requirement for chronological order. Ah.
3:42Because clocks and network delays are different everywhere. Server A might generate ID seven at 10 .05 AM, but server B might generate ID eight a minute earlier at 10 .04 AM. Oh, I see, so when you pull the records, you have a bigger ID number that actually represents an earlier event. Exactly. If you're using these to sort an activity feed or an audit log, the whole sequence is corrupted.
4:07Your user sees post number eight appear before post number seven. That approaches out, done. So next, we have what's usually the gold standard for global uniqueness and simplicity, the universally unique identifier, or UUID. Right, UIDs are everywhere. They're these 128 -bit numbers that any server can just generate instantly on its own without talking to anyone else. It scales instantly. And here's that amazing fact from the source.
4:31You could generate a billion UUIDs every single second for 100 years. And still only have a 50 % chance of a single duplicate. They solve uniqueness perfectly. They solve uniqueness, but they fail basically everything else we need for this system. One, they're 128 bits long. We need 64. Too big. Two, the format, you know, that long string of hex characters isn't guaranteed to be just numbers. And three, they fail on chronological order.
4:58You can use time -based versions, but even then, they don't sort neatly in a database. So for our constraints, it's a quick fail. Okay, that brings us to contender number three, an approach that Flickr famously used, the ticket server. The ticket server is appealing because it's, well, it's centralized reliability. You have one dedicated database server, the ticket server, and its entire job is to just hand out perfectly sequential numbers.
5:22It's a broker for unique IDs. So we're back to being centralized again. The ticket server generates a block of IDs, like a thousand at a time, and hands them out to our web servers to use. Exactly, gives you numeric IDs. It's easy to implement for smaller applications. It's conceptually very simple. But the downside has to be that single point of failure. If that one server goes down, the whole application stops.
5:44No new users, no new posts, no new anything. That's the obvious problem. But here's the deeper issue. You try to fix it by adding another one for redundancy to ticket servers. Right. The moment you do that, you're right back to the original problem. How do they coordinate which ID to serve next? You're back to the multi -master challenges, you lose the simplicity, you get potential ordering issues again, and it's still way less scalable than a truly distributed solution.
6:10So multi -master fails on ordering, UUID fails on size and format, the ticket server fails on availability and scale. Which leaves us with the final option, the only one that checks all five of our demanding boxes. The Twitter snowflake approach. This solution is such an elegant, well, it's a demonstration of divide and conquer. Instead of one big opaque number, we strategically encode the context, the time, the origin, the sequence, directly into the 64 bits of the ID itself.
6:39So the ID carries its own history. That's gotta be huge for sorting and for troubleshooting. Yeah. Okay, let's break down how the 64 bits are segmented. Picture from left to right in five sections. The first section is tiny, but really important. The sign bit. It's just one bit and it's always set to zero. Wait, why would you always set it to zero? You're intentionally giving up half your possible IDs.
7:01It's all about simplicity and compatibility. It ensures the ID is always a positive number, which avoids all kinds of headaches with how different programming languages and databases handle signed versus unsigned integers. It's an operational choice for stability. Okay, a safety bit. After that, we hit the big one, the timestamp, which is 41 bits. You said this is the key to getting that chronological sorting. It is. Then we have two smaller chunks that identify where the ID came from.
7:27A five bit data center ID and a five bit machine ID. And the last piece for handling really rapid requests is the sequence number, which is 12 bits. Let's look at those two identifier sections first. Five bits for the data center ID gives us two undefined of iVilers or $32 unique data centers. And the five bits for machine ID means we can have 32 unique machines inside each of those 32 data centers.
7:50That's a huge, clear structure. And what's so powerful here is the operational benefit. If a bad ID shows up in a log somewhere, you can instantly look at those 10 bits and know exactly which global region and which specific machine in that region created it. It's amazing for auditing. But I imagine those IDs have to stay fixed. Oh, absolutely. They're chosen at startup and they cannot change.
8:12If you accidentally change one mid run, you risk collisions. Okay, so now that 41 bit timestamp, because it's at the beginning of the number, the most significant part, that's what a database sees first when it's sorting. Exactly. And since the timestamp is always growing, the entire 64 bit ID is inherently time ordered. It stores time in milliseconds, sets a specific starting point, which is known as an epoch.
8:34And this is where Twitter famously chose a custom epoch, right? November 4, 2010? They did. Why do that? Why not just use the standard Unix epoch from 1970? Because those 41 bits can only represent 241 milliseconds. That translates to about 69 years of time. If they had started from 1970, their ID system would fail decades ago. By picking a custom epoch in 2010 closer to their launch, they bought themselves the full 69 year runway.
9:0169 years sounds like a long time, but in architecture, that's a fixed expiration date. After 69 years from your custom epoch, that field overflows and the whole generator breaks. It's a migration you have to plan for from day one. Okay, finally, let's look at how this design hits that huge scale requirement, over 10 ,000 IDs per second, using that last piece, the sequence number. So we have 12 bits here.
9:25That gives us $212, which is 4 ,096 combinations. And what does that do? This is the concurrency safeguard. It's a counter that goes up every time more than one ID is requested in the very same millisecond on the very same machine. The instant the millisecond ticks over, that counter resets to zero. So on a single machine, we can generate 4 ,096 unique IDs in just one millisecond.
9:45Which is 4 ,096 ,000 IDs per second per machine. Our original requirement was 10 ,000 IDs per second system -wide. A single machine, in theory, could handle that all by itself. So running even a handful of these snowflake generators just all. It easily and robustly crushes that scale requirement. So the Twitter snowflake -like approach is the clear winner. It's the only one we looked at that hits all five requirements.
10:11Unique, numeric, 64 -bit, time -ordered, and massively scalable. But you know, in a real -world scenario, the conversation doesn't stop there. Once you've defined the bits, there are three advanced operational things you have to consider to make this production ready. Okay, what's the first one? The first, and maybe the trickiest, is clock synchronization. The whole sorting guarantee depends on the assumption that all your ID servers have perfectly synchronized clocks.
10:37And that's a dangerous assumption. It's a very tricky assumption. Even inside one multi -core server, let alone a global fleet, if a machine's clock suddenly drifts backward, even for a fraction of a second. It could reuse a timestamp from a moment ago. And generate duplicate IDs. Which violates our number one rule. So you need external tools to manage that risk. Yes. The common solution is using something like the Network Time Protocol, or NTP, to keep time in check.
11:04If a clock drifts too far, the system has to be smart enough to just stop generating IDs until it catches up. What about changing requirements over time? You mentioned that 69 -year lifespan. That leads us to section -length tuning. Right. That 64 -bit split isn't sacred. It's highly customizable. Let's say your application has really low concurrency. Maybe it only needs 50 IDs a second. But it has to last for a hundred years.
11:28You could trade some of those sequence bits. Maybe take it down from 12 to eight or nine. And give those extra bits to the timestamp field. Extend that 69 -year lifespan to a hundred years, or even more. It's a powerful trade -off that lets you perfectly fit the ID structure to your application's profile. More traffic, more sequence bits. Longer lifespan, more timestamp bits. Precisely. And finally, circling back to why the ticket server failed.
11:53High availability. The ID generator is mission critical, so the system running it has to be built to never fail. Correct. We solved the ID generation problem with Snowflake, but the system hosting that generator still needs to be highly available. Redundant processes, fast failover, health checks. You need to be sure there's always a machine ready to serve IDs. What stands out to me is just how this simple act of dividing a number segmenting 64 bits into time, location, and sequence was the key to solving all these complex, multi -layered problems like scale and sortability.
12:27It's the ultimate lesson in structuring information. It really is. When your identifier carries its own context, you just drastically reduce the need for all that complicated, expensive, external coordination across your network. Thank you for joining us on this deep dive into distributed unique ID generation. We saw why traditional database tools fail at modern scale and explored the elegant complexity of the Twitter Snowflake model. And since that 41 -bit timestamp only guarantees a 69 -year lifespan from the moment an architect picks their custom epoch and systems built today are expected to last for decades, our final thought for you is this.
13:02As architects today set their new custom epochs closer and closer to now at get the longest runway, what specific measurable migration techniques must those modern systems design and build today to successfully manage that inevitable timestamp rollover decades in the future, long before their architecture's built -in expiration date?