Deterministic Guids
Guid Generation
Unique Identifiers
Programming Tips
Software Development

How to Create Deterministic Guids

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Deterministic GUIDs are useful when the same input must always produce the same identifier. The key idea is that the GUID is derived from stable input data rather than generated randomly, which makes it repeatable across runs, machines, and environments.

Why Determinism Changes the Tradeoff

Ordinary random GUIDs are great when you want uniqueness without coordination. Deterministic GUIDs solve a different problem:

  • same input should yield same id
  • different inputs should usually yield different ids
  • generation should not depend on a database round trip

That is helpful for imports, synchronization jobs, cache keys, and test fixtures where id stability matters.

Prefer Standard Name-Based UUIDs

The cleanest approach is usually a name-based UUID, which combines:

  • a namespace UUID
  • an input name string

The standard algorithms are:

  • version 3, which uses MD5
  • version 5, which uses SHA-1

Version 5 is a common modern choice because it is standardized and deterministic.

Python Example With UUID Version 5

Python's standard library already supports this:

python
1import uuid
2
3namespace = uuid.UUID("12345678-1234-5678-1234-567812345678")
4
5order_id = uuid.uuid5(namespace, "customer:42:order:7")
6same_order_id = uuid.uuid5(namespace, "customer:42:order:7")
7
8print(order_id)
9print(order_id == same_order_id)  # True

If you change the namespace or the input string, the generated UUID changes as well. That namespace dimension is important because it prevents unrelated domains from accidentally using the same name and expecting independent ids.

C# Example

The .NET runtime does not have a built-in Guid.CreateVersion5 everywhere, but you can still create deterministic GUIDs by hashing stable input and then formatting the result consistently.

csharp
1using System;
2using System.Security.Cryptography;
3using System.Text;
4
5static Guid CreateDeterministicGuid(string value)
6{
7    byte[] input = Encoding.UTF8.GetBytes(value);
8    byte[] hash = SHA256.HashData(input);
9    byte[] guidBytes = new byte[16];
10    Array.Copy(hash, guidBytes, 16);
11    return new Guid(guidBytes);
12}
13
14Guid id = CreateDeterministicGuid("customer:42:order:7");
15Console.WriteLine(id);

If you use a custom scheme like this, keep it stable forever. Once ids are persisted, changing the algorithm or the byte ordering will change the generated values.

Namespaces and Input Design Matter

Determinism is only as good as the input contract. If the input string is assembled inconsistently, you will generate inconsistent ids.

Good practices include:

  • choose a fixed namespace per entity family
  • normalize case when appropriate
  • choose one delimiter convention
  • document which fields are included and in what order

For example, customer:42:order:7 and order:7:customer:42 are different inputs and must not be treated as interchangeable unless your rules say so explicitly.

That documentation step is more important than it looks. Many deterministic-id bugs come from teams agreeing on the idea but not on the exact canonical input string.

Common Pitfalls

One common mistake is calling a random GUID generator and then trying to "make it deterministic" afterward. Determinism must come from the input-to-id algorithm itself.

Another issue is using unstable input such as timestamps, database surrogate keys, or display names that may change later. If the input changes, the deterministic GUID changes too.

It is also easy to forget namespaces. Without them, two unrelated domains may hash the same string and accidentally produce the same deterministic id under the same scheme.

Summary

  • Deterministic GUIDs are generated from stable input rather than randomness.
  • Name-based UUIDs such as version 5 are a strong standard option for deterministic ids.
  • Python supports UUID v5 directly through the standard library.
  • If you use a custom hashing scheme, freeze the algorithm and byte rules early.
  • The quality of a deterministic GUID scheme depends heavily on careful namespace and input design.

Course illustration
Course illustration

All Rights Reserved.