---
title: UUIDv7 functions | Tiger Data Docs
description: Create a hypertable partitioned by time-based UUIDv7
---

Community

UUIDv7 is a time-ordered UUID that includes a Unix timestamp with millisecond precision in its first 48 bits. Like other UUIDs it uses 6 bits for version and variant info. The remaining 74 bits are random.

![UUIDv7 structure with microsecond-precision timestamp](/docs/_astro/uuidv7-structure-microseconds.BBrmloq3.svg)

UUIDv7 is ideal anywhere you create lots of records over time. Advantages are:

- **No extra column required to partition by time with sortability**: you can sort UUIDv7 instances by their value. This is useful for ordering records by creation time without the need for a separate timestamp column.
- **Indexing performance**: UUIDv7s increase with time, so new rows are appended near the end of a B-tree. This results in fewer page splits, less fragmentation, faster inserts, and efficient time-range scans.
- **Easy keyset pagination**: `WHERE id > :cursor` and natural sharding.
- **UUID**: safe across services, replicas, and unique across distributed systems.

UUIDv7 also increases query speed by reducing the number of chunks scanned during queries. For example, in a database with 25 million rows, the following query runs in 25 seconds:

```
WITH ref AS (SELECT now() AS t0)
SELECT count(*) AS cnt_ts_filter
FROM events e, ref
WHERE uuid_timestamp(e.event_id) >= ref.t0 - INTERVAL '2 days';
```

Using UUIDv7 means that chunks are excluded at startup, and the query time is reduced to 550 ms:

```
WITH ref AS (SELECT now() AS t0)
SELECT count(*) AS cnt_boundary_filter
FROM events e, ref
WHERE e.event_id >= to_uuidv7_boundary(ref.t0 - INTERVAL '2 days')
```

You use UUIDs for events, orders, messages, uploads, runs, jobs, spans, and more.

## Samples

- **High-rate event logs for observability and metrics**:

  UUIDv7 gives you globally unique IDs for traceability and time windows such as “last hour”, without the need for a separate `created_at` column. UUIDv7 creates less churn because inserts land at the end of the index, and you can filter by time using UUIDv7 objects.

  - Last hour:

    ```
    SELECT count(*) FROM logs WHERE id >= to_uuidv7_boundary(now() - interval '1 hour');
    ```

  - Keyset pagination:

    ```
    SELECT * FROM logs WHERE id > to_uuidv7_boundary($last_seen::timestamptz) ORDER BY id LIMIT 1000;
    ```

- **Workflow / durable execution runs**:

  Each run needs a stable ID for joins and retries. UUIDs help by serving both as the primary key and a time cursor. For example:

  ```
  SELECT run_id, status
  FROM runs
  WHERE run_id >= to_uuidv7_boundary(now() - interval '5 minutes')
  ```

- **Orders / activity feeds / messages (SaaS apps)**:

  Human-readable timestamps are not mandatory in a table. However, you still need time-ordered pages and day/week ranges. UUIDv7 enables clean date windows and cursor pagination with just the ID. For example:

  ```
  SELECT * FROM orders
  WHERE id >= to_uuidv7_boundary('2025-08-01'::timestamptz)
  AND id <  to_uuidv7_boundary('2025-08-02'::timestamptz)
  ORDER BY id;
  ```

## Available functions

- [`generate_uuidv7()`](/docs/reference/timescaledb/uuid-functions/generate_uuidv7/index.md): generate a version 7 UUID based on the current time
- [`to_uuidv7()`](/docs/reference/timescaledb/uuid-functions/to_uuidv7/index.md): create a version 7 UUID from a PostgreSQL timestamp
- [`to_uuidv7_boundary()`](/docs/reference/timescaledb/uuid-functions/to_uuidv7_boundary/index.md): create a version 7 “boundary” UUID from a PostgreSQL timestamp
- [`uuid_timestamp()`](/docs/reference/timescaledb/uuid-functions/uuid_timestamp/index.md): extract a PostgreSQL timestamp from a version 7 UUID
- [`uuid_timestamp_micros()`](/docs/reference/timescaledb/uuid-functions/uuid_timestamp_micros/index.md): extract a PostgreSQL timestamp with microsecond precision from a version 7 UUID
- [`uuid_version()`](/docs/reference/timescaledb/uuid-functions/uuid_version/index.md): extract the version of a UUID
