pg_uuid_v8
Overview
| Package | Version | Category | License | Language |
|---|---|---|---|---|
pg_uuid_v8 | 1.0.0 | FUNC | PostgreSQL | C |
| ID | Extension | Bin | Lib | Load | Create | Trust | Reloc | Schema |
|---|---|---|---|---|---|---|---|---|
| 4530 | pg_uuid_v8 | No | Yes | No | Yes | No | No | public |
| Related | uuid-ossp pg_uuidv7 sequential_uuids pg_idkit pgx_ulid |
|---|
Pinned to public so uuid operator commutators resolve on PostgreSQL 17 and 18.
Version
| Type | Repo | Version | PG Ver | Package | Deps |
|---|---|---|---|---|---|
| EXT | PIGSTY | 1.0.0 | 1817161514 | pg_uuid_v8 | - |
| RPM | PIGSTY | 1.0.0 | 1817161514 | pg_uuid_v8_$v | - |
| DEB | PIGSTY | 1.0.0 | 1817161514 | postgresql-$v-pg-uuid-v8 | - |
Build
You can build the RPM / DEB packages for pg_uuid_v8 using pig build:
pig build pkg pg_uuid_v8 # build RPM / DEB packages
Install
You can install pg_uuid_v8 directly. First, make sure the PGDG and PIGSTY repositories are added and enabled:
pig repo add pgsql -u # Add repo and update cache
Install the extension using pig or apt/yum/dnf:
pig install pg_uuid_v8; # Install for current active PG version
pig ext install -y pg_uuid_v8 -v 18 # PG 18
pig ext install -y pg_uuid_v8 -v 17 # PG 17
pig ext install -y pg_uuid_v8 -v 16 # PG 16
pig ext install -y pg_uuid_v8 -v 15 # PG 15
pig ext install -y pg_uuid_v8 -v 14 # PG 14
dnf install -y pg_uuid_v8_18 # PG 18
dnf install -y pg_uuid_v8_17 # PG 17
dnf install -y pg_uuid_v8_16 # PG 16
dnf install -y pg_uuid_v8_15 # PG 15
dnf install -y pg_uuid_v8_14 # PG 14
apt install -y postgresql-18-pg-uuid-v8 # PG 18
apt install -y postgresql-17-pg-uuid-v8 # PG 17
apt install -y postgresql-16-pg-uuid-v8 # PG 16
apt install -y postgresql-15-pg-uuid-v8 # PG 15
apt install -y postgresql-14-pg-uuid-v8 # PG 14
Create Extension:
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)anduuid_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
publicschema 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.
Feedback
Was this page helpful?
Thanks for the feedback! Please let us know how we can improve.
Sorry to hear that. Please let us know how we can improve.