Systemd & Service Management
Production PostgreSQL on Linux runs under systemd (or an equivalent init). Knowing start, stop, reload, and status maps directly to incident response and safe deploys.
Search across all documentation pages
Production PostgreSQL on Linux runs under systemd (or an equivalent init). Knowing start, stop, reload, and status maps directly to incident response and safe deploys.
# systemd (Debian/Ubuntu package names vary)
sudo systemctl start postgresql@18-main
sudo systemctl status postgresql@18-main
sudo systemctl reload postgresql@18-main
# pg_ctl equivalents (any install)
sudo -u postgres pg_ctl -D /var/lib/postgresql/18/main start
sudo -u postgres pg_ctl -D /var/lib/postgresql/18/main reload
sudo -u postgres pg_ctl -D /var/lib/postgresql/18/main statusWhen to reach for this: Bootstrapping a host, applying pg_hba.conf changes, or recovering from a failed stop during maintenance.
# Inspect unit and environment
systemctl cat postgresql@18-main
systemctl show postgresql@18-main -p Environment -p ExecStart
# Graceful reload after config change
sudo systemctl reload postgresql@18-main
# Confirm reload picked up hba
sudo -u postgres psql -c "SELECT pg_reload_conf();"# Override fragment: /etc/systemd/system/postgresql@18-main.service.d/override.conf
[Service]
Environment=PGDATA=/data/pgdata
TimeoutStartSec=300
TimeoutStopSec=300sudo systemctl daemon-reload
sudo systemctl restart postgresql@18-mainWhat this demonstrates:
reload sends SIGHUP - applies pg_hba.conf and many GUCs without dropping connectionsdaemon-reload required after unit file editsTimeoutStopSec gives checkpoints time on large shared_buffers systems| Intent | systemd | pg_ctl |
|---|---|---|
| Start | systemctl start | pg_ctl start -D $PGDATA |
| Stop (fast) | systemctl stop | pg_ctl stop -m fast -D $PGDATA |
| Stop (immediate) | N/A (use pg_ctl) | pg_ctl stop -m immediate |
| Reload | systemctl reload | pg_ctl reload -D $PGDATA |
| Status | systemctl status | pg_ctl status -D $PGDATA |
| Restart | systemctl restart | pg_ctl restart -D $PGDATA |
# smart - wait for clients (default)
pg_ctl stop -D $PGDATA -m smart
# fast - rollback active transactions, disconnect clients
pg_ctl stop -D $PGDATA -m fast
# immediate - crash-like shutdown, recovery on next start
pg_ctl stop -D $PGDATA -m immediatesudo systemctl enable postgresql@18-main
sudo systemctl is-enabled postgresql@18-mainenable creates symlinks for multi-user.target.journalctl -u postgresql@18-main -f
journalctl -u postgresql@18-main --since "1 hour ago" -p errlog_directory in postgresql.conf for CSV/json file logs.shared_buffers changes need restart; reload silently keeps old value with pending_restart. Fix: SELECT name FROM pg_settings WHERE pending_restart;postgresql@18-main). Fix: systemctl cat and SHOW data_directory; must agree.TimeoutStopSec to 300s+ on large systems.sudo -u postgres pg_ctl ...| Alternative | Use When | Don't Use When |
|---|---|---|
| Patroni-managed unit | HA failover automation | Single-node dev laptop |
Docker docker compose restart | Containerized dev | You need journald integration |
pg_ctl only (no systemd) | BSD, manual tar installs | Standard Linux prod without init script |
Reload applies SIGHUP (hba, many GUCs). Restart stops and starts postmaster (required for shared_buffers, max_connections, etc.).
systemctl is-active postgresql@18-main or pg_isready -h localhost -p 5432.
systemctl stop (fast mode) quiesces writes. Verify no connections with pg_stat_activity before snapshot.
Use instance units (postgresql@18-main, postgresql@18-analytics) each with its own PGDATA.
Check journalctl -u postgresql@18-main -n 50. Often a typo in postgresql.conf - fix and start again.
Stack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, and PostGIS 3.5+.
Reviewed by Chris St. John·Last updated Jul 19, 2026