UUIDv7 vs UUIDv4: A Complete Comparison

    Understanding the key differences between random UUIDs and time-sortable UUIDs

    Universally Unique Identifiers (UUIDs) are 128-bit values used to identify records across distributed systems without coordination. For over a decade, UUIDv4 -- fully random identifiers -- has been the default choice. But in 2024, UUIDv7 emerged as a modern alternative defined in RFC 9562, embedding a Unix timestamp for chronological ordering. Which should you use? Let's compare them across every dimension that matters.

    At a Glance

    UUIDv4 (Random)

    550e8400-e29b-41d4-a716-446655440000

    122 random bits. No time component. Uniform random distribution. The standard choice since 2005 (RFC 4122).

    UUIDv7 (Time-Sortable)

    01936b2e-1e85-7000-8000-4a6f7e3b2c1d

    48-bit timestamp + 62 random bits. Chronologically sortable. Defined in RFC 9562 (2024).

    Did you know?Unix time starts at Jan 1, 1970 00:00:00 UTCLearn more

    Detailed Comparison

    FeatureUUIDv4UUIDv7
    SortabilityRandom orderTime-ordered (chronological)
    Embedded TimestampNone48-bit Unix ms timestamp
    Random Bits122 bits62 bits
    DB Index PerformancePoor (random inserts)Excellent (sequential inserts)
    Collision ProbabilityExtremely lowExtremely low
    Generation SpeedFast (random only)Fast (clock + random)
    Creation Time ExposureHidden (no timestamp)Visible (ms precision)
    StandardRFC 4122 (2005)RFC 9562 (2024)
    Ecosystem SupportUniversalGrowing rapidly

    Database Performance: Why It Matters

    The most impactful difference between UUIDv4 and UUIDv7 is their behavior as database primary keys. Most databases use B-tree indexes for primary keys, and the insertion pattern of UUIDs directly affects index efficiency.

    UUIDv4: Random Inserts

    • xNew rows land at random positions in the B-tree
    • xCauses frequent page splits and index fragmentation
    • xPoor cache locality -- recently written pages are evicted
    • xWrite performance degrades as table grows

    UUIDv7: Sequential Inserts

    • +New rows append near the end of the B-tree
    • +Minimal page splits, compact index structure
    • +Excellent cache locality -- hot pages stay in memory
    • +Consistent write performance at scale

    Benchmark note: In PostgreSQL benchmarks with 10 million rows, UUIDv7 primary keys typically show 2-3x faster insert throughput compared to UUIDv4, with significantly smaller index sizes due to reduced fragmentation. The gap widens further as table size increases.

    Uniqueness and Collision Resistance

    UUIDv4 has 122 random bits, which means you would need to generate approximately 2.71 quintillion UUIDs to have a 50% chance of a collision (the birthday paradox). In practical terms, generating 1 billion UUIDs per second would take about 85 years before a collision becomes likely.

    UUIDv7 has fewer random bits (62), but its uniqueness model is different. Because UUIDs generated at different milliseconds have different timestamp prefixes, collisions can only occur between UUIDs generated in the same millisecond. With 62 random bits per millisecond window, you would need to generate about 2.15 billion UUIDs in a single millisecond for a 50% collision probability -- far beyond any realistic workload.

    Both versions provide more than sufficient uniqueness for any practical application. The theoretical difference in random bits is not a meaningful concern in the real world.

    Did you know?Millisecond timestamps have 13 digitsLearn more

    When to Use Each Version

    Choose UUIDv7 When...

    • Database primary keys -- sequential inserts for B-tree performance
    • Event sourcing -- natural chronological ordering of events
    • Distributed systems -- time-ordered IDs without coordination
    • Audit trails -- creation time embedded in every record
    • Time-series data -- sortable IDs that double as rough timestamps
    • New projects -- modern default with growing ecosystem support

    Choose UUIDv4 When...

    • Privacy-sensitive IDs -- creation time must not be inferable
    • Security tokens -- maximum entropy with no predictable component
    • Existing systems -- already using UUIDv4 with no performance issues
    • Platform constraints -- runtime or library lacks UUIDv7 support
    • Non-indexed IDs -- IDs not used as database primary keys

    Code Examples: Generating Both Versions

    JavaScript / Node.js
    // UUIDv4 -- built-in since Node 14+
    const v4 = crypto.randomUUID();
    // "550e8400-e29b-41d4-a716-446655440000"
    
    // UUIDv7 -- Node.js 20+ or use a library
    // npm install uuidv7
    import { uuidv7 } from "uuidv7";
    const v7 = uuidv7();
    // "01936b2e-1e85-7000-8000-4a6f7e3b2c1d"
    
    // Extract timestamp from UUIDv7
    function getTimestamp(uuid) {
      const hex = uuid.replace(/-/g, "").slice(0, 12);
      return new Date(parseInt(hex, 16));
    }
    console.log(getTimestamp(v7));
    // 2024-12-01T10:30:45.000Z
    Python
    import uuid
    
    # UUIDv4 -- built-in
    v4 = uuid.uuid4()
    # UUID('550e8400-e29b-41d4-a716-446655440000')
    
    # UUIDv7 -- Python 3.x with uuid7 library
    # pip install uuid7
    from uuid_extensions import uuid7
    v7 = uuid7()
    # UUID('01936b2e-1e85-7000-8000-4a6f7e3b2c1d')
    
    # Extract timestamp from UUIDv7
    def get_timestamp(uuidv7: str) -> int:
        hex_str = str(uuidv7).replace('-', '')[:12]
        return int(hex_str, 16)
    
    from datetime import datetime
    ts_ms = get_timestamp(str(v7))
    print(datetime.utcfromtimestamp(ts_ms / 1000))
    PostgreSQL
    -- UUIDv4 (all PostgreSQL versions)
    SELECT gen_random_uuid();
    -- 550e8400-e29b-41d4-a716-446655440000
    
    -- UUIDv7 (PostgreSQL 17+)
    SELECT gen_random_uuid_v7();
    -- 01936b2e-1e85-7000-8000-4a6f7e3b2c1d
    
    -- Using UUIDv7 as a sortable primary key
    CREATE TABLE events (
      id UUID PRIMARY KEY DEFAULT gen_random_uuid_v7(),
      name TEXT NOT NULL,
      created_at TIMESTAMPTZ DEFAULT now()
    );
    -- IDs are naturally ordered by creation time
    Go
    import "github.com/google/uuid"
    
    // UUIDv4
    v4 := uuid.New()
    
    // UUIDv7
    v7, _ := uuid.NewV7()
    
    // Extract timestamp from UUIDv7
    ts, _ := uuid.TimestampFromV7(v7)
    sec, nsec := ts.Time().Unix(), ts.Time().Nanosecond()

    Internal Structure Comparison

    UUIDv4 Layout (128 bits)

    random_a-random-4rand-vrand-random_b

    122 random bits + 4-bit version (4) + 2-bit variant

    UUIDv7 Layout (128 bits)

    timestamp-time-7rand-vrand-random

    48-bit timestamp + 62 random bits + 4-bit version (7) + 2-bit variant

    Timestamp
    Version
    Variant
    Random
    Did you know?Unix time starts at Jan 1, 1970 00:00:00 UTCLearn more

    Frequently Asked Questions

    Try Our UUID Tools

    Extract timestamps from UUIDv7 identifiers or convert Unix timestamps to human-readable dates.

    Related Articles