Skip to content

pg_nanotime

Nanosecond timestamp and fixed-duration interval types

Overview

PackageVersionCategoryLicenseLanguage
pg_nanotime0.2.0TYPEPostgreSQLC
IDExtensionBinLibLoadCreateTrustRelocSchema
3870pg_nanotimeNoYesNoYesNoYes-

0.2.0 is a PGXN testing release for PG17-18. Adds nanointerval aggregates, abs and generate_series. Ordinary types need no preload; cross-backend global clocks require preload/restart, and state is lost at restart.

Version

TypeRepoVersionPG VerPackageDeps
EXTPIGSTY0.2.01817161514pg_nanotime-
RPMPIGSTY0.2.01817161514pg_nanotime_$v-
DEBPIGSTY0.2.01817161514postgresql-$v-pg-nanotime-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64N/AN/AN/A
el8.aarch64N/AN/AN/A
el9.x86_64N/AN/AN/A
el9.aarch64N/AN/AN/A
el10.x86_64N/AN/AN/A
el10.aarch64N/AN/AN/A
d12.x86_64N/AN/AN/A
d12.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A
d13.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A
d13.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A
u22.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A
u22.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A
u24.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A
u24.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A
u26.x86_64N/AN/AN/A
u26.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
N/AN/AN/A

Build

You can build the RPM / DEB packages for pg_nanotime using pig build:

pig build pkg pg_nanotime         # build RPM / DEB packages

Install

You can install pg_nanotime 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:

Install
pig install pg_nanotime;          # Install for current active PG version
pig
pig ext install -y pg_nanotime -v 18  # PG 18
pig ext install -y pg_nanotime -v 17  # PG 17
dnf
dnf install -y pg_nanotime_18       # PG 18
dnf install -y pg_nanotime_17       # PG 17
apt
apt install -y postgresql-18-pg-nanotime   # PG 18
apt install -y postgresql-17-pg-nanotime   # PG 17

Create Extension:

CREATE EXTENSION pg_nanotime;

Usage

Sources:

pg_nanotime 0.2.0 provides nanosecond timestamp and interval types on PostgreSQL 17–18 for event timestamps, latency measurements and externally supplied nanosecond data. Nanosecond storage precision does not imply nanosecond clock accuracy.

Core Workflow

CREATE EXTENSION pg_nanotime;
CREATE TABLE events (at nanotimestamptz DEFAULT clock_ns(), body text);
INSERT INTO events (body) VALUES ('received');
SELECT at, at::timestamptz FROM events;
TypeStorage and meaning
nanotimestamptz16 bytes; an instant displayed in the session time zone, with PostgreSQL’s full timestamp range
nanotimestamp16 bytes; a timestamp without a time zone
nanotimestamptz88 bytes; signed Unix nanoseconds with a narrower 1677–2262 range
nanointerval16 bytes; a fixed elapsed duration, without calendar months

Conversion to built-in timestamps floors to microseconds, including before the Unix epoch. Casting an instant to bigint yields Unix nanoseconds and fails if the result exceeds bigint range. Do not use double precision to transport large integer nanosecond values.

Durations, Aggregates and Series

Subtracting timestamps produces a nanosecond duration. Version 0.2.0 adds interval aggregates and series generation:

WITH samples(ns) AS (VALUES (1250::bigint), (2751::bigint))
SELECT sum(nanointerval_from_ns(ns)) AS total,
       avg(nanointerval_from_ns(ns)) AS mean,
       abs(nanointerval_from_ns(-1250::bigint)) AS magnitude
FROM samples;

SELECT *
FROM generate_series(
  '2026-10-24 00:00:00+00'::nanotimestamptz,
  '2026-10-24 00:00:00.000000003+00'::nanotimestamptz,
  nanointerval_from_ns(1::bigint)
);

sum and avg accumulate exactly, ignore NULL values and return NULL for no input; overflow raises an error. The average rounds to the nearest nanosecond, with ties away from zero. Series include a reachable stop value, support negative steps and reject a zero step.

Use nanointerval_from_ns(bigint) for exact integer input and nanointerval_from_ns(numeric) for larger values; fractional input rounds to nanoseconds. The double-precision overload becomes inexact beyond 2^53 nanoseconds.

Other useful objects include time_bucket_ns for fixed-duration buckets, extract_ns for precise fields, date_trunc and timezone. Explicitly type duration literals: an untyped string in timestamp arithmetic may resolve to PostgreSQL’s calendar-aware interval. Timestamp types support B-tree, hash and BRIN minmax indexes; the interval type supports B-tree and hash.

Clocks and Boundaries

clock_ns() reads the wall clock on each call. now_ns() caches an extension clock reading for the transaction and statement_ns() for the statement; these readings are not the same sampling instant as PostgreSQL’s built-in timestamps. Ordinary clocks can move backwards with the system clock.

clock_ns_monotonic() produces strictly increasing values within one backend. clock_ns_global() does so across backends in one PostgreSQL instance and requires this configuration followed by a server restart:

shared_preload_libraries = 'pg_nanotime'

Preserve other libraries already in the setting. Ordinary types and clocks do not require preloading. Global monotonic state is in shared memory and does not survive restart; it is not a durable sequence or distributed ordering mechanism. Install as a superuser. The extension is relocatable and is not marked trusted.

nanotime_clock_status() reports clock and monotonic-state diagnostics. nanotime.clock_source defaults to realtime; the optional tai source depends on the operating system’s configured TAI offset. TAI values still use UTC-style output, so do not mix these sources in the same column.

Upgrade and Migration

Upstream marks 0.2.0 as a PGXN testing release. After replacing library and SQL files, update each database:

ALTER EXTENSION pg_nanotime UPDATE TO '0.2.0';

The column-conversion helper nanotime_migrate_column defaults to the 16-byte type, even for a bigint source, and changes the column with ALTER TABLE, rebuilding its indexes. Review the conversion and locking cost before running it. TimescaleDB integration is optional; its integer-time and continuous-aggregate requirements are separate from merely storing nanosecond timestamps.

Was this page helpful?