Developer guide

Unix timestamp precision and storage guide

Choose the right epoch unit before it becomes a production migration. This guide focuses on practical storage choices for APIs, logs, databases, and high-precision event streams.

Pick a unit and storage shape

Seconds

10 digits today

Where seen: API payloads, Unix CLI, database functions

Store as: Use BIGINT/integer seconds or TIMESTAMPTZ for instants.

Milliseconds

13 digits

Where seen: JavaScript Date, browser events, many logs

Store as: Safe as a JS Number for modern dates; document the unit explicitly.

Microseconds

16 digits

Where seen: PostgreSQL logs, tracing, analytics

Store as: Do not store in JS Number when exactness matters; use string, BigInt, or BIGINT.

Nanoseconds

19 digits

Where seen: Go/Rust/Java Instant, protobuf Timestamp

Store as: Prefer seconds+nanos fields or decimal/string storage; avoid JSON number precision loss.

Storage decision checklist

  • Store one-off instants in UTC. In SQL, TIMESTAMPTZ is usually clearer than a local TIMESTAMP column.
  • For recurring local rules, store the IANA timezone such as America/New_York in addition to the instant or schedule.
  • Treat digit length as a heuristic, not validation. Confirm the producer contract before multiplying or dividing.
  • Serialize microseconds and nanoseconds as strings in JSON unless both sides explicitly support BigInt-style parsing.

Copyable implementation notes

JavaScript ms: const date = new Date(epochMilliseconds);
JavaScript ns: const seconds = epochNanoseconds / 1000000000n; const nanos = epochNanoseconds % 1000000000n;
PostgreSQL seconds: SELECT to_timestamp(epoch_seconds) AT TIME ZONE 'UTC';
PostgreSQL µs: SELECT to_timestamp(epoch_microseconds / 1000000.0);
Go: t := time.Unix(seconds, nanoseconds).UTC()

Next steps

Turn this guide into an action