Обсуждение: Postgres Parameters
On Mon, Nov 10, 2025 at 6:28 PM Sam Stearns <sam.stearns@dat.com> wrote:
Howdy,Could someone advise on how to determine the correct settings for the following, please?:
- checkpoint_timeout
- max_wal_size
https://postgresqlco.nf/doc/en/param/ is a great web site.
How busy are your systems?
I sometimes set max_wal_size to be 6GB or 12GB, and sometimes the default. As https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-MAX-WAL-SIZE says, "This is a soft limit; WAL size can exceed max_wal_size under special circumstances, such as heavy load". Leave it at the default, and then search the log files for complaints about checkpointing too often. No complaints? Leave at the default. Complaints? Bump it up.
My standard checkpoint_timeout is 15 minutes, for Unremembered Reasons. Things work, so I have no need to change.
If the disk with our WAL files crashes (not very likely), we probably lose at most 15 minutes of data.
When doing a multi-TB pg_restore to an empty database, I bump checkpoint_time to 30m and max_wal_size to 32GB (and use dangerous settings like fsync=off).
Death to <Redacted>, and butter sauce.
Don't boil me, I'm still alive.
<Redacted> lobster!
On Mon, 2025-11-10 at 15:28 -0800, Sam Stearns wrote: > Could someone advise on how to determine the correct settings for the following, please?: > > * checkpoint_timeout > * max_wal_size Leave "checkpoint_timeout" as it is, and increase "max_wal_size" to 10GB. Wait, and if pg_stat_checkpointer tells you that many checkpoints are *not* triggered by timeout, increase "max_wal_size". Yours, Laurenz Albe
Hi,
You could also use this query, if the ratio is low, that means there is no pressure on wal size and you can keep the max_wal_size value as it is.
SELECT
num_timed,
num_requested,
round((num_requested::numeric / NULLIF(num_timed + num_requested, 0)) * 100, 2)
AS requested_pct
FROM pg_stat_checkpointer;
+-----------+---------------+---------------+
| num_timed | num_requested | requested_pct |
+-----------+---------------+---------------+
| 3502 | 146 | 4.00 |
+-----------+---------------+---------------+
(1 row)
Regards,
Fabrice
On Tue, Nov 11, 2025 at 12:28 AM Sam Stearns <sam.stearns@dat.com> wrote:
Awesome stuff. Thank you, everyone!
Sam
On Tue, Nov 11, 2025 at 3:19 AM Fabrice Chapuis <fabrice636861@gmail.com> wrote:
Hi, You could also use this query, if the ratio is low, that means there is no pressure on wal size and you can keep the max_wal_size value as it is. SELECT num_timed, num_requested, round((num_requested: : numeric / NULLIF(num_timed + num_requested,ZjQcmQRYFpfptBannerStartThis Message Is From an Untrusted SenderYou have not previously corresponded with this sender.ZjQcmQRYFpfptBannerEndHi,You could also use this query, if the ratio is low, that means there is no pressure on wal size and you can keep the max_wal_size value as it is.SELECTnum_timed,num_requested,round((num_requested::numeric / NULLIF(num_timed + num_requested, 0)) * 100, 2)AS requested_pctFROM pg_stat_checkpointer;+-----------+---------------+---------------+| num_timed | num_requested | requested_pct |+-----------+---------------+---------------+| 3502 | 146 | 4.00 |+-----------+---------------+---------------+(1 row)Regards,FabriceOn Tue, Nov 11, 2025 at 12:28 AM Sam Stearns <sam.stearns@dat.com> wrote:
I found that PostgreSQL 15.3 doesn't support the
pg_stat_checkpointer view. We can use pg_stat_bgwriter instead. The SQL is as follows:SELECT checkpoints_timed AS num_timed, -- Checkpoints triggered by timeout checkpoints_req AS num_requested, -- Checkpoints triggered by requests (like when WAL space is tight) round( (checkpoints_req::numeric / NULLIF(checkpoints_timed + checkpoints_req, 0)) * 100, 2 ) AS requested_pct -- % of checkpoints that were request-triggered
FROM pg_stat_bgwriter;Awesome stuff. Thank you, everyone!SamOn Tue, Nov 11, 2025 at 3:19 AM Fabrice Chapuis <fabrice636861@gmail.com> wrote:Hi, You could also use this query, if the ratio is low, that means there is no pressure on wal size and you can keep the max_wal_size value as it is. SELECT num_timed, num_requested, round((num_requested: : numeric / NULLIF(num_timed + num_requested,ZjQcmQRYFpfptBannerStartThis Message Is From an Untrusted SenderYou have not previously corresponded with this sender.ZjQcmQRYFpfptBannerEndHi,You could also use this query, if the ratio is low, that means there is no pressure on wal size and you can keep the max_wal_size value as it is.SELECTnum_timed,num_requested,round((num_requested::numeric / NULLIF(num_timed + num_requested, 0)) * 100, 2)AS requested_pctFROM pg_stat_checkpointer;+-----------+---------------+---------------+| num_timed | num_requested | requested_pct |+-----------+---------------+---------------+| 3502 | 146 | 4.00 |+-----------+---------------+---------------+(1 row)Regards,FabriceOn Tue, Nov 11, 2025 at 12:28 AM Sam Stearns <sam.stearns@dat.com> wrote:--
Thank you, Zhenwei.
I found that PostgreSQL 15. 3 doesn't support the pg_stat_checkpointer view. We can use pg_stat_bgwriter instead. The SQL is as follows: SELECT checkpoints_timed AS num_timed, -- Checkpoints triggered by timeout checkpoints_req AS num_requested,ZjQcmQRYFpfptBannerStartThis Message Is From an Untrusted SenderYou have not previously corresponded with this sender.ZjQcmQRYFpfptBannerEndI found that PostgreSQL 15.3 doesn't support thepg_stat_checkpointerview. We can usepg_stat_bgwriterinstead. The SQL is as follows:SELECT checkpoints_timed AS num_timed, -- Checkpoints triggered by timeout checkpoints_req AS num_requested, -- Checkpoints triggered by requests (like when WAL space is tight) round( (checkpoints_req::numeric / NULLIF(checkpoints_timed + checkpoints_req, 0)) * 100, 2 ) AS requested_pct -- % of checkpoints that were request-triggered FROM pg_stat_bgwriter;Awesome stuff. Thank you, everyone!SamOn Tue, Nov 11, 2025 at 3:19 AM Fabrice Chapuis <fabrice636861@gmail.com> wrote:Hi, You could also use this query, if the ratio is low, that means there is no pressure on wal size and you can keep the max_wal_size value as it is. SELECT num_timed, num_requested, round((num_requested: : numeric / NULLIF(num_timed + num_requested,ZjQcmQRYFpfptBannerStartThis Message Is From an Untrusted SenderYou have not previously corresponded with this sender.ZjQcmQRYFpfptBannerEndHi,You could also use this query, if the ratio is low, that means there is no pressure on wal size and you can keep the max_wal_size value as it is.SELECTnum_timed,num_requested,round((num_requested::numeric / NULLIF(num_timed + num_requested, 0)) * 100, 2)AS requested_pctFROM pg_stat_checkpointer;+-----------+---------------+---------------+| num_timed | num_requested | requested_pct |+-----------+---------------+---------------+| 3502 | 146 | 4.00 |+-----------+---------------+---------------+(1 row)Regards,FabriceOn Tue, Nov 11, 2025 at 12:28 AM Sam Stearns <sam.stearns@dat.com> wrote:--