uuidgeneratorsdatabase

UUID Generator Guide: All Versions Explained

· Cosyslabs

A UUID (Universally Unique Identifier) is a 128-bit identifier that can be generated by any system without central coordination while maintaining practical uniqueness. UUIDs are standardized in RFC 9562 (2024) and represented as 32 hex digits in five groups: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx. The version digit M and variant bits N identify the generation algorithm.

UUID Versions Overview

VersionSource of UniquenessSortableRecommended
v1Timestamp + MAC addressPartiallyNo (deprecated)
v2DCE Security (POSIX UID)NoNo (obsolete)
v3MD5 hash of namespace + nameYes (deterministic)No (use v5)
v4RandomNoYes (when unpredictability needed)
v5SHA-1 hash of namespace + nameYes (deterministic)Yes
v6Reordered v1 timestampYesNo (use v7)
v7Unix ms timestamp + randomYesYes (DB primary keys)
v8Custom (implementation-defined)Context-specific

UUID v4: Random

UUID v4 uses 122 bits of cryptographically random data (6 bits are fixed for version and variant):

f47ac10b-58cc-4372-a567-0e02b2c3d479
              ^    ^
              4    [89ab] — version and variant markers
// Modern browsers and Node.js 14.17+
const id = crypto.randomUUID();

// Python
import uuid
id = str(uuid.uuid4())

// Go
import "github.com/google/uuid"
id := uuid.New().String()

// Rust
use uuid::Uuid;
let id = Uuid::new_v4().to_string();

Use UUID v4 when:

  • Generating tokens, session IDs, API keys, or invite codes
  • Security requires IDs to be unpredictable
  • Creation time must not be inferable from the ID
  • IDs are exposed to users or in URLs

UUID v7 (RFC 9562, 2024) embeds a 48-bit Unix millisecond timestamp in the most significant bits, making IDs sortable by generation time:

01905b80-3e40-7abc-8def-123456789abc
^^^^^^^^ ^^^^
48-bit Unix ms timestamp
import { v7 as uuidv7 } from "uuid";
const id = uuidv7();

// Node.js 21+ native support (via --experimental-uuid-v7)
// PostgreSQL 17+ native uuidv7() function
import uuid
# Python stdlib does not yet include v7 — use uuid6 package
from uuid6 import uuid7
id = str(uuid7())
-- PostgreSQL 17+
SELECT uuidv7();

-- PostgreSQL 14-16
CREATE EXTENSION IF NOT EXISTS "pg_uuidv7";
SELECT uuid_generate_v7();

-- MySQL 8.0 (manual construction)
SELECT LOWER(
  CONCAT(
    LPAD(HEX(FLOOR(UNIX_TIMESTAMP(NOW(3)) * 1000)), 12, '0'),
    '-7',
    LPAD(HEX(FLOOR(RAND() * POW(2, 12))), 3, '0'),
    '-',
    LPAD(HEX(FLOOR(RAND() * POW(2, 14)) + 32768), 4, '0'),
    '-',
    LPAD(HEX(FLOOR(RAND() * POW(2, 48))), 12, '0')
  )
);

UUID v7 advantages for databases:

  • Sequential inserts avoid B-tree fragmentation
  • ORDER BY id gives chronological order
  • Index cache hit rate improves significantly
  • Partitioning by time works naturally

UUID v7 limitations:

  • Embeds creation timestamp — avoid for security-sensitive IDs
  • Requires monotonic clock; two UUIDs in the same millisecond need sub-ms counter

UUID v5: Name-Based (Deterministic)

UUID v5 generates the same UUID for the same namespace + name combination using SHA-1. This is useful for content-addressable systems:

import { v5 as uuidv5 } from "uuid";

// Standard namespaces (RFC 4122)
const DNS_NAMESPACE = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
const URL_NAMESPACE = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";

// Always produces the same UUID for the same input
const id = uuidv5("example.com", DNS_NAMESPACE);
// "cfbff0d1-9375-5685-968c-48ce8b15ae17" — always this value

const pageId = uuidv5("https://example.com/page", URL_NAMESPACE);
import uuid

ns = uuid.NAMESPACE_URL
id = uuid.uuid5(ns, "https://example.com/page")

UUID v5 use cases:

  • Converting existing string identifiers to UUIDs deterministically
  • Content-addressed storage (same content → same ID)
  • Generating stable IDs from user emails or domain names for migration
  • Creating test fixtures with reproducible IDs

Note: UUID v3 uses MD5 instead of SHA-1. Prefer v5 for new projects since SHA-1 is deprecated (though for UUID purposes, the security weakness of MD5/SHA-1 is less critical than their use for cryptographic signatures).

Database Storage Strategies

PostgreSQL

Use the native uuid type — it stores as 16 bytes (not 36-char string):

CREATE TABLE users (
  id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  -- For UUID v7 (PostgreSQL 17+):
  -- id uuid DEFAULT uuidv7() PRIMARY KEY,
  name text NOT NULL,
  created_at timestamptz DEFAULT now()
);

MySQL

Avoid VARCHAR(36) for UUIDs. Use BINARY(16):

CREATE TABLE users (
  id BINARY(16) NOT NULL DEFAULT (UUID_TO_BIN(UUID(), 1)),
  name VARCHAR(255) NOT NULL,
  PRIMARY KEY (id)
);

-- Query
SELECT BIN_TO_UUID(id) as id, name FROM users;

The second argument 1 to UUID_TO_BIN reorders the bytes to make v1 UUIDs sortable. For UUID v7, this reordering is not needed.

MongoDB

MongoDB's ObjectId is a 12-byte time-ordered identifier similar to UUID v7. When you need proper UUID v7 with MongoDB:

const { v7: uuidv7 } = require("uuid");
const { Binary } = require("mongodb");

function uuidToBinary(uuidStr) {
  const hex = uuidStr.replace(/-/g, "");
  const buf = Buffer.from(hex, "hex");
  return new Binary(buf, Binary.SUBTYPE_UUID);
}

await collection.insertOne({
  _id: uuidToBinary(uuidv7()),
  name: "Alice"
});

ULID: An Alternative to UUID v7

ULID (Universally Unique Lexicographically Sortable Identifier) is an alternative format:

01ARZ3NDEKTSV4RRFFQ69G5FAV
^          ^^
10-char    16-char random
timestamp
import { ulid } from "ulid";
const id = ulid(); // "01ARZ3NDEKTSV4RRFFQ69G5FAV"

// With specific timestamp
const id2 = ulid(Date.now());

ULID vs UUID v7:

FeatureULIDUUID v7
FormatBase32Hex with dashes
Length26 chars36 chars
Timestamp resolution1ms1ms
RFC standardNoRFC 9562
Database supportLibrary onlyNative in PG 17+
URL-safe by defaultYesYes (no special chars)

UUID v7 is now preferred due to RFC standardization and native database support.

NanoID: Compact Random IDs

When you need short, URL-safe random identifiers instead of UUIDs:

import { nanoid } from "nanoid";

const id = nanoid();     // "V1StGXR8_Z5jdHi6B-myT" (21 chars)
const shortId = nanoid(10); // "IRFa-VaY2b" (10 chars)

NanoID uses A-Za-z0-9_- (64 characters), making IDs URL-safe. At 21 characters it has the same collision probability as UUID v4.

Try It Now

Generate UUID v4, v5, and v7 with the UUID Generator Tool. Generate NanoIDs and ULIDs with their dedicated tools.