Configuring PostgreSQL Server

1. Initializing Database Cluster

initdb -D /var/lib/postgresql/17/main \
       -U postgres --pwprompt \
       -E UTF8 --locale=en_US.UTF-8 \
       --data-checksums
FlagPurpose
-DData directory (PGDATA)
-USuperuser name (default postgres)
-EDefault encoding
--localeDefault collation/ctype
--data-checksumsPage-level corruption detection (recommended)
--wal-segsizeWAL file size (default 16 MB)

2. Starting Server

MethodCommand
pg_ctlpg_ctl -D $PGDATA -l logfile start
systemdsudo systemctl start postgresql
Directpostgres -D $PGDATA

3. Stopping Server

ModeCommandBehavior
smartpg_ctl stop -m smartWait for clients (default)
fastpg_ctl stop -m fastDisconnect clients, clean shutdown
immediatepg_ctl stop -m immediateAbort; requires recovery on next start

4. Restarting Server

Use CaseCommand
Apply config requiring restartpg_ctl restart -D $PGDATA -m fast
systemdsudo systemctl restart postgresql
Note: Parameters with context postmaster require restart; check with SELECT name, context FROM pg_settings;

5. Reloading Configuration

pg_ctl reload -D $PGDATA
sudo systemctl reload postgresql
psql -c "SELECT pg_reload_conf();"
Reload Picks UpRestart Required
pg_hba.conf, pg_ident.confshared_buffers, max_connections
log_*, work_mem, autovacuum_*listen_addresses, port, wal_level

6. Setting Environment Variables

VariablePurpose
PGDATAData directory path
PGHOSTDefault server host
PGPORTDefault port (5432)
PGUSERDefault username
PGPASSWORDPassword (insecure; prefer .pgpass)
PGDATABASEDefault database name
PGSSLMODErequire, verify-full, etc.
PGAPPNAMEapplication_name shown in pg_stat_activity

7. Configuring postgresql.conf

ParameterRecommendedNotes
listen_addresses'*' or 'localhost'Restart required
port5432Restart required
max_connections100-300Use pooler beyond ~300
shared_preload_libraries'pg_stat_statements'Restart required
timezone'UTC'Reload

8. Setting Memory Parameters

ParameterTypical (16 GB box)Purpose
shared_buffers4GB (25% RAM)OS-shared page cache
effective_cache_size12GB (75% RAM)Planner hint, not allocated
work_mem16-64MBPer sort/hash op
maintenance_work_mem1GBVACUUM, CREATE INDEX
wal_buffers16MBAuto-tuned by default
temp_buffers8MBPer-session temp tables

9. Setting Connection Limits

SettingEffect
max_connectionsTotal backend cap
superuser_reserved_connectionsSlots reserved for superusers
CREATE ROLE ... CONNECTION LIMIT nPer-role cap
ALTER DATABASE x CONNECTION LIMIT nPer-database cap

10. Configuring Logging

ParameterRecommended
logging_collectoron
log_directory'log'
log_filename'postgresql-%Y-%m-%d.log'
log_min_duration_statement1000 (ms)
log_line_prefix'%m [%p] %q%u@%d '
log_checkpointson
log_connections / log_disconnectionson (audit)
log_lock_waitson
log_temp_files0 (log all)

11. Setting WAL Parameters

ParameterTypicalPurpose
wal_levelreplica or logicalReplication mode
max_wal_size4GBCheckpoint trigger
min_wal_size1GBRecycle floor
checkpoint_timeout15minMax time between checkpoints
checkpoint_completion_target0.9Spread checkpoint I/O
wal_compressiononReduce WAL volume
synchronous_commiton / off / remote_applyDurability vs latency

12. Understanding Configuration File Hierarchy

postgresql.conf  ← base file
   └─ include 'conf.d/*.conf'
postgresql.auto.conf  ← written by ALTER SYSTEM (highest precedence)
ALTER DATABASE x SET param = ...
ALTER ROLE x SET param = ...
SET param = ... (session)
SET LOCAL param = ... (transaction)
      
SHOW work_mem;
SELECT name, setting, source, context
  FROM pg_settings
 WHERE name = 'work_mem';
ALTER SYSTEM SET work_mem = '32MB';   -- writes postgresql.auto.conf
SELECT pg_reload_conf();