Skip to content
pg_uuid_v8

pg_uuid_v8

pg_uuid_v8 : UUID v8 generator with embedded timestamps for PostgreSQL

Overview

IDExtensionPackageVersionCategoryLicenseLanguage
4530
pg_uuid_v8
pg_uuid_v8
1.0.0
FUNC
PostgreSQL
C
AttributeHas BinaryHas LibraryNeed LoadHas DDLRelocatableTrusted
--s-d--
No
Yes
No
Yes
no
no
Relationships
Schemaspublic
See Also
uuid-ossp
pg_uuidv7
sequential_uuids
pg_idkit
pgx_ulid

Pinned to public so uuid operator commutators resolve on PostgreSQL 17 and 18.

Packages

TypeRepoVersionPG Major CompatibilityPackage PatternDependencies
EXT
PIGSTY
1.0.0
18
17
16
15
14
pg_uuid_v8-
RPM
PIGSTY
1.0.0
18
17
16
15
14
pg_uuid_v8_$v-
DEB
PIGSTY
1.0.0
18
17
16
15
14
postgresql-$v-pg-uuid-v8-
Linux / PGPG18PG17PG16PG15PG14
el8.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
el8.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
el9.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
el9.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
el10.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
el10.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
d12.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
d12.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
d13.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
d13.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
u22.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
u22.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
u24.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
u24.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
u26.x86_64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
u26.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PackageVersionOSORGSIZEFile URL
pg_uuid_v8_181.0.0el8.x86_64pigsty18.9 KiBpg_uuid_v8_18-1.0.0-1PIGSTY.el8.x86_64.rpm
pg_uuid_v8_181.0.0el8.aarch64pigsty19.2 KiBpg_uuid_v8_18-1.0.0-1PIGSTY.el8.aarch64.rpm
pg_uuid_v8_181.0.0el9.x86_64pigsty18.7 KiBpg_uuid_v8_18-1.0.0-1PIGSTY.el9.x86_64.rpm
pg_uuid_v8_181.0.0el9.aarch64pigsty18.7 KiBpg_uuid_v8_18-1.0.0-1PIGSTY.el9.aarch64.rpm
pg_uuid_v8_181.0.0el10.x86_64pigsty18.9 KiBpg_uuid_v8_18-1.0.0-1PIGSTY.el10.x86_64.rpm
pg_uuid_v8_181.0.0el10.aarch64pigsty19.1 KiBpg_uuid_v8_18-1.0.0-1PIGSTY.el10.aarch64.rpm
postgresql-18-pg-uuid-v81.0.0d12.x86_64pigsty18.9 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~bookworm_amd64.deb
postgresql-18-pg-uuid-v81.0.0d12.aarch64pigsty18.6 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~bookworm_arm64.deb
postgresql-18-pg-uuid-v81.0.0d13.x86_64pigsty18.9 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~trixie_amd64.deb
postgresql-18-pg-uuid-v81.0.0d13.aarch64pigsty18.6 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~trixie_arm64.deb
postgresql-18-pg-uuid-v81.0.0u22.x86_64pigsty19.4 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~jammy_amd64.deb
postgresql-18-pg-uuid-v81.0.0u22.aarch64pigsty19.4 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~jammy_arm64.deb
postgresql-18-pg-uuid-v81.0.0u24.x86_64pigsty19.6 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~noble_amd64.deb
postgresql-18-pg-uuid-v81.0.0u24.aarch64pigsty19.1 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~noble_arm64.deb
postgresql-18-pg-uuid-v81.0.0u26.x86_64pigsty19.6 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~resolute_amd64.deb
postgresql-18-pg-uuid-v81.0.0u26.aarch64pigsty19.6 KiBpostgresql-18-pg-uuid-v8_1.0.0-1PIGSTY~resolute_arm64.deb

Source

pig build pkg pg_uuid_v8;		# build rpm/deb

Install

Make sure PGDG and PIGSTY repo available:

