A UUID (Universally Unique Identifier), sometimes called a GUID by Microsoft, is a 128-bit value defined originally by the Open Software Foundation, then RFC 4122, and most recently RFC 9562. It is rendered as 32 lowercase hex digits separated by hyphens into the canonical 8-4-4-4-12 grouping (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). Two of those 128 bits encode the variant; another four encode the version. The remaining 122 bits carry the actual identifier.
This generator produces v4 (random) and v1 (time-based) UUIDs. v4 is the workhorse used by almost every modern system: 122 of the 128 bits are random, giving a collision probability so small that you would need to generate 1 billion UUIDs per second for 85 years before reaching a 50 percent chance of any duplicate (the birthday-paradox bound). For v4 we prefer the browser's built-in window.crypto.randomUUID() when available — that is a native, cryptographically secure implementation specified in the Web Crypto API. We fall back to a manual implementation seeded with Math.random only on browsers without that API.
v1 is more involved. It encodes a 60-bit timestamp counted in 100-nanosecond intervals since the Gregorian reform date 1582-10-15 UTC (the UUID epoch). Our implementation reconstructs that count from Date.now(), splitting it into 16-bit halves to keep arithmetic within JavaScript's 53-bit safe integer range. The clock_seq field gets random bits (the spec allows random initialization on each generator instance), and the node identifier — historically a MAC address — is also random because browsers cannot read network hardware addresses.
Use v1 when you need IDs that are roughly time-sortable so they cluster together on disk and in indexes (which can dramatically improve insert performance on B-tree primary keys in MySQL). Use v4 when you do not want the timestamp to leak when a record was created, or when you do not need ordering. If you want both ordering and randomness, look at v6 and v7 from RFC 9562, ULID, or KSUID — modern alternatives that solve the index-locality problem of v4 without leaking generator metadata like v1.
Common pitfalls to avoid: treating the version nibble or variant bits as random (they are not — they are fixed by the spec, which is why generated UUIDs always have a 4 or 1 at position 13 and one of 8/9/a/b at position 17); storing UUIDs as VARCHAR(36) when binary(16) would save space and speed indexes (Postgres has a native uuid type, MySQL needs UUID_TO_BIN); using v4 as a security token (it is not — 122 bits is plenty for uniqueness but treat it as predictable enough to require additional entropy when authentication is at stake); and relying on uniqueness across systems that all use Math.random — only the crypto-backed implementations are truly collision-safe at scale.
Performance details that surprise people: PostgreSQL stores UUIDs in 16 bytes natively and indexes them well, but the random distribution of v4 causes B-tree fragmentation in clustered indexes (MySQL InnoDB primary keys) — that is why high-throughput systems often pick v1, v6, v7, or ULID. SQL Server's default GUID generation is non-sequential too, but NEWSEQUENTIALID exists for the same reason.
All generation happens locally. Nothing is sent over the network. crypto.randomUUID() draws from the OS CSPRNG, while the v1 implementation uses Math.random for the clock and node fields, which is sufficient for uniqueness but explicitly not cryptographically secure — do not use v1 output here as a session token.