PostgreSQL automatically closes idle sessions based on the idle_session_timeout parameter, typically set for interactive users. This error occurs when a session has been idle (not running queries) for longer than the configured timeout duration.
The idle_session_timeout parameter controls the maximum amount of time a session can remain idle before PostgreSQL automatically terminates the connection. Introduced in PostgreSQL 14, this setting applies to any session that is idle when not in a transaction. When the timeout expires, PostgreSQL sends a FATAL error and closes the connection. Unlike idle_in_transaction_session_timeout, which only applies to sessions waiting inside a transaction, idle_session_timeout applies to all idle sessions regardless of transaction state.
First, verify what idle_session_timeout is set to on your PostgreSQL server:
SELECT name, setting FROM pg_settings WHERE name = 'idle_session_timeout';The result shows the timeout value in milliseconds. A value of 0 means the timeout is disabled. If the setting is non-zero, it's actively terminating idle sessions.
If you don't need idle session timeout, disable it by setting it to 0:
ALTER SYSTEM SET idle_session_timeout = 0;Then reload the configuration:
SELECT pg_reload_conf();This disables the timeout globally. Verify the change took effect by running the pg_settings query again.
Best practice: don't apply idle_session_timeout globally. Instead, set it only for interactive login accounts:
ALTER ROLE interactive_user SET idle_session_timeout = 600000; -- 10 minutesAvoid setting this for service or application accounts, as connection poolers and application frameworks may not handle unexpected disconnections gracefully.
If you need idle_session_timeout for interactive users, increase the duration to a reasonable value:
ALTER ROLE interactive_user SET idle_session_timeout = 1800000; -- 30 minutesTimeout values are in milliseconds. Common durations:
- 600000 = 10 minutes
- 1200000 = 20 minutes
- 1800000 = 30 minutes
Choose a value that matches your expected user behavior.
Prevent frozen connections on the client side by adding a connection timeout to your connection string:
postgresql://user:password@host:5432/database?connect_timeout=5Or set the PGCONNECT_TIMEOUT environment variable:
export PGCONNECT_TIMEOUT=5This ensures clients don't hang indefinitely on network failures.
Configure TCP keepalive to detect and clean up dead connections:
ALTER SYSTEM SET tcp_keepalives_idle = 120; -- 2 minutes
ALTER SYSTEM SET tcp_keepalives_interval = 30; -- 30 seconds
ALTER SYSTEM SET tcp_keepalives_count = 5; -- 5 probesThen reload:
SELECT pg_reload_conf();TCP keepalive helps detect network issues without relying on idle_session_timeout.
If your application experiences frequent disconnections, use a connection pooler like PgBouncer to manage connections and reduce the impact of timeouts:
sudo apt-get install pgbouncerConfigure PgBouncer in your connection pool to:
- Reuse connections across multiple application processes
- Implement connection pooling strategies (transaction or session mode)
- Handle reconnection logic automatically
This allows the pooler to manage timeouts while keeping application connections stable.
idle_session_timeout applies to sessions when NOT in a transaction, making it less critical than idle_in_transaction_session_timeout. However, unlike an open transaction, an idle session imposes minimal server resource cost, so enabling this timeout is usually unnecessary unless managing interactive user behavior. Be cautious when setting idle_session_timeout on connections made through connection pooling middleware; unexpected connection closures can cause poolers to behave unpredictably. For production databases, prefer using idle_in_transaction_session_timeout (which terminates only transactions) rather than idle_session_timeout. PostgreSQL 14+ introduced idle_session_timeout; earlier versions only have idle_in_transaction_session_timeout. Consider using role-based settings to apply different timeouts to different user categories (interactive vs. service accounts). TCP keepalive is a complementary approach that doesn't require parameter changes and may be preferable in shared infrastructure environments.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL