Beginner’s Guide to Using uuid-ossp for UUID Generation in PostgreSQL

In modern applications, unique identifiers play a critical role. Whether you are building distributed systems, microservices, multi-region applications, or simply want safer primary keys, UUIDs (Universally Unique Identifiers) are one of the most reliable ways to generate identifiers that never collide.

PostgreSQL provides powerful built-in support for UUIDs, but many developers still rely on the popular uuid-ossp extension to generate UUID values from inside the database. This article explains the purpose of this extension, how to use all its functions, and what changed with the introduction of PostgreSQL 18.

What is the purpose of the uuid-ossp extension in PostgreSQL?

The uuid-ossp extension adds a set of functions to PostgreSQL that allow you to generate UUIDs directly within SQL. This is especially useful when:

  • You want PostgreSQL itself to generate unique IDs
  • You need specific UUID versions such as v1, v3, v5
  • Your application requires identifier uniqueness across servers, regions, or environments

Without this extension, PostgreSQL only supports UUID types but does not generate them automatically. uuid-ossp fills that gap.

Difference Between UUID v1, v3, and v5 in PostgreSQL

UUIDs are generated in multiple ways depending on the version. The most commonly compared ones are v1 (time-based), v3 (name-based + MD5), and v5 (name-based + SHA-1).

Below is the exact difference in purpose, input, and output behavior.

UUID v1: Time-based UUID

How it works:

  • Uses timestamp + MAC address + sequence number
  • Generated based on the system clock
  • Produces a nearly sortable UUID

Key points:

  • Not deterministic (output changes every time)
  • Slightly exposes machine MAC address
  • Good when you need ordering by creation time

Example use case:

  • Logging systems
  • Order-creation sequences
  • Large distributed databases where ordering helps

UUID v3: Name-based UUID (Deterministic using MD5)

How it works:

  • Takes two inputs:
  1. A namespace UUID
  2. A name (string)
    • Applies MD5 hash, then converts to UUID format

Key points:

  • 100% deterministic
  • The same name + namespace always produces the same UUID

  • Uses MD5 (weaker hash compared to SHA-1)
  • Not random

Example use case:

  • Generating the same UUID for the same email, username, or URL
  • Configuration keys
  • Cache keys

UUID v5: Name-based UUID (Deterministic using SHA-1)

How it works:

  • Same inputs as v3:
  1. Namespace UUID
  2. Name string
    • Uses SHA-1 hashing instead of MD5

Key points:

  • Also deterministic
  • More secure and preferred over v3
  • Same input gives same output every time

Example use case:

  • API keys
  • URL-based keys
  • Deterministic user identifiers

Difference Between MD5 and SHA-1

MD5 and SHA-1 are both hashing algorithms used to generate fixed-length hash values from input data. They are commonly used for checksums, signatures, and cryptographic operations—but SHA-1 is stronger than MD5.

Here is the exact difference:

1. Hash Length

  • MD5> 128-bit hash (32 characters in hex)
  • SHA-1> 160-bit hash (40 characters in hex)

Longer hash > more possible combinations > harder to break.

2. Security

  • MD5 is weaker
    • Easily breakable
    • High chance of collisions
    • Not recommended for any secure system
  • SHA-1 is stronger than MD5, but
    • Also considered weak today
    • Collisions have been demonstrated

Both are considered cryptographically broken, but SHA-1 is harder to break than MD5.

3. Collision Resistance

A collision happens when two different inputs produce the same hash.

  • MD5 > Very high collision vulnerability
  • SHA-1> Less vulnerable but still breakable

This is why modern security systems use SHA-256 or stronger algorithms.

4. Speed

  • MD5 is faster
  • SHA-1 is slightly slower (still very fast)

The speed difference is small in modern systems.

5. Use in UUIDs

In PostgreSQL:

  • UUID v3 uses MD5
  • UUID v5 uses SHA-1

Which means:

  • v3 > faster, weaker deterministic UUID
  • v5> stronger, safer deterministic UUID

That is why UUID v5 is preferred over UUID v3 in modern applications.

How to Enable the uuid-ossp Extension

Before using the functions, enable the extension in your database:

CREATE EXTENSION "uuid-ossp";

You can confirm that the extension is available using:

SELECT * FROM pg_available_extensions WHERE name = 'uuid-ossp';

And list all functions:

\dx+ uuid-ossp

Why Use UUIDs Instead of Serial or Bigserial?

Traditional integer primary keys (SERIAL, BIGSERIAL) are simple and fast, but they reveal system behavior:

  • Predictable and sequential
  • Expose information such as number of records
  • Not ideal for distributed writes
  • Harder to merge data between systems

