# psycopg2.OperationalError: ERROR: out of shared memory HINT: You might need to increase max_locks_per_transaction.

- **ID:** `database/postgresql-too-many-snapshots`
- **Domain:** database
- **Category:** resource_error
- **Verification:** ai_generated
- **Fix Rate:** 78%

## Root Cause

PostgreSQL's shared memory for lock management is exhausted, typically because too many concurrent transactions hold locks or snapshots, exceeding the max_locks_per_transaction * max_connections limit.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| PostgreSQL 14 | active | — | — |
| PostgreSQL 15 | active | — | — |
| PostgreSQL 16 | active | — | — |

## Workarounds

1. **Increase max_locks_per_transaction in postgresql.conf (e.g., to 128 or 256), then restart PostgreSQL. Verify with SHOW max_locks_per_transaction;. Also consider reducing the number of concurrent long-running transactions.** (85% success)
   ```
   Increase max_locks_per_transaction in postgresql.conf (e.g., to 128 or 256), then restart PostgreSQL. Verify with SHOW max_locks_per_transaction;. Also consider reducing the number of concurrent long-running transactions.
   ```
2. **Identify and terminate idle-in-transaction sessions that hold locks: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND xact_start < now() - interval '10 minutes';** (80% success)
   ```
   Identify and terminate idle-in-transaction sessions that hold locks: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND xact_start < now() - interval '10 minutes';
   ```

## Dead Ends

- **Restart PostgreSQL to clear the shared memory, assuming it's a temporary leak** — If the workload pattern (e.g., many concurrent long-running transactions) remains the same, the error will recur quickly after restart. (85% fail)
- **Increase max_connections instead of max_locks_per_transaction** — max_connections increases the number of possible connections but does not increase the lock space per connection; the shared memory limit is still bounded by max_locks_per_transaction * max_connections. (75% fail)
