The efficient way to create GUID/UUID in JavaScript (with explanation)

22 May

I want to share with you the fastest GUID/UUID generator method (as far as I know).

Million executions of this implementation takes just 32.5 seconds, which is the fastest i’ve ever seen in a browser (the only solution without loops/iterations).

The function is as simple as:

 * Generates a GUID string.
 * @returns {String} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser ([email protected]).
 * @link

function guid() {
    function _p8(s) {
        var p = (Math.random().toString(16)+"000000000").substr(2,8);
        return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
    return _p8() + _p8(true) + _p8(true) + _p8();

To test the performance, you can run this code:

for (var i = 0; i < 10000000; i++) {

I’m sure most of you will understand what I did there, but maybe there is at least one person that will need an explanation:

The algorithm:

  • The Math.random() function returns a decimal number between 0 and 1 with 16 digits after the decimal fraction point (for example 0.4363923368509859).
  • Then we take this number and convert it to a string with base 16 (from the example above we’ll get 0.6fb7687f).
  • Then we cut off the 0. prefix (0.6fb7687f => 6fb7687f) and get a string with eight hexadecimal characters long.
  • Sometimes the Math.random() function will return shorter number (for example 0.4363), due to zeros at the end (from the example above, actually the number is 0.4363000000000000). That’s why i’m appending to this string "0000000000" (a string with nine zeros) and then cutting it off with substr() function to make it nine characters exactly (filling zeros to the right).
  • The reason of adding exactly nine zeros is because of the worse case scenario, which is when the Math.random() function will return exactly 0 or 1 (probability of 1/10^16 for each one of them). That’s why we needed to add nine zeros to it ("0"+"000000000" or "1"+"0000000000"), and then cutting it off from the second index (3rd character) with a length of eight characters. For the rest of the cases, the addition of zeros will not harm the result because it is cutting it off anyway.

The assembly:

  • The GUID is in the following format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  • I divided the GUID into 4 pieces, each piece divided into 2 types (or formats): XXXXXXXX and -XXXX-XXXX.
  • Now I’m building the GUID using these 2 types to assemble the GUID with call 4 pieces, as follows: XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX.
  • To differ between these two types, I added a flag parameter to a pair creator function _p8(s), the s parameter tells the function whether to add dashes or not.
  • Eventually we build the GUID with the following chaining: _p8() + _p8(true) + _p8(true) + _p8(), and return it.

Enjoy! 🙂


Tags: , , , , , ,

Leave a Reply


  1. Mark Stratmann

    August 28, 2013 at 15:33

    Nice one,

    Just what I needed.


    • Kate

      April 8, 2014 at 00:26


      Exactly what I was looking for.

  2. Broofa

    December 9, 2014 at 23:20

    1. These are not valid RFC4122 IDs. (Making them valid is fairly trivial – just make sure the ‘variant’ and version’ fields are set properly.)
    2. “Million executions of this implementation takes just 32.5 seconds” is a largely meaningless statement without a description of the JS execution environment you’re running this code in.
    2a. … and my experience (with the node-uuid project) is that UUID generation performance isn’t a significant concern. I suspect this is because the work required to generate a UUID is insignificant compared to work being done by the calling code (e.g. creating new data structures, updating UI, issuing network requests, persisting state to a data store, etc.)

    Just my $.02.

    • Slavik Meltser

      February 20, 2015 at 11:47

      1. It is not RFC4122 compliance, but a random ID that looks like GUID.
      2. I tested it on WebKit engine. You are welcome to test it yourself wherever you like, that’s why I published a test case.
      2a. In my case, I generated several thousands of these at once, so the for me performance was important.

  3. Manny

    February 19, 2015 at 15:18

    Works perfectly… and clearly explaned to wit.
    Nice work Slavik. Thanks for publishing this.

  4. sachadee

    May 6, 2017 at 17:18

    Thanks a lot for this code and explanaition !