postgres / now
now()
is not wall-clock time.
It is shorthand for
transaction_timestamp(),
fixed when the transaction begins.
That is usually what you want.
Every now() in the same transaction returns the same value,
so audit columns line up:
INSERT INTO docs (
title, summary, created_at, updated_at
) VALUES (
$1, $2, now(), now()
);
Two calls, one timestamp. Multi-row inserts and batch updates get the same guarantee.
The footgun is a freshness check inside a long transaction. A typical cooldown query:
SELECT
1
FROM
jobs
WHERE
name = $1
AND finished_at > now() - '3 days'::interval
LIMIT 1;
Fine on its own.
Inside a retry loop that stays in one BEGIN ... COMMIT,
now() never advances and the cooldown window is frozen.
Reach for
clock_timestamp()
when you need real elapsed time inside a transaction.
It reads the wall clock on each call.