UUIDs solve these problems:

  • Virtually impossible to guess
  • Safe for public URLs
  • Can be generated anywhere
  • Work well in distributed environments
  • No risk of collisions

All Functions Provided by uuid-ossp and Their Purpose

The extension gives you multiple UUID generation methods. Each method has a specific use case.

1. uuid_generate_v1()

Generates a Version 1 UUID, based on:

  • Timestamp
  • MAC address of the machine

Example:

SELECT uuid_generate_v1();

Use case:

Systems that require sortable UUIDs and are comfortable with MAC-address-based generation.

2. uuid_generate_v1mc()

Similar to v1 but uses a random multicast MAC instead of the hardware MAC.

Example:

SELECT uuid_generate_v1mc();

Use case:

When you want v1 UUID ordering advantage but want to avoid exposing real MAC addresses.

3. uuid_generate_v4()

Generates a Version 4 UUID, completely random.

Example:

SELECT uuid_generate_v4();

Use case:

Most common for modern applications. Provides strong randomness and avoids machine-identifying data.

4. uuid_nil()

Returns a UUID filled with all zeros:

00000000-0000-0000-0000-000000000000

Example:

SELECT uuid_nil();

Use case:

A standard “empty value” for UUID fields.

5. Namespace UUID Functions

These UUIDs act as predefined namespaces for name-based UUID generation.

  • uuid_ns_dns()
  • uuid_ns_oid()
  • uuid_ns_url()
  • uuid_ns_x500()

These return constant UUIDs defined in RFC 4122.

Example:

SELECT uuid_ns_dns();

Use case:

Used with v3 and v5 UUIDs to create namespaced identifiers.

6. uuid_generate_v3(namespace_uuid, name_text)

Generates a Version 3 UUID using:

  • MD5 hashing
  • Namespace UUID
  • A text value

Example:

SELECT uuid_generate_v3(uuid_ns_dns(), 'example.com');

Use case:

Use when you want deterministic UUIDs. The same input always produces the same UUID.

Common in:

  • URL hashing
  • DNS-based identities
  • Reproducible identifiers across environments

7. uuid_generate_v5(namespace_uuid, name_text)

Similar to v3 but uses SHA-1 hashing instead of MD5.

Example:

SELECT uuid_generate_v5(uuid_ns_url(), 'https://myapp.com/users');

Use case:

Safer deterministic UUIDs than v3. Useful for stable, repeatable keys in distributed systems.

When Should You Use v3 or v5 UUIDs?

Choose v3/v5 UUIDs when:

  • You need the same UUID every time for the same input
  • You want stable identifiers
  • Perfect for caching, URLs, integration, configuration keys

Never use them when you need randomness.

What’s New in PostgreSQL 18 Related to UUID?

Starting from PostgreSQL 13 onward, PostgreSQL has supported the built-in function:

gen_random_uuid()

In PostgreSQL 18, this remained the recommended way for modern projects.

gen_random_uuid() belongs to the pgcrypto extension:

CREATE EXTENSION pgcrypto;
SELECT gen_random_uuid();

Why is it recommended?

  • Faster
  • More secure
  • Does not require OSSP library installation
  • Purely random UUID v4

This means, for most modern uses, pgcrypto’s gen_random_uuid() is preferred over uuid_generate_v4().

However, uuid-ossp is still useful because:

  • It provides v1 UUID generation
  • It provides v3/v5 deterministic UUIDs
  • It provides namespace UUIDs
  • It is necessary when you need backwards compatibility

Which UUID Method Should You Use?

Here is a simple guidance:

  • Use v4 for most applications.
  • Use v1 when you need time-sortable UUIDs.
  • Use v1mc to avoid MAC exposure.
  • Use v3 or v5 when you need deterministic UUIDs
  • Use gen_random_uuid() on modern PostgreSQL instead of uuid_generate_v4()

Conclusion

The uuid-ossp extension in PostgreSQL is a versatile and reliable solution for generating multiple types of UUIDs directly inside the database. It supports time-based UUIDs, name-based deterministic UUIDs, namespace-based identifiers, and more—making it suitable for a wide range of system architectures and data requirements.

While PostgreSQL 18 continues to support this extension, the preferred method for generating modern random UUIDs is gen_random_uuid() from the pgcrypto extension due to its speed, security, and simplicity. However, uuid-ossp remains essential when you need features that pgcrypto does not provide, such as:

  • Time-based UUIDs (v1, v1mc)
  • Namespaced UUIDs (v3 and v5)
  • Deterministic and reproducible UUID generation

In scenarios where predictable or namespace-driven UUIDs are required, uuid-ossp is still the best choice.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message