pig repo add pgsql -u   # add both repo and update cache

Install this extension with pig:

pig install pg_uuid_v8;		# install via package name, for the active PG version

pig install pg_uuid_v8 -v 18;   # install for PG 18
pig install pg_uuid_v8 -v 17;   # install for PG 17
pig install pg_uuid_v8 -v 16;   # install for PG 16
pig install pg_uuid_v8 -v 15;   # install for PG 15
pig install pg_uuid_v8 -v 14;   # install for PG 14

Create this extension with:

CREATE EXTENSION pg_uuid_v8;

Usage

Sources: pg_uuid_v8 README, SQL definitions, control file.

pg_uuid_v8 generates UUIDs that look like UUID v4 values while embedding encrypted microsecond timestamps for extraction, sorting, and range predicates. The SQL file exposes both uuid_stego_* names and uuid_v8_* convenience aliases.

Generate UUIDs

CREATE EXTENSION pg_uuid_v8;

SELECT uuid_v8_set_seed('replace-with-a-secret-seed');
SELECT uuid_v8_generate();

The equivalent lower-level generator is:

SELECT uuid_stego_generate();

Use a default expression when inserting events:

CREATE TABLE events (
  id uuid PRIMARY KEY DEFAULT uuid_v8_generate(),
  data jsonb,
  created_at timestamptz DEFAULT now()
);

Extract And Query Hidden Timestamps

Extract the embedded timestamp as microseconds since the Unix epoch:

SELECT uuid_v8_extract_timestamp(id)
FROM events
ORDER BY uuid_v8_extract_timestamp(id)
LIMIT 10;

The README recommends functional indexes for time-based lookups:

CREATE INDEX events_uuid_v8_time_idx
ON events USING btree (uuid_v8_extract_timestamp(id));

SELECT *
FROM events
WHERE uuid_v8_extract_timestamp(id)
      BETWEEN timestamp_to_stego_time('2026-01-01'::timestamptz)
          AND timestamp_to_stego_time(now())
ORDER BY uuid_v8_extract_timestamp(id);

Helper functions convert between timestamps and the integer timestamp format:

SELECT timestamp_to_stego_time(now());
SELECT stego_time_to_timestamp(uuid_v8_extract_timestamp(id))
FROM events;

Range Helpers And Operators

The SQL definition includes direct range helpers:

SELECT *
FROM events
WHERE uuid_stego_in_range(
  id,
  now() - interval '24 hours',
  now()
);

It also defines timestamp-aware comparison functions and operators for uuid:

  • uuid_stego_compare(uuid, uuid) and uuid_v8_compare(uuid, uuid).
  • uuid_stego_lt, uuid_stego_le, uuid_stego_gt, uuid_stego_ge.
  • Operators <, <=, >, and >= compare UUIDs by hidden timestamp.

Seed And Encryption Mode

Set and inspect the seed:

SELECT uuid_v8_set_seed('replace-with-a-secret-seed');
SELECT uuid_v8_get_seed();

Available encryption modes are XOR, AES128, and AES256:

SELECT uuid_v8_get_encryption_mode();
SELECT uuid_v8_set_encryption_mode('AES128');
SELECT uuid_v8_set_encryption_mode('XOR');

For a persistent default, the README documents the uuid_v8.encryption_mode GUC:

ALTER SYSTEM SET uuid_v8.encryption_mode = 'AES128';
SELECT pg_reload_conf();

Caveats

  • Keep the seed secret; it is required to interpret hidden timestamps.
  • UUIDs generated with one seed and encryption mode must be decoded with the same settings.
  • Functional indexes on extracted timestamps add storage and update overhead, but are the intended path for efficient time-range predicates.
  • Local Pigsty metadata pins this extension to the public schema so the UUID comparison operator commutators resolve on PostgreSQL 17 and 18; test operators explicitly if using a different schema in a non-Pigsty build.
Last updated on