DB Internals AtlasPostgreSQL 18.6 Home About

Parameter · Client Connection Defaults / Statement Behavior

default_transaction_read_only

Sets the default read-only status of new transactions.

  • Default: off
  • Type: bool
  • Applies: Session (any user)

In plain words

When on, each new transaction starts as read-only: SELECTs work, but INSERT, UPDATE, DELETE and DDL fail. It is a guard rail for reporting users, not a security feature, because a session can switch it back off.

For DBAs and operators

Sets the initial value of transaction_read_only. Writes fail with ERROR: cannot execute CREATE TABLE in a read-only transaction (or INSERT/UPDATE/…). Writes to temporary tables are still allowed.

It is not a permission: any user can SET default_transaction_read_only = off or run BEGIN READ WRITE. Use GRANT/REVOKE for real protection.

Notable uses: ALTER DATABASE … SET default_transaction_read_only = on during a migration freeze; on a hot standby, transactions are read-only regardless (see in_hot_standby). Since PostgreSQL 14 this parameter is reported to clients, and libpq target_session_attrs=read-write uses it together with in_hot_standby to pick a writable server, so a primary with this set to on is skipped by such clients.

How to change it

Any user can change it for their session with SET.

See it in context

Hot standby and recovery conflicts

Related parameters

transaction_read_only in_hot_standby default_transaction_isolation

All Client Connection Defaults parameters