Binary UUIDs: Saving Space and Improving Performance

    June 3, 2024
    10 min read
    Technical deep-dive
    Tutorial
    uuid
    database
    performance
    architecture

    UUIDs are 128-bit identifiers β€” but most developers store them as 36-character strings, which is far from optimal in terms of size and performance.

    In reality, a UUID is just 16 bytes. So why store it as a long, slow string?

    Let’s explore how to store UUIDs in binary format to reduce disk usage, improve indexing, and speed up your database β€” with examples in MySQL, PostgreSQL, and MongoDB.


    🧬 Why Binary UUIDs?

    FormatSize (bytes)Storage Type
    UUID text36CHAR(36)
    UUID hex32CHAR(32)
    Binary UUID16BINARY(16)
    Native UUID16uuid (Postgres)

    Benefits:

    • 50% smaller than string UUIDs
    • Faster joins and lookups
    • More cache-efficient indexes
    • Fewer pages read = faster queries

    πŸ› οΈ MySQL: Using BINARY(16)

    πŸ”§ Schema

    sql
    CREATE TABLE users (
      id BINARY(16) PRIMARY KEY,
      name VARCHAR(255)
    );

    πŸ” Converting UUID to Binary

    sql
    INSERT INTO users (id, name)
    VALUES (UUID_TO_BIN(UUID()), 'Alice');

    The UUID_TO_BIN() function converts a UUID string to 16-byte binary.

    πŸ” Converting Binary to UUID

    sql
    SELECT BIN_TO_UUID(id) AS uuid, name FROM users;

    πŸ” Recommended Index Format

    Use UUID_TO_BIN(UUID(), 1) to reorder UUID bytes for index optimization (for InnoDB clustered indexes).


    🐘 PostgreSQL: Use the Native `uuid` Type

    Postgres has a built-in uuid column type that stores values as compact binary.

    πŸ”§ Schema

    sql
    CREATE TABLE users (
      id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
      name TEXT
    );

    πŸ“¦ Performance Tip

    • No need to use BINARY(16) β€” uuid is efficient and binary under the hood
    • Supported by GIN/GiST indexes if needed
    • Compatible with pgcrypto and gen_random_uuid()

    πŸƒ MongoDB: Use `BinData` Type

    MongoDB stores UUIDs as BinData(4, ...) β€” a 16-byte binary field.

    πŸ”§ Insert Example

    In MongoDB shell or driver:

    js
    {
      _id: UUID("550e8400-e29b-41d4-a716-446655440000"),
      name: "Alice"
    }

    Under the hood, this becomes:

    js
    "_id": BinData(4, "1Q6EAOKbQdSnFkRmVUQAAA==")

    Use the UUID helper:

    js
    UUID("...") // safe from string parsing errors

    πŸ”Ž Query

    js
    db.users.find({ _id: UUID("550e8400-e29b-41d4-a716-446655440000") })

    πŸ“ˆ Benchmarks (Estimated)

    FormatQuery SpeedDisk SpaceIndex SizeNotes
    CHAR(36)❌ Slow❌ Large❌ LargeInefficient all around
    BINARY(16)βœ… Fastβœ… Smallβœ… CompactRecommended in MySQL
    uuid (PG)βœ… Nativeβœ… Compactβœ… IndexableBuilt-in Postgres type
    BinDataβœ… Optimizedβœ… Compactβœ… FastNative in MongoDB

    πŸ§ͺ Working With Binary UUIDs in Code

    Python

    python
    import uuid
    
    # Get binary representation
    binary_uuid = uuid.uuid4().bytes
    
    # Convert back
    restored = uuid.UUID(bytes=binary_uuid)

    JavaScript (Node.js)

    js
    const { v4: uuidv4, parse, stringify } = require('uuid');
    
    const u = uuidv4();
    const binary = Buffer.from(parse(u)); // 16-byte binary
    const restored = stringify(binary);

    πŸ” Tips & Best Practices

    • Use binary UUIDs in storage, but convert to string at API boundaries
    • Add human-readable indexes only if needed for debugging
    • For MySQL, use UUID_TO_BIN(uuid, 1) for better index locality
    • Don’t truncate UUIDs β€” use base64 if you want short string IDs

    Final Thoughts

    Binary UUIDs are easy to implement and deliver real-world gains in performance and efficiency.

    Whether you're scaling up in MySQL, tuning PostgreSQL, or designing a MongoDB schema β€” storing UUIDs as compact 16-byte values will save space, boost speed, and simplify indexing.

    πŸ“¦ UUIDs don’t need to be bulky to be powerful.

    Generate Your Own UUIDs

    Ready to put this knowledge into practice? Try our UUID generators:

    Generate a Single UUID

    Create a UUID with our fast, secure generator

    Bulk UUID Generator

    Need multiple UUIDs? Generate them in bulk

    Summary

    This article explores how storing UUIDs in binary format can improve performance and storage efficiency. It includes concrete implementation examples for MySQL, PostgreSQL, and MongoDB, with tips for conversion and indexing.

    TLDR;

    Storing UUIDs in binary format (instead of text) reduces storage, improves indexing, and speeds up queries.

    Key points:

    • UUIDs are 128-bit (16-byte) values β€” but are often stored as 36-character strings
    • Binary UUIDs save 40–50% of space and offer faster index performance
    • MySQL (BINARY(16)), PostgreSQL (uuid type), and MongoDB (BinData) all support compact storage

    Convert carefully and maintain human-readability in logs or APIs if needed.

    Cookie Consent

    We use cookies to enhance your experience on our website. By accepting, you agree to the use of cookies in accordance with our Privacy Policy.