Before you start
Almost every platform can generate a UUID in one line, but three decisions are worth making up front, because they are hard to change later.
- Pick the version. Version 4 is random and supported everywhere. Version 7 is time-ordered and better for database primary keys. If you are unsure, read UUID v4 vs v7 first.
- Use a cryptographically secure generator. The built-in functions shown below all do. Avoid copy-pasted snippets that build UUIDs from
Math.random()or similar functions; they are predictable and collide far more often than real UUIDs. - Store UUIDs natively. Use your database’s UUID or 16-byte binary type rather than a 36-character text column.
Need a few IDs right now without writing code? The UUID Generator creates versions 1, 4, 6, and 7 in bulk in your browser.
JavaScript in the browser
Modern browsers include crypto.randomUUID(), which returns a version 4 UUID as a lowercase string. It is available in secure contexts, meaning pages served over HTTPS or from localhost.
const id = crypto.randomUUID();
console.log(id); // for example "3b241101-e2bb-4255-8caf-4136c566a962"For version 7, or to support older environments, use the widely used uuid package. Version 10 and later include v7().
import { v4 as uuidv4, v7 as uuidv7 } from 'uuid';
const randomId = uuidv4();
const orderedId = uuidv7();Node.js
Node.js has a built-in version 4 generator in the crypto module, so no package is needed for random UUIDs.
import { randomUUID } from 'node:crypto';
const id = randomUUID();For version 7 in Node.js, use the same uuid package shown above.
Python
The standard library uuid module returns UUID objects. Convert them with str() for the hyphenated form or .hex for 32 digits without hyphens. Python 3.14 added uuid7() to the standard library.
import uuid
random_id = uuid.uuid4()
print(str(random_id)) # hyphenated, lowercase
print(random_id.hex) # 32 hex digits, no hyphens
ordered_id = uuid.uuid7() # Python 3.14 and laterTo check whether a string is a valid UUID, try to parse it. uuid.UUID(value) raises ValueError for invalid input.
Java
java.util.UUID generates version 4 values and parses existing UUID strings.
import java.util.UUID;
UUID id = UUID.randomUUID(); // version 4
String text = id.toString();
UUID parsed = UUID.fromString(text); // throws IllegalArgumentException if invalidThe JDK does not generate version 7 yet. The Java UUID Generator library (com.fasterxml.uuid:java-uuid-generator) provides it.
import com.fasterxml.uuid.Generators;
import java.util.UUID;
UUID ordered = Generators.timeBasedEpochGenerator().generate(); // version 7C# and .NET
.NET calls UUIDs GUIDs. Guid.NewGuid() creates a version 4 value, and .NET 9 added Guid.CreateVersion7().
Guid randomId = Guid.NewGuid(); // version 4
Guid orderedId = Guid.CreateVersion7(); // version 7, .NET 9 and later
string text = randomId.ToString(); // lowercase, hyphenatedGo
The github.com/google/uuid module is the common choice. NewV7 returns an error alongside the value, because it depends on the system clock and random source.
import "github.com/google/uuid"
randomID := uuid.New() // version 4
orderedID, err := uuid.NewV7() // version 7
if err != nil {
// handle the error
}PostgreSQL
PostgreSQL has a native uuid type. gen_random_uuid() is built in from version 13, and PostgreSQL 18 added uuidv7().
SELECT gen_random_uuid(); -- version 4, PostgreSQL 13 and later
SELECT uuidv7(); -- version 7, PostgreSQL 18 and later
CREATE TABLE orders (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
created_at timestamptz NOT NULL DEFAULT now()
);MySQL
MySQL’s UUID() function returns a version 1 UUID, which contains a timestamp but stores it in an order that sorts poorly. Converting it with UUID_TO_BIN(value, 1) swaps the time fields so the stored bytes increase over time, and BIN_TO_UUID(value, 1) converts back for display.
SELECT UUID(); -- version 1
CREATE TABLE orders (
id BINARY(16) PRIMARY KEY DEFAULT (UUID_TO_BIN(UUID(), 1))
);
SELECT BIN_TO_UUID(id, 1) AS id FROM orders;If you generate version 4 or version 7 UUIDs in your application instead, store them in the same BINARY(16) column with UUID_TO_BIN(value) and no swap flag.
SQL Server
SQL Server uses the uniqueidentifier type. NEWID() returns a random value. NEWSEQUENTIALID() returns increasing values on one machine, which helps clustered indexes, but it can only be used as a column default.
SELECT NEWID();
CREATE TABLE orders (
id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY
);Command line
On macOS and most Linux distributions, uuidgen prints a new UUID. macOS prints uppercase letters, so pipe through tr if you want the canonical lowercase form. On Windows, PowerShell has New-Guid.
uuidgen
uuidgen | tr 'A-Z' 'a-z' # lowercase output
cat /proc/sys/kernel/random/uuid # Linux, no extra tools neededNew-Guid
[guid]::NewGuid().ToString()Deterministic UUIDs with version 5
Sometimes you want the same input to always produce the same UUID, for example to give every email address or URL a stable identifier, or to make imports idempotent so running them twice does not create duplicates. That is what name-based version 5 UUIDs are for: they hash a namespace UUID and a name with SHA-1 and format the result as a UUID.
import uuid
uuid.uuid5(uuid.NAMESPACE_URL, 'https://utilistudio.com/tools')
# always returns the same UUID for this namespace and nameimport { v5 as uuidv5 } from 'uuid';
const NAMESPACE = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; // standard URL namespace
uuidv5('https://utilistudio.com/tools', NAMESPACE);Use a namespace that is specific to your application so your IDs cannot clash with another system that hashes the same names. Remember that anyone who knows the namespace and the name can recompute the UUID, so never derive version 5 IDs from secret values.
Text formats for storing and sending UUIDs
The canonical text form is 36 characters: lowercase hexadecimal with hyphens in the 8-4-4-4-12 pattern. Use it in APIs, logs, and URLs unless you have a strong reason not to, because every library can parse it.
- Compact hex: the same 32 digits without hyphens, such as Python’s
.hex. Common in file names and caches. - URN:
urn:uuid:followed by the canonical form, used in some XML and standards-based formats. - Binary: 16 raw bytes, the right choice inside databases and binary protocols.
- Shortened encodings: Base64 or Base58 representations are shorter in URLs but are not standard, so document them clearly if you use them.
Validating a UUID string
When you accept UUIDs from users or other systems, validate them before use. Parsing with your language’s UUID type is the most reliable check. If you need a regular expression, this one accepts standard UUIDs of versions 1 to 8 in either letter case:
const UUID_PATTERN =
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
UUID_PATTERN.test('550e8400-e29b-41d4-a716-446655440000'); // trueThis pattern intentionally rejects the special nil UUID (all zeros) and max UUID (all f digits). Allow those separately if your system uses them.
Common mistakes to avoid
- Hand-rolled generators. Snippets that format random numbers into a UUID shape usually rely on non-cryptographic randomness and often set the version and variant bits incorrectly.
- Comparing as case-sensitive strings.
550E8400-...and550e8400-...are the same UUID. Normalize to lowercase, or compare parsed values. - Storing as text. A 36-character string uses more than twice the space of 16 bytes and makes indexes larger and slower.
- Treating UUIDs as secrets. A UUID identifies a record; it does not authorize access to it. Check permissions on every request.
- Mixing versions by accident. If one service generates version 7 and another version 4 for the same table, you lose the ordering benefits of version 7.
Quick reference
| Platform | Version 4 | Version 7 |
|---|---|---|
| Browser JavaScript | crypto.randomUUID() | uuid package: v7() |
| Node.js | randomUUID() from node:crypto | uuid package: v7() |
| Python | uuid.uuid4() | uuid.uuid7() (3.14+) |
| Java | UUID.randomUUID() | java-uuid-generator library |
| C# / .NET | Guid.NewGuid() | Guid.CreateVersion7() (.NET 9+) |
| Go | uuid.New() | uuid.NewV7() |
| PostgreSQL | gen_random_uuid() | uuidv7() (18+) |
| SQL Server | NEWID() | Generate in the application |
Keep learning
- UUID v4 vs v7: which one should you use?
- Developer Utilities: Essential developer helpers including hash generators, base64 encoders, and regex testers.