From 984ab0098fc0fe027750cc513ad4c026e7630645 Mon Sep 17 00:00:00 2001 From: deepshekhardas Date: Fri, 31 Jul 2026 11:19:34 +0530 Subject: [PATCH] fix(replication): correct Postgres epoch constant in replication client --- internal-packages/replication/src/client.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/internal-packages/replication/src/client.ts b/internal-packages/replication/src/client.ts index a45831dc57e..7423c3e1a9c 100644 --- a/internal-packages/replication/src/client.ts +++ b/internal-packages/replication/src/client.ts @@ -12,6 +12,14 @@ import { PgoutputParser, } from "./pgoutput.js"; +/** + * Milliseconds between the Unix epoch (1970-01-01) and the Postgres epoch + * (2000-01-01), used to convert between Postgres replication timestamps and + * `Date.now()`. Mirrors `(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * USECS_PER_DAY` + * in pgoutput.ts (946684800000000 micros). + */ +const POSTGRES_EPOCH_MS = 946684800000; + export interface LogicalReplicationClientOptions { /** * The pg client config. @@ -521,7 +529,7 @@ export class LogicalReplicationClient { } else if (buffer[0] === 0x6b) { // Primary keepalive message const timestamp = Math.floor( - buffer.readUInt32BE(9) * 4294967.296 + buffer.readUInt32BE(13) / 1000 + 946080000000 + buffer.readUInt32BE(9) * 4294967.296 + buffer.readUInt32BE(13) / 1000 + POSTGRES_EPOCH_MS ); const shouldRespond = !!buffer.readInt8(17); this.events.emit("heartbeat", { lsn, timestamp, shouldRespond }); @@ -833,7 +841,7 @@ export class LogicalReplicationClient { const slice = lsn.split("/"); let [upperWAL, lowerWAL]: [number, number] = [parseInt(slice[0], 16), parseInt(slice[1], 16)]; // Timestamp as microseconds since midnight 2000-01-01 - const now = Date.now() - 946080000000; + const now = Date.now() - POSTGRES_EPOCH_MS; const upperTimestamp = Math.floor(now / 4294967.296); const lowerTimestamp = Math.floor(now - upperTimestamp * 4294967.296); if (lowerWAL === 4294967295) {