How-To Reload PostgreSQL Config Without Restarting the DB

benchmark and performance test postgresql database

Short answer: pg_ctl -D /path/to/data reload, or from inside psql,
SELECT pg_reload_conf();. Both re-read postgresql.conf and
pg_hba.conf without dropping a single connection. Settings whose context is
postmastershared_buffers, max_connections,
wal_level — will not apply, and PostgreSQL will not warn you. Check
pg_settings.pending_restart to find out.

The -D is not optional

Most guides (this one included, until today) show pg_ctl reload with no data
directory. It fails:

$ pg_ctl reload
pg_ctl: no database directory specified and environment variable PGDATA unset
Try "pg_ctl --help" for more information.
$ echo $?
1

It only works if PGDATA happens to be exported in that shell — which it is for the
postgres system user on most packaged installs, and is not when you su into
a bare shell or run it from a script. Pass -D explicitly and it always works:

$ pg_ctl -D /opt/homebrew/var/postgresql@17 reload
server signaled
$ echo $?
0

Don’t know your data directory? Ask the server:

SHOW data_directory;
SHOW config_file;
SHOW hba_file;

Proof that a reload actually applies a setting

work_mem has context user, so it takes effect on reload:

postgres=# SHOW work_mem;
 work_mem
----------
 4MB

$ echo "work_mem = '8MB'" >> $PGDATA/postgresql.conf
$ pg_ctl -D $PGDATA reload
server signaled

postgres=# SHOW work_mem;
 work_mem
----------
 8MB

And proof that some settings silently don’t

This is the part that costs people an afternoon. shared_buffers has context
postmaster. Reload it and nothing happens — no error, no warning, no log entry:

postgres=# SHOW shared_buffers;
 shared_buffers
----------------
 128MB

$ echo "shared_buffers = '256MB'" >> $PGDATA/postgresql.conf
$ pg_ctl -D $PGDATA reload
server signaled

postgres=# SHOW shared_buffers;
 shared_buffers
----------------
 128MB          <-- unchanged

The server does record it, but only if you look:

postgres=# SELECT name, setting, pending_restart FROM pg_settings WHERE pending_restart;
      name      | setting | pending_restart
----------------+---------+-----------------
 shared_buffers | 16384   | t
(1 row)

Make this your habit: after every reload, run that query. If it returns rows, your
change is sitting in the config file doing nothing until the next restart.

Which settings need a restart?

There are 65 of them in PostgreSQL 17.10. Don’t memorise the list — query it.
context = 'postmaster' means restart required:

SELECT name, context, short_desc
FROM pg_settings
WHERE context = 'postmaster'
ORDER BY name;

The other contexts you’ll meet: sighup (applies on reload),
superuser and user (settable per-session), backend (fixed when
a connection starts), and internal (compile-time, not changeable at all).

The three ways to reload, and when each is right

MethodCommandUse when
pg_ctlpg_ctl -D $PGDATA reloadYou have shell access as the postgres user. Works on any install.
SQLSELECT pg_reload_conf();You’re already in psql, or you only have SQL access (managed/cloud PG). Returns t on success.
systemdsudo systemctl reload postgresql@17-mainPackaged Linux installs. Note the versioned unit name — plain postgresql is a wrapper and may not forward the reload.

Checking the logs

The log path is not /var/log/postgresql/postgresql.log on most systems. Find yours:

SHOW log_directory;
SHOW log_filename;

Debian/Ubuntu packages write to /var/log/postgresql/postgresql-17-main.log; Homebrew
writes wherever you pointed -l at start time; RHEL-family defaults to
$PGDATA/log/. A successful reload logs
received SIGHUP, reloading configuration files.


Verified 2026-08-09 on PostgreSQL 17.10 (Homebrew), aarch64-apple-darwin25.6.0.
Every command above was executed on a scratch cluster and the output pasted unedited — including the
failure in the first example. You can reproduce all of it in about 30 seconds with
this script, which creates a throwaway cluster on
port 55432 and tears it down afterwards.

Photo of author
Sudhir P. founded HeatWare.com in 1999 and has built and operated it full-stack ever since; it is now used by more than 88,000 people. He writes here about the PostgreSQL, MySQL, Linux and DevOps work that keeps it running. Articles are rewritten only after the commands in them have actually been run, and the verification scripts are published alongside them so anyone can check the claims. Reach him at blog@heatware.net.