Skip to content
    universaldevtools.in
    Back to Blog
    Generators
    6 min readJan 11, 2025

    UUID Generation: Choosing the Right Version

    "Just use UUID" sounds simple until you discover there are 8 versions with very different characteristics. Picking the wrong one can tank your database performance or leak information. Here's how to choose the right UUID version for your use case.

    The Three UUIDs You Need to Know

    While UUID has 8 versions, only three matter for most developers: v1 (legacy), v4 (current standard), and v7 (the future). Here's how they compare:

    VersionBased OnSortable?Privacy
    v1Timestamp + MAC addressPartially❌ Leaks device info
    v4Random numbersNo✅ Fully random
    v7Timestamp + random✅ Yes✅ No device info

    The Modern Recommendation

    For new projects in 2025, use UUID v7 for database primary keys. It combines v4's randomness with v1's time-ordering, giving you the best of both worlds without privacy concerns.

    Understanding Each Version

    UUID v1: The Legacy Option

    Generated from timestamp + your computer's MAC address. While this guarantees uniqueness, it also exposes when and where the UUID was created—a privacy concern for public-facing IDs.

    550e8400-e29b-11d4-a716-446655440000

    ↑ The "1" indicates version 1

    UUID v4: The Current Standard

    Completely random with 122 bits of randomness. No information about when or where it was created. This is what most libraries generate by default and is suitable for most use cases.

    f47ac10b-58cc-4372-a567-0e02b2c3d479

    ↑ The "4" indicates version 4 (random)

    UUID v7: The Future

    Combines Unix timestamp in the first 48 bits with 74 bits of randomness. This makes them sortable by creation time while maintaining uniqueness and privacy. Ideal for database primary keys.

    018e9d1c-e4a1-7b5c-9abc-def012345678

    ↑ The "7" indicates version 7 (time-ordered)

    Practical Code Examples

    Generating UUIDs in JavaScript

    // UUID v4 - Native browser/Node.js support
    const uuidv4 = crypto.randomUUID();
    console.log(uuidv4); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
    
    // UUID v7 - Using the 'uuid' package
    import { v7 as uuidv7 } from 'uuid';
    const uuidV7 = uuidv7();
    console.log(uuidV7); // "018e9d1c-e4a1-7b5c-9abc-def012345678"
    
    // Custom UUID v7 implementation (if no library)
    function generateUUIDv7() {
      const timestamp = Date.now();
      const timestampHex = timestamp.toString(16).padStart(12, '0');
      
      const randomBytes = new Uint8Array(10);
      crypto.getRandomValues(randomBytes);
      
      // Set version (7) and variant bits
      randomBytes[0] = (randomBytes[0] & 0x0f) | 0x70;
      randomBytes[2] = (randomBytes[2] & 0x3f) | 0x80;
      
      const randomHex = Array.from(randomBytes)
        .map(b => b.toString(16).padStart(2, '0'))
        .join('');
      
      return `${timestampHex.slice(0, 8)}-${timestampHex.slice(8)}-${randomHex.slice(0, 4)}-${randomHex.slice(4, 8)}-${randomHex.slice(8)}`;
    }

    UUID in Database Schemas (PostgreSQL)

    -- PostgreSQL has native UUID support
    CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
    
    -- Table with UUID v4 primary key (random)
    CREATE TABLE users_v4 (
      id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
      email VARCHAR(255) NOT NULL,
      created_at TIMESTAMP DEFAULT NOW()
    );
    
    -- For UUID v7, use gen_random_uuid() or application-generated
    -- Note: Native v7 support coming in future PostgreSQL versions
    
    -- Validate UUID format
    SELECT id FROM users_v4 
    WHERE id::text ~ '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$';

    Common UUID Mistakes

    Using UUID v1 in Public URLs

    UUID v1 contains your MAC address and timestamp. Attackers can determine when records were created and potentially identify your servers. Use v4 or v7 for public-facing identifiers.

    Using UUID v4 for High-Write Tables

    Random UUIDs cause B-tree index fragmentation because new records insert randomly across the index. For tables with millions of inserts, use UUID v7 or consider ULID for better write performance.

    Storing UUIDs as Strings

    A UUID stored as VARCHAR(36) uses 36 bytes. Native UUID types use 16 bytes—less than half the storage. Always use your database's native UUID type when available.

    Trusting Client-Generated UUIDs

    Never trust UUIDs from untrusted clients for security-critical operations. Attackers can guess or brute-force sequential patterns. Generate UUIDs server-side for sensitive records.

    Frequently Asked Questions

    Can UUID v4 ever generate duplicates?

    Theoretically yes, but practically no. With 122 random bits, you'd need to generate 2.71×10^18 UUIDs before having a 50% chance of a collision. That's about 1 billion UUIDs per second for 85 years. For all practical purposes, UUID v4 is unique.

    Why is UUID v7 better for databases than v4?

    UUID v7 is time-ordered (timestamp in the first bits), so new records naturally sort after old ones. This maintains B-tree index efficiency because new inserts go at the end. UUID v4 is random, causing inserts across the entire index—leading to page splits and slower writes.

    Should I use UUID or auto-increment integers for primary keys?

    UUIDs are better for distributed systems, preventing collisions without coordination. Auto-increment is faster for single-database apps and uses less storage (8 bytes vs 16). For most modern applications, especially those that might scale or need offline support, UUID v7 is the best choice.

    Wrapping Up

    UUID version choice matters more than most developers realize. For new projects, UUID v7 is the best default—it's sortable, private, and database-friendly. Use v4 when you need pure randomness, and avoid v1 unless you're maintaining legacy systems.

    Next steps: Generate different UUID versions with our tool to see how they look, then update your database schema to use the appropriate version for your use case.

    Related Resources