Here's a v5, with mostly minor changes compared to v4.

The main change is that it prefers zstd over lz4, per the discussion
about benchmark results. This is what v3 did.

I did not like the DEFAULT_WAL_COMPRESSION name, because that seems to
imply default for the wal_compression GUC. Which is misleading. I've
renamed it to WAL_COMPRESSION_ON.

Updated/reworded the commit message a bit. Feel free to suggest
adjustments. I've included only two people as reviewers - there's been a
lot of discussion about what "on" should mean, but I don't think that
counts as reviews.


regards

-- 
Tomas Vondra
From 0f1af038dea6beff4197b5d17d4152ed35eb7498 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <[email protected]>
Date: Sun, 9 Aug 2026 14:52:19 +0200
Subject: [PATCH v5] Change wal_compression=on to the first of zstd, lz4, pglz

Previously, wal_compression=on was an alias for pglz, with the
assummption that users could make an informed choice to pick a better
option. But in practice, users rarely got to that second step.

Many users don't want to be choosing algorithms - they just want WAL
compression, and expect that to work well. The configuration parameter
is set by an administrator, who does not control the workload, and so is
not in a position to evaluate the options anyway. And finally, the
algorithms make different trade offs between speed and compression
ratio, and there's no obvious best choice.

In fact, some users may not even realize there are other options, as
previously "on" was the only choice available.

This change maps "on" to non-pglz options, supported by the build. Both
lz4 and zstd are faster, and achieve comparable (or better) compression
ratio. We prefer zstd over lz4 - per our testing the better compression
ratio pays for the lower (de)compression speed.

Like for TOAST compression, the value depends on algorithms supported by
the PostgreSQL build, with lz4 and zstd being optional. But most builds
will have at least one of these external libraries. If neither zstd or
lz4 is supported, we fallback to pglz.

This only affects what "on" means. Users can still make the informed
choice and explicitly select a compression algorithm if it works better
for their system. The default value for "wal_compression" remains "off."

Initial proposal and patch by wenhui qiu, reviews and patch adjustments
by Christoph Berg. A number of other people participated in the
discussion. Benchmarks by me.

Backpatch to 19.

Author: wenhui qiu <[email protected]>
Reviewed-by: Christoph Berg <[email protected]>
Reviewed-by: Michael Paquier <[email protected]>
Discussion: https://postgr.es/m/CAGjGUAL1b=Mwd1SCvLbo+fivEr9KDpFcu4jmqKCZXwT=6ci...@mail.gmail.com
Backpatch-through: 19
---
 doc/src/sgml/config.sgml                      | 12 ++++++------
 src/backend/utils/misc/guc_tables.c           |  8 ++++----
 src/backend/utils/misc/postgresql.conf.sample |  3 ++-
 src/include/access/xlog.h                     | 13 +++++++++++++
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 236ee067f40..3ca1bdac81d 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -3667,12 +3667,12 @@ include_dir 'conf.d'
         <xref linkend="guc-full-page-writes"/> is on, during a base backup,
         etc.).
         A compressed page image will be decompressed during WAL replay.
-        The supported methods are <literal>pglz</literal>,
-        <literal>lz4</literal> (if <productname>PostgreSQL</productname>
-        was compiled with <option>--with-lz4</option>) and
-        <literal>zstd</literal> (if <productname>PostgreSQL</productname>
-        was compiled with <option>--with-zstd</option>).
-        The value <literal>on</literal> is a historical spelling of <literal>pglz</literal>.
+        The supported methods are <literal>off</literal>, <literal>on</literal>,
+        <literal>lz4</literal> (if <productname>PostgreSQL</productname> was compiled with <option>--with-lz4</option>),
+        <literal>zstd</literal> (if <productname>PostgreSQL</productname> was compiled with <option>--with-zstd</option>), and
+        <literal>pglz</literal>.
+        The value <literal>on</literal> selects the first of <literal>zstd</literal>,
+        <literal>lz4</literal>, <literal>pglz</literal> that is available.
         The default value is <literal>off</literal>.
         Only superusers and users with the appropriate <literal>SET</literal>
         privilege can change this setting.
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 1ec460b6a82..afd50e80f92 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -484,13 +484,13 @@ static const struct config_enum_entry wal_compression_options[] = {
 #ifdef USE_ZSTD
 	{"zstd", WAL_COMPRESSION_ZSTD, false},
 #endif
-	{"on", WAL_COMPRESSION_PGLZ, false},
+	{"on", WAL_COMPRESSION_ON, false},
 	{"off", WAL_COMPRESSION_NONE, false},
-	{"true", WAL_COMPRESSION_PGLZ, true},
+	{"true", WAL_COMPRESSION_ON, true},
 	{"false", WAL_COMPRESSION_NONE, true},
-	{"yes", WAL_COMPRESSION_PGLZ, true},
+	{"yes", WAL_COMPRESSION_ON, true},
 	{"no", WAL_COMPRESSION_NONE, true},
-	{"1", WAL_COMPRESSION_PGLZ, true},
+	{"1", WAL_COMPRESSION_ON, true},
 	{"0", WAL_COMPRESSION_NONE, true},
 	{NULL, 0, false}
 };
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 493f57409e1..b536823bf25 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -262,7 +262,8 @@
 #wal_log_hints = off                    # also do full page writes of non-critical updates
                                         # (change requires restart)
 #wal_compression = off                  # enables compression of full-page writes;
-                                        # off, pglz (or "on"), lz4, or zstd
+                                        # off, on, lz4, zstd, or pglz (on means the first
+                                        # of zstd, lz4 and pglz, supported by the build)
 #wal_init_zero = on                     # zero-fill new WAL files
 #wal_recycle = on                       # recycle WAL files
 #wal_buffers = -1                       # min 32kB, -1 sets based on shared_buffers
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 4dd98624204..338d68d7424 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -87,6 +87,19 @@ typedef enum WalCompression
 	WAL_COMPRESSION_ZSTD,
 } WalCompression;
 
+/*
+ * Choose an appropriate default WAL compression method for wal_compression=on.
+ * Prefer zstd when compiled in; otherwise use lz4 if available, falling back
+ * to pglz.
+ */
+#if defined(USE_ZSTD)
+#define WAL_COMPRESSION_ON	WAL_COMPRESSION_ZSTD
+#elif defined(USE_LZ4)
+#define WAL_COMPRESSION_ON	WAL_COMPRESSION_LZ4
+#else
+#define WAL_COMPRESSION_ON	WAL_COMPRESSION_PGLZ
+#endif
+
 /* Recovery states */
 typedef enum RecoveryState
 {
-- 
2.55.0

Reply via email to