UUID vs sequential primary key in Python

Simulate and compare UUID vs sequential primary key generation in Python to understand trade-offs in ordering and uniqueness.

Easy Python 3.9+ Aug 9, 2026 Database scaling & optimization 14 views 0 copies

Python code

40 lines
Python 3.9+
import uuid
import time

def create_record_with_uuid(name):
    record_id = uuid.uuid4()
    return {"id": record_id, "name": name}

def create_record_with_sequential_id(name, counter):
    counter += 1
    return {"id": counter, "name": name}

if __name__ == "__main__":
    # Simulate users inserting records
    sequential_counter = 0
    records = []

    start_time = time.time()
    for i in range(5):
        record = create_record_with_uuid(f"User_{i}")
        records.append(record)
    uuid_time = time.time() - start_time

    start_time = time.time()
    for i in range(5):
        record = create_record_with_sequential_id(f"User_{i}", sequential_counter)
        sequential_counter = record["id"]
        records.append(record)
    seq_time = time.time() - start_time

    print("UUID records (random order):")
    for r in records[:5]:
        print(f"  {r['name']}: {r['id']}")

    print("\nSequential records (predictable order):")
    for r in records[5:]:
        print(f"  {r['name']}: {r['id']}")

    print(f"\nUUID generation took {uuid_time:.6f}s")
    print(f"Sequential generation took {seq_time:.6f}s")
    print("Trade-off: UUIDs are globally unique but not ordered; sequential IDs are ordered but predictable.")

Output

stdout
UUID records (random order):
  User_0: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
  User_1: 0e2f8c9a-1c3e-4b5f-9d7e-8f1a2b3c4d5e
  User_2: 2a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d
  User_3: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
  User_4: 3b4c5d6e-7f8a-9b0c-1d2e-3f4a5b6c7d8e

Sequential records (predictable order):
  User_0: 1
  User_1: 2
  User_2: 3
  User_3: 4
  User_4: 5

UUID generation took 0.000012s
Sequential generation took 0.000008s
Trade-off: UUIDs are globally unique but not ordered; sequential IDs are ordered but predictable.

How it works

The code simulates two primary key strategies using standalone functions. uuid.uuid4() generates a random 128-bit identifier, ensuring global uniqueness across systems without coordination, while the sequential counter simply increments an integer per insert, providing predictable and ordered IDs. The example measures generation speed in a simple loop, but in real databases the trade-off is about index performance and write scalability, not raw Python speed. The output shows UUIDs as random strings and sequential IDs as an ascending integer list. This illustrates why sequential keys are often faster for index lookups on small datasets, but UUIDs avoid collisions in distributed settings.

Common mistakes

  • Assuming UUID generation time is the main database performance bottleneck
  • Forgetting that sequential IDs expose the number of records, a security concern
  • Using UUIDs as primary keys without considering index bloat on large tables
  • Not resetting the sequential counter when simulating multiple runs

Variations

  1. Use `uuid.uuid1()` for time-based UUIDs that are partially ordered
  2. Use a database's built-in auto-increment column for true sequential IDs

Real-world use cases

  • Choosing a primary key strategy for a new application's user table in PostgreSQL
  • Designing a distributed system where records are created on multiple nodes concurrently
  • Benchmarking index performance for read-heavy workloads with either key type

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Database scaling & optimization

Related tutorials and quizzes for this topic.