From 63279ec5776d292ce3bde860ec987726a775dca9 Mon Sep 17 00:00:00 2001
From: Andrew Pogrebnoi <absourd.noise@gmail.com>
Date: Fri, 13 Feb 2026 16:14:45 +0200
Subject: [PATCH v2 1/2] Change default wal_blocksize to 4KB

With the current 8KB default, we do more flushes of partially written
buffers, which significantly increases the number of disk writes
compared to 4KB XLOG_BLCKSZ. 4KB pages result in more overhead for
headers, but it is small in comarison with the actual WAL data (~0.29%
of space is headers with 8KB pages, and 0.59% with 4KB).

See more on justification and benchmarks:
https://www.postgresql.org/message-id/20231009230805.funj5ipoggjyzjz6%40awork3.anarazel.de
---
 configure                      | 4 ++--
 configure.ac                   | 4 ++--
 doc/src/sgml/config.sgml       | 6 +++---
 doc/src/sgml/installation.sgml | 4 ++--
 doc/src/sgml/wal.sgml          | 2 +-
 meson_options.txt              | 2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/configure b/configure
index ba293931878..06b50b61d25 100755
--- a/configure
+++ b/configure
@@ -1574,7 +1574,7 @@ Optional Packages:
   --with-segsize-blocks=SEGSIZE_BLOCKS
                           set table segment size in blocks [0]
   --with-wal-blocksize=BLOCKSIZE
-                          set WAL block size in kB [8]
+                          set WAL block size in kB [4]
   --with-llvm             build with LLVM based JIT support
   --without-icu           build without ICU support
   --with-tcl              build Tcl modules (PL/Tcl)
@@ -3840,7 +3840,7 @@ if test "${with_wal_blocksize+set}" = set; then :
   esac
 
 else
-  wal_blocksize=8
+  wal_blocksize=4
 fi
 
 
diff --git a/configure.ac b/configure.ac
index 412fe358a2f..59678a7dd99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -324,9 +324,9 @@ AC_DEFINE_UNQUOTED([RELSEG_SIZE], ${RELSEG_SIZE}, [
 # WAL block size
 #
 AC_MSG_CHECKING([for WAL block size])
-PGAC_ARG_REQ(with, wal-blocksize, [BLOCKSIZE], [set WAL block size in kB [8]],
+PGAC_ARG_REQ(with, wal-blocksize, [BLOCKSIZE], [set WAL block size in kB [4]],
              [wal_blocksize=$withval],
-             [wal_blocksize=8])
+             [wal_blocksize=4])
 case ${wal_blocksize} in
   1) XLOG_BLCKSZ=1024;;
   2) XLOG_BLCKSZ=2048;;
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index f1af1505cf3..f06de24bd04 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -3536,7 +3536,7 @@ include_dir 'conf.d'
         but any positive value less than <literal>32kB</literal> will be
         treated as <literal>32kB</literal>.
         If this value is specified without units, it is taken as WAL blocks,
-        that is <symbol>XLOG_BLCKSZ</symbol> bytes, typically 8kB.
+        that is <symbol>XLOG_BLCKSZ</symbol> bytes, typically 4kB.
         This parameter can only be set at server start.
        </para>
 
@@ -3596,7 +3596,7 @@ include_dir 'conf.d'
         flushed to disk.  If <varname>wal_writer_flush_after</varname> is set
         to <literal>0</literal> then WAL data is always flushed immediately.
         If this value is specified without units, it is taken as WAL blocks,
-        that is <symbol>XLOG_BLCKSZ</symbol> bytes, typically 8kB.
+        that is <symbol>XLOG_BLCKSZ</symbol> bytes, typically 4kB.
         The default is <literal>1MB</literal>.
         This parameter can only be set in the
         <filename>postgresql.conf</filename> file or on the server command line.
@@ -12146,7 +12146,7 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir'
        <para>
         Reports the size of a WAL disk block.  It is determined by the value
         of <literal>XLOG_BLCKSZ</literal> when building the server. The default value
-        is 8192 bytes.
+        is 4096 bytes.
        </para>
       </listitem>
      </varlistentry>
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index c903ccff988..6f3409406db 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1520,7 +1520,7 @@ build-postgresql:
        <listitem>
         <para>
          Set the <firstterm>WAL block size</firstterm>, in kilobytes.  This is the unit
-         of storage and I/O within the WAL log.  The default, 8 kilobytes,
+         of storage and I/O within the WAL log.  The default, 4 kilobytes,
          is suitable for most situations; but other values may be useful
          in special cases.
          The value must be a power of 2 between 1 and 64 (kilobytes).
@@ -3047,7 +3047,7 @@ ninja install
       <listitem>
        <para>
         Set the <firstterm>WAL block size</firstterm>, in kilobytes.  This is the unit
-        of storage and I/O within the WAL log.  The default, 8 kilobytes,
+        of storage and I/O within the WAL log.  The default, 4 kilobytes,
         is suitable for most situations; but other values may be useful
         in special cases.
         The value must be a power of 2 between 1 and 64 (kilobytes).
diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml
index f3b86b26be9..731b8b6c6f0 100644
--- a/doc/src/sgml/wal.sgml
+++ b/doc/src/sgml/wal.sgml
@@ -881,7 +881,7 @@
    <filename>pg_wal</filename> under the data directory, as a set of
    segment files, normally each 16 MB in size (but the size can be changed
    by altering the <option>--wal-segsize</option> <application>initdb</application> option).  Each segment is
-   divided into pages, normally 8 kB each (this size can be changed via the
+   divided into pages, normally 4 kB each (this size can be changed via the
    <option>--with-wal-blocksize</option> configure option).  The WAL record headers
    are described in <filename>access/xlogrecord.h</filename>; the record
    content is dependent on the type of event that is being logged.  Segment
diff --git a/meson_options.txt b/meson_options.txt
index 6a793f3e479..22d936973d8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -9,7 +9,7 @@ option('blocksize', type: 'combo',
 
 option('wal_blocksize', type: 'combo',
   choices: ['1', '2', '4', '8', '16', '32', '64'],
-  value: '8',
+  value: '4',
   description: 'WAL block size, in kilobytes')
 
 option('segsize', type: 'integer', value: 1,
-- 
2.43.0

