UUID and GUID — are they the same thing?
Yes, almost. A UUID (Universally Unique Identifier) is defined by RFC 4122 as a 128-bit identifier typically represented as 32 hexadecimal digits in five groups separated by hyphens: 550e8400-e29b-41d4-a716-446655440000. A GUID (Globally Unique Identifier) is Microsoft's implementation of the same concept. The term GUID is common in Windows, .NET, and COM/ActiveX contexts; UUID is used everywhere else. For practical purposes, they are interchangeable.
UUID versions
RFC 4122 originally defined versions 1 through 5. RFC 9562 (2024) added versions 6, 7, and 8.
UUID v1 — timestamp + MAC address
Generated from the current timestamp and the MAC address of the network interface. Guarantees uniqueness across machines and time, but the embedded MAC address is a privacy concern — it reveals the generating machine's hardware identity. Rarely used in new applications.
UUID v3 — name-based (MD5)
Deterministically generated from a namespace UUID and a name string using MD5 hashing. The same namespace + name always produces the same UUID. Useful for generating stable identifiers for known resources (e.g., always the same UUID for a given URL). MD5 is considered weak; prefer v5 for new implementations.
UUID v4 — random
Generated from 122 random bits (the remaining 6 bits are fixed version/variant markers). This is the most widely used version. Collision probability is astronomically low — you would need to generate approximately 2.7 quintillion UUIDs before a 50% collision probability. Use v4 when you need a unique identifier quickly and do not need sortability.
UUID v5 — name-based (SHA-1)
Same concept as v3 but uses SHA-1 instead of MD5. Preferred over v3 for new name-based UUID generation.
UUID v6 — reordered timestamp (sortable v1)
Reorders the timestamp bits of v1 so that UUIDs sort lexicographically in creation order. Solves the database index fragmentation problem of v4 while keeping the v1 uniqueness guarantees. Not yet widely supported by language libraries.
UUID v7 — Unix timestamp + random (sortable)
Uses the current Unix millisecond timestamp in the most significant bits, followed by random bits. UUIDs sort chronologically, making them ideal as database primary keys in modern systems. This is quickly becoming the preferred UUID version for new projects where database performance matters.
Which version should you use?
- Default choice: UUID v4 — random, universally supported, zero setup. Use this unless you have a specific reason not to.
- Database primary keys at scale: UUID v7 — monotonically increasing, reduces B-tree index fragmentation, better INSERT performance on large tables. Use with PostgreSQL, MySQL 8+, or SQL Server.
- Stable identifiers for known names: UUID v5 — deterministic. Use when the same input must always produce the same UUID (e.g., canonical URLs, content addressable storage).
- Avoid v1 — privacy concern (embedded MAC address). Avoid v3 — MD5 is deprecated.
UUID in databases — the performance question
UUID v4 as a primary key in a relational database has a well-known trade-off: because the values are random, each new INSERT goes into a random position in the B-tree index rather than the end. This causes page splits and index fragmentation, especially at high write volumes.
Solutions:
- UUID v7 — sort-friendly by design, solves fragmentation.
- ULID (Universally Unique Lexicographically Sortable Identifier) — an alternative to UUID that is always sorted by creation time.
- Store as binary(16) — storing UUID as 16-byte binary rather than a 36-character string halves the storage footprint and improves index performance.
- Sequential UUID libraries —
Guid.NewGuid()in .NET 9+ supports sequential GUIDs viaGuid.CreateVersion7().
UUID vs auto-increment integer
Auto-increment integers (1, 2, 3…) are compact, fast, and simple, but they have drawbacks in distributed systems: they require a central sequence generator, they reveal record counts and insertion order to clients, and they make merging data from multiple databases error-prone. UUIDs solve all three problems at the cost of larger storage and potential index fragmentation. Choose based on your scale and architecture requirements.