On 9th of February 2026, Álvaro Herrera committed patch:
Allow log_min_messages to be set per process type Change log_min_messages from being a single element to a comma-separated list of type:level elements, with 'type' representing a process type, and 'level' being a log level to use for that type of process. The list must also have a freestanding level specification which is used for process types not listed, which convenientely makes the whole thing backwards-compatible. Some choices made here could be contested; for instance, we use the process type `backend` to affect regular backends as well as dead-end backends and the standalone backend, and `autovacuum` means both the launcher and the workers. I think it's largely sensible though, and it can easily be tweaked if desired. Author: Euler Taveira <euler@eulerto.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Japin Li <japinli@hotmail.com> Reviewed-by: Tan Yang <332696245@qq.com> Discussion: https://postgr.es/m/e85c6671-1600-4112-8887-f97a8a5d07b2@app.fastmail.com
I don't think that this change will see much use outside of PostgreSQL developers, but it's interesting nonetheless.
In PostgreSQL, we have setting log_min_messages, which could take one of these values:
- DEBUG5
- DEBUG4
- DEBUG3
- DEBUG2
- DEBUG1
- INFO
- NOTICE
- WARNING
- ERROR
- LOG
- FATAL
- PANIC
The earlier the level, the more logs it generates. Generally, most people don't really care about much stuff before WARNING, and even NOTICE isn't really super useful in normal cases. That's why default is WARNING.
This new change allows us to set messages level per backend type. What that means? For example, if I see weird behavior from archiver, I can make it so that archiver, and only archiver, will be on DEBUG5. Or perhaps background workers. Or …?
It seems that our set of backend types is:
- archiver – handles archiving or wal segments – calling either archive_command, or working with archive_library.
- autovacuum – all things related to autovacuum, timer to or check workers that vacuum or analyze
- backend – process handling client queries
- bgworker – various background workers, described in detail in docs
- bgwriter – process that writes data to datafiles, and is supposedly doing (ideally) all of the work, though it doesn't handle checkpoints, plus normal backends still can write too
- checkpointer – handles writes to data files that happens on checkpoint
- ioworker – processes handling parallelization of IO, new thing in Pg18.
- postmaster – main process, listening for new connections, and responsible for spawning other processes.
- syslogger – handles writing to logs, as in text logs, json, csv, or to syslog.
- slotsyncworker – is responsible fro managing synchronizing slots for logical replication. I'm kinda fuzzy on details, but you can find more info in sources
- startup – loads wal, and applies – either on system startup, or, in case of wal-file based replication – on every restored wal file.
- walreceiver – connects to primary server, and loads WAL from there using streaming replication
- walsender – runs on primary server in streaming replication scenario and provides WAL to replicas
- walsummarizer – generates WAL summary files, if you enabled summarize_wal option.
- walwriter – writes WAL records to wal files, whenever it's needed.
That's a lot of different settings.
Long story short, now we can set different log levels for each of the processes. For example, to keep default of WARNING, but have autovacuum output all of the debug information we set:
log_min_messages = 'warning,autovacuum:debug5'
To show you what it means, here is a bit of data from autovacuum, ran every minute on my test system (1 minute because of autovacuum_naptime):
2026-02-21 16:02:08.053 CET @ 1316663 DEBUG: InitPostgres 2026-02-21 16:02:08.053 CET @ 1316663 DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGRESS, xid/subid/cid: 0/1/0 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: CommitTransaction(1) name: unnamed; blockState: STARTED; state: INPROGRESS, xid/subid/cid: 0/1/0 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: autovacuum: processing database "template0" 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGRESS, xid/subid/cid: 0/1/0 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_authid: vac: 3 (threshold 53), ins: 2 (threshold 1000), anl: 5 (threshold 52) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_subscription: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_attribute: vac: 0 (threshold 691), ins: 0 (threshold 1000), anl: 0 (threshold 371) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_class: vac: 0 (threshold 133), ins: 0 (threshold 1000), anl: 0 (threshold 92) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_index: vac: 0 (threshold 83), ins: 0 (threshold 1000), anl: 0 (threshold 66) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_opclass: vac: 0 (threshold 86), ins: 0 (threshold 1000), anl: 0 (threshold 68) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_am: vac: 0 (threshold 51), ins: 0 (threshold 1000), anl: 0 (threshold 51) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_amproc: vac: 0 (threshold 194), ins: 0 (threshold 1000), anl: 0 (threshold 122) 2026-02-21 16:02:08.054 CET @ 1316663 DEBUG: pg_database: vac: 7 (threshold 50), ins: 6 (threshold 1000), anl: 13 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_db_role_setting: vac: 0 (threshold 50), ins: 1 (threshold 1000), anl: 1 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_tablespace: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_auth_members: vac: 0 (threshold 51), ins: 3 (threshold 1000), anl: 3 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_shdepend: vac: 4 (threshold 50), ins: 89 (threshold 1000), anl: 26 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_shdescription: vac: 0 (threshold 50), ins: 2 (threshold 1000), anl: 2 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_replication_origin: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_shseclabel: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_parameter_acl: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_toast_1262: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_toast_2964: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_toast_1213: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_toast_2396: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_toast_3592: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_toast_6243: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: pg_toast_6100: vac: 0 (threshold 50), ins: 0 (threshold 1000), anl: 0 (threshold 50) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: CommitTransaction(1) name: unnamed; blockState: STARTED; state: INPROGRESS, xid/subid/cid: 0/1/0 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: shmem_exit(0): 5 before_shmem_exit callbacks to make 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: shmem_exit(0): 8 on_shmem_exit callbacks to make 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: proc_exit(0): 1 callbacks to make 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: exit(0) 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: shmem_exit(-1): 0 before_shmem_exit callbacks to make 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: shmem_exit(-1): 0 on_shmem_exit callbacks to make 2026-02-21 16:02:08.055 CET @ 1316663 DEBUG: proc_exit(-1): 0 callbacks to make 2026-02-21 16:02:08.056 CET @ 1199940 DEBUG: autovacuum worker (PID 1316663) exited with exit code 0
I'm not sure which DEBUG these actually are, but I had it set to DEBUG5, so it should be all that there is 🙂
Anyway – I don't think this change will be broadly used, though it can provide answer to question like: why didn't autovacuum vacuum (or analyze) this table 🙂
Regardless, it will make life of developers easier, so it's a great thing. Thanks to everyone involved.