The one-line cheat sheet (every major language)
This is the reference table. The call column is the shortest idiomatic way to get a random UUID; the v7 column shows how to get the newer time-ordered variant where it exists.
| Language | One-line call (v4 random) | Built-in or package | Time-ordered v7 |
|---|---|---|---|
| Python | uuid.uuid4() | Built-in (uuid stdlib) | uuid.uuid7() — Python 3.14+ |
| JavaScript (browser) | crypto.randomUUID() | Built-in (Web Crypto) | uuidv7 npm package |
| Node.js | crypto.randomUUID() | Built-in since v14.17 | crypto.randomUUIDv7() (experimental) |
| Java | UUID.randomUUID() | Built-in (java.util) | Library (e.g. java-uuid-generator) |
| C# / .NET | Guid.NewGuid() | Built-in (System) | Guid.CreateVersion7() — .NET 9+ |
| Go | uuid.New() | Package github.com/google/uuid | uuid.NewV7() |
| Rust | Uuid::new_v4() | Crate uuid (feature v4) | Uuid::now_v7() (feature v7) |
| PHP | Uuid::uuid4() | Package ramsey/uuid | Uuid::uuid7() |
| Ruby | SecureRandom.uuid | Built-in (securerandom) | Gem (e.g. uuid7) |
| SQL (PostgreSQL) | gen_random_uuid() | Built-in (PG 13+) | uuidv7() — PG 18+ |
| SQL (SQL Server) | NEWID() | Built-in | NEWSEQUENTIALID() (sequential GUID) |
Which should you reach for? If you only need a unique ID, the built-in v4 call in your language is the correct answer — do not add a dependency. Reach for v7 specifically when the UUID becomes a database primary key, where its leading timestamp keeps rows insert-ordered and avoids index bloat.
Anatomy of the value they all return
Every call above emits the same structure. Two nibbles are not random — they encode the version and the variant, which is how any parser can read a raw string and tell you it is a "v4" UUID.
JavaScript and TypeScript
Browser: modern browsers expose native UUID generation through the Web Crypto API:
// Version 4 (random) UUID — no library needed
const uuid = crypto.randomUUID();
console.log(uuid); // e.g. "550e8400-e29b-41d4-a716-446655440000"
The one gotcha: crypto.randomUUID() is only defined in a secure context (HTTPS or localhost). On a plain http:// page it is undefined — if you support insecure origins, fall back to the uuid package.
Node.js: the same call works, built in since Node 14.17:
import { randomUUID } from 'node:crypto';
const id = randomUUID(); // v4
console.log(id);
// Time-ordered v7 (experimental) in recent Node:
import { randomUUIDv7 } from 'node:crypto'; // guard: may be undefined on older runtimes
For versioned or namespaced UUIDs (v3/v5) or a stable v7 across runtimes, use the uuid package:
import { v4 as uuidv4, v5 as uuidv5, v7 as uuidv7 } from 'uuid';
const random = uuidv4();
const stable = uuidv5('example.com', uuidv5.DNS); // deterministic
const sortable = uuidv7(); // time-ordered
TypeScript uses the identical APIs; crypto.randomUUID() is typed as returning a branded template-literal string (${string}-${string}-...), so you get compile-time shape checking for free.
Python
Python's standard-library uuid module covers every classic version with zero dependencies:
import uuid
random_uuid = uuid.uuid4() # v4 (random) — the default
time_uuid = uuid.uuid1() # v1 (time + node)
name_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com') # v5 (deterministic)
parsed = uuid.UUID('550e8400-e29b-41d4-a716-446655440000') # string -> UUID
# Python 3.14+ adds the draft versions to the stdlib:
sortable = uuid.uuid7() # time-ordered, ideal for DB keys
Before Python 3.14, get v6/v7/v8 from the uuid-utils package (a Rust-backed drop-in). For everything else, uuid.uuid4() is all you need.
Java
Java has built-in UUID support in java.util.UUID:
import java.util.UUID;
UUID randomUuid = UUID.randomUUID(); // v4 (random)
UUID parsed = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
int version = randomUuid.version(); // 4
int variant = randomUuid.variant(); // 2 (RFC 9562/4122 layout)
Note UUID.nameUUIDFromBytes(...) produces a v3 (MD5) name-based UUID, not v5. The JDK has no built-in v7; use a library such as com.fasterxml.uuid:java-uuid-generator for time-ordered IDs.
C# and .NET
C#/.NET uses the Guid struct (GUID is Microsoft's name for a UUID):
using System;
Guid newGuid = Guid.NewGuid(); // v4 (random)
Guid parsed = Guid.Parse("550e8400-e29b-41d4-a716-446655440000");
Guid empty = Guid.Empty; // all-zero UUID
string noHyphens = newGuid.ToString("N"); // 32 chars, no dashes
// .NET 9+ adds native time-ordered v7:
Guid v7 = Guid.CreateVersion7();
Go
Go's de-facto standard is the github.com/google/uuid package:
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
id := uuid.New() // v4 (random), panics on RNG failure
id4, _ := uuid.NewRandom() // v4, returns an error instead of panicking
id7, _ := uuid.NewV7() // v7 (time-ordered)
parsed, _ := uuid.Parse("550e8400-e29b-41d4-a716-446655440000")
fmt.Println(id, id4, id7, parsed)
}
Install with go get github.com/google/uuid.
Rust
Rust's uuid crate is gated behind feature flags — enable the versions you use:
# Cargo.toml
uuid = { version = "1", features = ["v4", "v7"] }
use uuid::Uuid;
let id = Uuid::new_v4(); // v4 (random)
let id7 = Uuid::now_v7(); // v7 (time-ordered)
let parsed = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
println!("{id} {id7} {parsed}");
PHP
PHP has no built-in UUID generator; ramsey/uuid is the standard choice (composer require ramsey/uuid):
<?php
require 'vendor/autoload.php';
use Ramsey\Uuid\Uuid;
$v4 = Uuid::uuid4(); // random
$v5 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'example.com'); // deterministic
$v7 = Uuid::uuid7(); // time-ordered
echo $v4->toString(); // e.g. 550e8400-e29b-41d4-a716-446655440000
Ruby
Ruby's standard library covers v4 through SecureRandom:
require 'securerandom'
uuid = SecureRandom.uuid # v4 (random), no gem required
puts uuid
SecureRandom.uuid only returns v4. For v7 or name-based UUIDs, add a gem such as uuid7.
SQL (generate them in the database)
You often want the database itself to mint the key:
-- PostgreSQL 13+ (built in, random v4)
SELECT gen_random_uuid();
-- PostgreSQL 18+ (native time-ordered v7)
SELECT uuidv7();
-- SQL Server (random GUID)
SELECT NEWID();
-- ... or sequential, better for clustered index inserts:
-- DEFAULT NEWSEQUENTIALID()
-- MySQL 8 (note: UUID() returns a v1 UUID)
SELECT UUID();
Store UUID keys in a native uuid column (Postgres) or 16-byte BINARY(16) (MySQL/SQL Server) rather than a 36-char string — it halves the storage and speeds up index comparisons.
UUID versions: which one, and when
| Version | How it is built | Sortable? | Use it for |
|---|---|---|---|
| v1 | Timestamp + MAC/node | By time | Legacy systems; avoid in new code (leaks MAC) |
| v4 | 122 random bits | No | The safe default for general unique IDs |
| v5 | SHA-1 of namespace + name | No | Deterministic IDs (same input → same UUID) |
| v7 | Unix-ms timestamp + random | By time | Database primary keys — the modern best choice |
The headline shift since RFC 9562 (2024) is v7. A random v4 primary key scatters inserts all over a B-tree index, causing page splits and fragmentation; v7's leading millisecond timestamp keeps new rows appending to the "end" of the index, the way an auto-increment key would — while still being globally unique and non-coordinated. If you are choosing a key type for a new table today, v7 is usually the answer; v4 remains right for opaque tokens and IDs you do not want to reveal a creation time.
Best practices
- Default to the built-in v4 call. Do not add a dependency to generate a random ID when your standard library already does it (Python, Java, C#, Ruby, Node, browsers, Postgres).
- Use v7 for database primary keys so inserts stay index-friendly; use v4 for tokens where a leaked timestamp would matter.
- Use v5 for deterministic IDs — when the same input must always map to the same UUID.
- Avoid v1 in new code because it can embed the machine's MAC address (a privacy and enumeration risk).
- Store as 16 bytes, not 36 characters — native
uuid/BINARY(16)columns are smaller and index faster than text. - Validate on input before trusting a UUID from an untrusted source:
const UUID_RE =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const isValidUUID = (s) => UUID_RE.test(s);
UUID vs other identifier schemes
- vs database sequences — UUIDs need no central coordinator, so any node can mint one offline; sequences are shorter and human-readable but require a single source of truth. Use UUIDs for distributed systems, sequences for a single database.
- vs ULIDs — ULIDs are also time-sortable and use Crockford base32 (26 chars, URL-friendly). UUIDv7 now covers the same "sortable ID" need while staying in the standard UUID format, so it is the more portable choice.
- vs Snowflake IDs — 64-bit, coordinated IDs tuned for extreme insert rates at Twitter/Discord scale. UUIDs are 128-bit and need no ID-allocation service, which makes them simpler for almost every other system.
Conclusion
UUID generation is a solved, one-line problem in every major language — usually built into the standard library, and always producing the same RFC 9562 format so the value travels freely between systems. Reach for the built-in v4 call by default, switch to v7 when the UUID is a database key, and use v5 when you need determinism. The APIs differ; the 128-bit identifier they hand you does not.