Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,128 | Comments: 45,550

filter by tags archive

CreateSequetialUuid – Answer

time to read 2 min | 248 words

I got a lot of interesting answers for the riddle, and here is my solution:

private static int sequentialUuidCounter;
public static Guid CreateSequentialUuid()
    var ticksAsBytes = BitConverter.GetBytes(DateTime.Now.Ticks);
    var increment = Interlocked.Increment(ref sequentialUuidCounter);
    var currentAsBytes = BitConverter.GetBytes(increment);
    var bytes = new byte[16];
    Array.Copy(ticksAsBytes, 0, bytes, 0, ticksAsBytes.Length);
    Array.Copy(currentAsBytes, 0, bytes, 12, currentAsBytes.Length);
    return bytes.TransfromToGuidWithProperSorting();

Basically, we use the current system ticks as the 1 – 8 bytes, and a counter incremented atomically on the 12 – 16 bytes. This ensures that even concurrent calls on the same tick will have a different value.

Note that this code explicitly allows the same guid on multiple machines. You can fix that by adding the MAC address as 9 – 12 bytes, which will make this globally unique, but this isn’t something that I actually need.

Additional challenge, why am I reversing the bytes?


Daniel Grunwald

You are reversing the bytes because you want a big-endian representation of the numbers so that the GUIDs sort the same way as the numbers.

BitConverter returns little-endian on all architectures where MS.NET (currently) runs, so you need to reverse the bytes.

However, for portability, I would write:

if (BitConverter.IsLittleEndian) Array.Reverse(...);

Peter Morris

You want the most significant data on the left so that index entries are always added to the end of the index rather than having to be inserted?


There is a nasty bug in here: When network time sync kicks in the clock can jump back a bit. Then the guids are not sequential anymore. You can switch to recording DT.UtcNow on app startup and then adding Environment.TickCount to it (that will wrap every 40 days however).

Ken Egozi

Yup, DateTime.UtcNow is probably a better choice than DateTime.Now


Ken: I did not even see that. Your database will have a hiccup twice a year because of daylight savings^^


@tobi: Actually, it would only be a hiccup once per year, as clocks going forward to daylight savings time won't have any affect... it's just when the clocks go back that you get an issue! :O)

Mark J. Miller

I had been writing a Comb class when you first posted about this and pointed out the Sql Server sorting tidbit. I had started a post a day or two ago (honest) to show my version. Since you posted this one, I thought I'd just throw mine up real quick for comparison. www.developmentalmadness.com/.../...s-in-.net.aspx

I can't say I know why you're reversing your byte arrays though. As far as SQL Server is concerned I know from your last post on this topic that you specifically mentioned that and your means of fixing the issue (which I copied). But I know you're doing this for RavenDb, however from your "make this code run faster" post it looked like you were transforming values back and forth between Sql Server and Ascent sorting - could that have something to do with it?

Michael Morton

@James_2JS: Some places do not observe DST.

Ayende Rahien


Ticks aren't local time, they are time from known location in the past. So it doesn't matter about UTC.

TickCount would mean that I can only work for ~41 days or so, which is bad.

I am willing to leave with the issue of the clock sync, though. The current time would change as well, which is fine by me

Ayende Rahien


I know, I am not using SQL sorting.


Ticks aren't local time, they are time from known location in the past. So it doesn't matter about UTC.

That's not true :) Doing

DateTime.Now.Ticks - DateTime.UtcNow.Ticks;

will give you the difference it ticks according to your time zone. for me it's reporting ~ 144000000000 ticks, which is 4 hours, because I'm in UTC+4 zone.

so, in a few weeks the value of DateTime.Now.Ticks will jump, because we will move to UTC+3 due to DST, while DateTime.UtcNow.Ticks won't jump

Ayende Rahien


Huh?! I didn't know that.



Ticks aren't local time, they are time from known location in the past. So it doesn't matter about UTC.<<

This can be said about Environment.TickCount IMHO.

Comment preview

Comments have been closed on this topic.


  1. The worker pattern - 12 hours from now

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    26 May 2016 - The client side
  2. RavenDB 3.5 whirl wind tour (14):
    25 May 2016 - Got anything to declare, ya smuggler?
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats