From 5b2272d229800c1f30e54abb4f72c004b479c705 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Mon, 26 Oct 2026 13:50:58 +0000
Subject: [PATCH v1 1/5] Update bulk-read buffer ring description in the buffer
 README

The buffer README still describes the bulk-read strategy as using a fixed
256kB ring.

Commit 15f0cb26b530 changed this but forgot to upate the README: the ring now
starts at 256kB and grows to accommodate the configured I/O concurrency, subject
to the backend pin limit and the general cap of one eighth of shared_buffers.

Update the README to describe the current sizing behavior.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by:
Discussion: https://postgr.es/m/
---
 src/backend/storage/buffer/README | 33 +++++++++++++++++++------------
 1 file changed, 20 insertions(+), 13 deletions(-)
 100.0% src/backend/storage/buffer/

diff --git a/src/backend/storage/buffer/README b/src/backend/storage/buffer/README
index b332e002ba1..3d233b53827 100644
--- a/src/backend/storage/buffer/README
+++ b/src/backend/storage/buffer/README
@@ -216,19 +216,26 @@ whole scan.  This also implies that much of the write traffic caused by such
 a statement will be done by the backend itself and not pushed off onto other
 processes.
 
-For sequential scans, a 256KB ring is used. That's small enough to fit in L2
-cache, which makes transferring pages from OS cache to shared buffer cache
-efficient.  Even less would often be enough, but the ring must be big enough
-to accommodate all pages in the scan that are pinned concurrently.  256KB
-should also be enough to leave a small cache trail for other backends to
-join in a synchronized seq scan.  If a ring buffer is dirtied and its LSN
-updated, we would normally have to write and flush WAL before we could
-re-use the buffer; in this case we instead discard the buffer from the ring
-and (later) choose a replacement using the normal clock-sweep algorithm.
-Hence this strategy works best for scans that are read-only (or at worst
-update hint bits).  In a scan that modifies every page in the scan, like a
-bulk UPDATE or DELETE, the buffers in the ring will always be dirtied and
-the ring strategy effectively degrades to the normal strategy.
+For bulk reads, a ring of at least 256KB is used. That's small enough to fit
+in L2 cache, which makes transferring pages from OS cache to shared buffer
+cache efficient.  Even less would often be enough, but the ring must be big
+enough to accommodate all pages in the scan that are pinned concurrently.
+This minimum should also be enough to leave a small cache trail for other
+backends to join in a synchronized seq scan.
+
+The ring is enlarged to accommodate io_combine_limit *
+effective_io_concurrency buffers while I/O is in progress, but no further
+than the backend's pin limit allows.  Like all strategy rings, its size is
+also capped at 1/8th of shared_buffers.
+
+If a ring buffer is dirtied and its LSN updated, we would normally have to
+write and flush WAL before we could re-use the buffer; in this case we instead
+discard the buffer from the ring and (later) choose a replacement using the
+normal clock-sweep algorithm.  Hence this strategy works best for scans that
+are read-only (or at worst update hint bits).  In a scan that modifies every
+page in the scan, like a bulk UPDATE or DELETE, the buffers in the ring will
+always be dirtied and the ring strategy effectively degrades to the normal
+strategy.
 
 VACUUM uses a ring like sequential scans, however, the size of this ring is
 controlled by the vacuum_buffer_usage_limit GUC.  Dirty pages are not removed
-- 
2.34.1

