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
Related parameters
transaction_read_only in_hot_standby default_transaction_isolation