Hello everybody, I'm Nick and in this video I'm going to introduce you to the brand new type of ID being added in.NET 9, aiming to replace how we used to use GUIDs until now, as well as integers in some case. Now, this ID mostly has to do with databases, usually relational databases, and it builds on top of what we already know about GUIDs. However, the biggest issue with GUIDs is that they can cause a bunch of very nasty performance issues on databases when they're used in many scenarios as primary keys. So you have this problem where it makes sense to use a GUID in a database as a primary key but you can't because you really need that performance.
So you fall back to an integer and usually you have an auto incremented integer because you want that ordering. However that has its own problems. So what I'm going to show you in this video aims to solve both issues and it's doing it by introducing a new type of ID called a UUID.
version 7. First let's just recap on how we create a GUID in C sharp right if you want to create a GUID all you do is GUID new GUID and you usually use that basically everywhere especially as an ID and especially in NoSQL databases this is pretty much the way to do ID in NoSQL databases because you don't need to check any database to see if it exists because the fact that it exists is astronomically small so you can keep calling GUID.newGUID in an extremely distributed system and you don't have to worry about other services in that system creating the exact same ID so you can assume it's globally unique. That's what GUID stands for, globally unique identifier and it's building on the UUID, universally unique identifier which some people use interchangeably but it's not quite the same thing but let's just treat it as the same thing. And some of you might already know that GUID in C sharp is often associated with the version 4 of the UUID.
Now if you want the specification on how UUIDv4 works, I'm going to put a link in the description if you want to read further. But basically, UUIDv4 is meant for generating UUIDs for truly random or pseudo-random numbers. That's the idea.
Preventing clashes. It's very unlikely it's going to exist anywhere else with this value. It's 128 bits and we've been using it for years and the distribution of bits doesn't really matter but what does matter is the new version of GUI that we're going to have now in dotnet 9 which is a UUID v7 and what makes the UUID v7 special well as we're going to see down here it is time ordered because the first bits is actually time it's a unix timestamp making it sorted making it orderable and that sortability the fact that it's ordered fixes the problem that we can have in databases.
So if you need that, you should be using this new v7 in your applications in.NET 9. Now, I don't think you should retroactively go ahead and use it in existing databases. I don't know what clashes that might cause. I'm also not a DBA, so it's not something I can go ahead and say, if you use v4 now in an existing system, go and use v7 everywhere. But you should know that this will now exist.
So if you have a new system, Maybe it's something you can use. Now, before I show you how you can use this new type of UUID in.NET 9, I do want to mention that we're running a summer sale on Domotrain. Until the 14th of July, you can get 30% off any course, including the brand new OpenTelemetry course that we just launched. It's a unique opportunity because usually you get 15% to 20% discount on launch.
But until the 14th, you can get that for 30%. It's an amazing course. No developer should be building applications without OpenTelemetry baked in.
So if you want to find more about that, you can link in the description. or use code summer24 at checkout to get 30% off. Now, making that UUID 7 is very, very easy. All you need to do, again, using the exact same GUID type, you're going to go ahead and say GUID create version 7. And that will create your GUID.
So if I go ahead and I run it, you're going to see that it looks very much the same. But if I go ahead and I do this five times, what you will notice is that GUID starts... In a very very similar way you can see these first bits they look very similar because they represent time.
And that's exactly the problem that this thing solves. In fact, we now also have an overload for create version where you can pass down the date time offset as a timestamp. So you can say time provider using the new time provider, use the system, and then you can say get UTC now. So you can get the UTC now and you can push that further in the past, you can move it in the future. And that is also the default.
So if we go in here, you'll see that timestamp. is taken into account, it's being converted into Unix time in milliseconds and then it's used in the algorithm to convert it into what we eventually get back. In fact looking at this, and I'm looking at this for the first time, I don't know if it's going to be final but it's interesting that they use just the new GUID method of how we create a normal GUID, a v4 GUID, and then they go ahead and they use unsaved.asRef to very efficiently write the bits of that timestamp in milliseconds.
on the A, B, C, and D parts of the UUID, because as you know, it is integer, short, short, and then a bunch of bytes, and the rest they leave untouched, which I find very interesting. I don't know if that's the most optimal way to do this. And in fact, I think I saw a comment saying, this is probably not the most optimal way to do this, but they don't have an easy way to get secure random bytes in Colib, the BCL.
without doing this since the secure RNG is in a different layer. I don't know enough about this but I do know that we can see over here that 1 the power of 48 is roughly 8,925 years which from the Unix epoch means won't overflow until July of 10,895. The poor developer whose system will crash in 8,000 years I really feel for them but for now I don't have to worry about it and I will also be dead. Now what's interesting about all this is that well If you have to do extra work on top of generating a GUID, which, you know, we go from new GUID to new GUID plus add time in the mix.
Well, this isn't going to have a performance impact. And let's take a look at that. I'm going to say benchmark runner dot run benchmarks and the benchmarks I'm going to run was very simple.
I have the V4, the new GUID, and then I have the V7 create version four. So if I go ahead and I just say, run this, let's take a look. at what results we get back how the two different versions compare okay so results are back and let's see what we have here so as you can see we go from 37 nanoseconds to 70 nanoseconds it's around twice as slow to generate the time ordered good the v7 compared to the v4 the new good version so clearly there is a performance hit now if you have this sort of use case it's very unlikely these 40 nanoseconds should ever bother you and there's no memory allocation difference because as we can see Microsoft is being very cheeky to write the date time very efficiently by using unsaved.asref. So it's not something you have to worry about and if you are using GUIDs as database keys use this feature.
You should not be using integer, you should not be using the traditional GUID, you should be using this. It will be more efficient for your system in general even though it takes longer. to generate i don't think you should even look at this longer at all you're gonna gain more by just using it and ultimately it's replacing code that you already have because there's many new packages that try to offer the same uuid v7 some of them have half a million downloads recently updated nine days ago 11 days ago a month ago so these things exist people have a use case for this and if you're not using something like snowflake id or any sort of other globally distributed ordered ID. I think this is the easiest way to get into this without breaking your existing API because ultimately this just maps back to a GUID.
It is not a new distinct type. It just takes those new ordered bits into account in the first half. But now from you, what do you think about all this?
And have you been using any other type of ID? Leave a comment down below and let me know. Well, that's all I have for you for this video.
Thank you very much for watching. And as always, keep coding.