Skip to content

Commit 1fcb4a7

Browse files
committed
fix(replication): correct Postgres epoch constant in replication client
The keepalive decode and standby status ack used 946080000000 as the Postgres-to-Unix epoch offset (ms). That value is 1999-12-25, seven days short of the real Postgres epoch (2000-01-01 = 946684800000). Replace both literals with a shared POSTGRES_EPOCH_MS constant matching pgoutput.ts. The affected timestamps are observability-only: the decoded keepalive timestamp is unused by consumers, and the encoded standby-reply timestamp only surfaces as pg_stat_replication.reply_time. WAL feedback is driven by the LSN bytes, so slot advancement is unaffected.
1 parent 65c545d commit 1fcb4a7

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

internal-packages/replication/src/client.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ import { LogicalReplicationClientError } from "./errors.js";
99
import { PgoutputMessage, PgoutputParser, getPgoutputStartReplicationSQL } from "./pgoutput.js";
1010
import { startSpan, trace, Tracer } from "@internal/tracing";
1111

12+
/**
13+
* Milliseconds between the Unix epoch (1970-01-01) and the Postgres epoch
14+
* (2000-01-01), used to convert between Postgres replication timestamps and
15+
* `Date.now()`. Mirrors `(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * USECS_PER_DAY`
16+
* in pgoutput.ts (946684800000000 micros).
17+
*/
18+
const POSTGRES_EPOCH_MS = 946684800000;
19+
1220
export interface LogicalReplicationClientOptions {
1321
/**
1422
* The pg client config.
@@ -363,7 +371,7 @@ export class LogicalReplicationClient {
363371
} else if (buffer[0] === 0x6b) {
364372
// Primary keepalive message
365373
const timestamp = Math.floor(
366-
buffer.readUInt32BE(9) * 4294967.296 + buffer.readUInt32BE(13) / 1000 + 946080000000
374+
buffer.readUInt32BE(9) * 4294967.296 + buffer.readUInt32BE(13) / 1000 + POSTGRES_EPOCH_MS
367375
);
368376
const shouldRespond = !!buffer.readInt8(17);
369377
this.events.emit("heartbeat", { lsn, timestamp, shouldRespond });
@@ -658,7 +666,7 @@ export class LogicalReplicationClient {
658666
const slice = lsn.split("/");
659667
let [upperWAL, lowerWAL]: [number, number] = [parseInt(slice[0], 16), parseInt(slice[1], 16)];
660668
// Timestamp as microseconds since midnight 2000-01-01
661-
const now = Date.now() - 946080000000;
669+
const now = Date.now() - POSTGRES_EPOCH_MS;
662670
const upperTimestamp = Math.floor(now / 4294967.296);
663671
const lowerTimestamp = Math.floor(now - upperTimestamp * 4294967.296);
664672
if (lowerWAL === 4294967295) {

0 commit comments

Comments
 (0)