now(), current_timestamp, and current_date all return the timestamp when the current transaction started. In a multi-second or multi-minute transaction, they stay frozen. This means using now() for elapsed-time calculations inside a transaction will always show zero elapsed time.
-- Inside a long transaction — this doesn't measure actual elapsed time:
SELECT now() - start_time AS elapsed FROM long_running_task;Result: Incorrect elapsed time if called within same transaction as start_time assignment
-- Use clock_timestamp() for real wall-clock time:
SELECT clock_timestamp() - start_time AS elapsed FROM long_running_task;
-- Or timeofday() which returns a text timestamp:
SELECT timeofday();Result: Actual wall-clock elapsed time
now() = current_timestamp = transaction start. clock_timestamp() = actual system clock, changes with each call. statement_timestamp() = start of the current SQL statement. For audit timestamps that should reflect the real commit time, use clock_timestamp() in triggers.