Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w6uvd-004mPh-1G for pgsql-hackers@arkaria.postgresql.org; Sun, 29 Mar 2026 18:32:05 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w6uvb-00GvU0-2v for pgsql-hackers@arkaria.postgresql.org; Sun, 29 Mar 2026 18:32:04 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w6uvb-00GvTr-1K for pgsql-hackers@lists.postgresql.org; Sun, 29 Mar 2026 18:32:04 +0000 Received: from mail-ua1-x92c.google.com ([2607:f8b0:4864:20::92c]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w6uvZ-00000001gKZ-2kGu for pgsql-hackers@lists.postgresql.org; Sun, 29 Mar 2026 18:32:02 +0000 Received: by mail-ua1-x92c.google.com with SMTP id a1e0cc1a2514c-953b9fd8ebdso302733241.1 for ; Sun, 29 Mar 2026 11:32:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1774809121; cv=none; d=google.com; s=arc-20240605; b=b1IVU0i+lrsY+b+3Lq+H+ULkGJZ1qT2CG/73goNX1Bmthz3JUsbn5QaSD0/1j4pr45 EOlt9ptpyIJMsCjrvLF1fJ2JQf22q2JSiYGNUDIx0CL5u1R4I1cEdm4EO1lWHiCg6cJc +yBeCtRCvydgMD4G5KT3SA9a0gZmmf4h5vZVR+mnOsqy5rdwgWA0DkHPWHmojGdwf4E/ LOj7NZzBk0lKmLByLiddMZd3sDvj7bAZlfEl6upe5gdMxCmpMkWIogL+3lahgSz2U0Ge 7n+Oui6cMeG8Wl7ez2JD/SaBIhr0XYX7h7WQsWsNd4spumOI1Sd45mmf70GBc6VutRnT BNGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=M9sJo+0Kbe2PKxdFALzn55W0PNR2dPXPbXtfDGHLfCI=; fh=eGhD8NE58EmIgD6b+gPO+CvU80MO/Q+yy1QKus3+4M4=; b=hGxAQo7bl69Q+BO0UIdZKM0W/kMtrurtymZMUZ73Tg5QbfoSUk8+n6N0q7PFMjJyKg ISwbk8NrqLwlr+wY0SJJKvRzOZYNhVArwtnJwKOOxzFvUPMu5KKdXTE0rr8MlUyoEOMu dE/1iB6NgktNugPdlN56XkR/h2UE9gBg5ogvGw5gCuKj7eEAQT94QmsKHR9bG6kgQ+a1 /qL1NU5sC0/+zpXA5vmVGeH+la779dERTSPFzuKMTCnQXDnwM/ELdsxXEp/zMsnoiFRy 7TCFwsi40oPCNZkstGFtuId1z3vvBbMMutOdELJZvRCY8NVw6FUSDqx5Jihn28S0FPtN Op7A==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774809121; x=1775413921; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=M9sJo+0Kbe2PKxdFALzn55W0PNR2dPXPbXtfDGHLfCI=; b=dA6VDG/dgSp1arW0QEHTDXzgHQQJDGiS+jJq1zL962uiuSIvOWjjClqfUaCvlY9OYk Edq0BCRetA2qzbGA0aLVwmygpaZgyT1xu3p0CqXffnE6l+k2MpZJ94QgI4KQc+Xw06zS lN98+JsC/MNkVIkLKBsUYWM/PLz45H0uJUkJsXMjHaIgmPMzIOYc9AwKAgYYAsdQFWOf amX6oDbSelDOps4ulV51yjgs2OynvtMfphpKQBhFcIGoBRdy0UqYZOXssFbk2bG/uyWX U5wkKhUhrifapt+puiAaXkBKL3lq35AROTDto1GwYTR9I3hB7p9PlredzPPxIO3oxy2L uPqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774809121; x=1775413921; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=M9sJo+0Kbe2PKxdFALzn55W0PNR2dPXPbXtfDGHLfCI=; b=ggt20O4fODzxGx53QL9CiqeUsmJlevyx4EdgGSf2HNcM6wawHCuTZc80QOId4S25Xw CHyisA7B1fbeGsc3tph8N0nmjUOurETJppTKdWFk6Eok8Y6TJp9xp0B+G4GJDA0YQkTM A5Fpp4YRfqmxPRvIiMw6wYYDFEv1YE+JOvd4Hp9/oT+ajePMonZ6Pf9TvJkXJRGHwsTX KupqLjydwtu2MR+wvz1Z0s/XOP95NMhB/iZ6CgbPfHayTUaKzid7lt1OrkKbVSYKj6Cz 2muRXy5UAhl7TI5yt1UxSJf86N682uUy0guiZxzTNDfI8yEDw7jFhJGUngNtkKVptP+n qxfA== X-Gm-Message-State: AOJu0Yw3TxqZtMlIMMy+XQjZDu+YhlQnvw7ZkFa2OGL3G5qME35ue3tZ gXBfqv1NbWFxsazElgQMZNdi5V9G3DPobArNZXxiS7jJaG5ljXpL5YzgaqZcm1Zsaezqv9h4h/l wNaiDugkBZr4O9a38Y/jytfsRSPwCVKvlldSL X-Gm-Gg: ATEYQzwDbJO5T2XwN7j/AeHqfd1u0qWH0wGrwqWJfefryYEqhnCNF8X2hEdoZNjVe7e l69+nCxgk8gaBvONL6KFZ6HPPm65zysR0DmIMH8Ev0D4ro5yDKd4a2rnc+pTuCQyBFY8h62QY6u 0QFXAQj/+G68nUl7IR2i4iogB8A40S9DIxlbbT0u7VDMcRhdKhQ+CNU/NYLOo4S4KWvptAqfzRU eNqW3zR9OpVPFqh2OBFsGFUVhsOb/NvaOPfQcqB0zbAoo9pO21YAtUSK4Qg94ckHR3NgItMWs31 oZxJh4U= X-Received: by 2002:a05:6102:4a91:b0:602:813c:1b24 with SMTP id ada2fe7eead31-604f903dd83mr4131634137.7.1774809120761; Sun, 29 Mar 2026 11:32:00 -0700 (PDT) MIME-Version: 1.0 References: <126eb1e4-d98e-4647-b629-517adbcad28e@uni-muenster.de> In-Reply-To: <126eb1e4-d98e-4647-b629-517adbcad28e@uni-muenster.de> From: SATYANARAYANA NARLAPURAM Date: Sun, 29 Mar 2026 11:31:49 -0700 X-Gm-Features: AQROBzCupZMXpq25K4i1hZe2e5roX16I0cSPW-UFjCK9mqB6WwkAfbQYrJ1Nk7s Message-ID: Subject: Re: Add max_wal_replay_size connection parameter to libpq To: Jim Jones Cc: PostgreSQL Hackers Content-Type: multipart/alternative; boundary="0000000000002fea6b064e2df36e" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000002fea6b064e2df36e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Jim, On Sun, Mar 29, 2026 at 10:56=E2=80=AFAM Jim Jones wrote: > Hi, > > When connecting with target_session_attrs=3Dstandby (or prefer-standby, > read-only, any) and multiple standbys are available, libpq currently > selects the first acceptable candidate without regard for how "current" > its data is. A standby configured with recovery_min_apply_delay, > experiencing slow I/O, or otherwise lagging is treated the same as one > that is fully caught up. > > I would like to propose a new libpq connection parameter, > max_wal_replay_size, that allows clients to skip standby servers whose > WAL replay backlog exceeds a given threshold. > > Example: > > psql "host=3Dhost1,host2,host3 port=3D5111,5222,5333 \ > target_session_attrs=3Dstandby max_wal_replay_size=3D16MB" > > When this parameter is set, libpq executes a small query during > connection establishment to evaluate: > > pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn()) > > on the standby. If the result exceeds the specified threshold, the > server is skipped and the next host in the list is tried. The check is > skipped entirely when target_session_attrs is set to primary or > read-write, since those modes already exclude standbys. > What if none of them meets the criteria? You fail the connection? Wouldn't it cause an availability issue? > > If pg_last_wal_receive_lsn() is NULL (e.g. no active WAL receiver due to > missing primary_conninfo or a disconnected upstream), the backlog cannot > be determined. In that case, the standby is treated as exceeding the > threshold and is skipped. > When a standby is replaying archiving log, it can still be caught up. This doesn't seem right to me. > > This parameter measures only the apply lag on the standby itself, i.e., > how much already-received WAL remains to be replayed. It does not > attempt to measure how far the standby is behind the primary. In > particular, a standby that is slow to receive WAL but fast to replay it > may report a small backlog here while still being significantly behind. > IMHO, this change appears to not meet the objective of routing connections/queries to the most up-to-date standby. Thanks, Satya --0000000000002fea6b064e2df36e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi=C2=A0Jim,

On Sun,= Mar 29, 2026 at 10:56=E2=80=AFAM Jim Jones <jim.jones@uni-muenster.de> wrote:
Hi,

When connecting with target_session_attrs=3Dstandby (or prefer-standby,
read-only, any) and multiple standbys are available, libpq currently
selects the first acceptable candidate without regard for how "current= "
its data is. A standby configured with recovery_min_apply_delay,
experiencing slow I/O, or otherwise lagging is treated the same as one
that is fully caught up.

I would like to propose a new libpq connection parameter,
max_wal_replay_size, that allows clients to skip standby servers whose
WAL replay backlog exceeds a given threshold.

Example:

=C2=A0 psql "host=3Dhost1,host2,host3 port=3D5111,5222,5333 \
=C2=A0 =C2=A0 =C2=A0 =C2=A0 target_session_attrs=3Dstandby max_wal_replay_s= ize=3D16MB"

When this parameter is set, libpq executes a small query during
connection establishment to evaluate:

=C2=A0 pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn())=

on the standby. If the result exceeds the specified threshold, the
server is skipped and the next host in the list is tried. The check is
skipped entirely when target_session_attrs is set to primary or
read-write, since those modes already exclude standbys.

What if none of them meets the criteria? You fail the conn= ection? Wouldn't it cause an availability issue?
=C2=A0
=

If pg_last_wal_receive_lsn() is NULL (e.g. no active WAL receiver due to missing primary_conninfo or a disconnected upstream), the backlog cannot be determined. In that case, the standby is treated as exceeding the
threshold and is skipped.

When a standb= y is replaying archiving log, it can still be caught up. This doesn't s= eem right to me.
=C2=A0

This parameter measures only the apply lag on the standby itself, i.e.,
how much already-received WAL remains to be replayed. It does not
attempt to measure how far the standby is behind the primary. In
particular, a standby that is slow to receive WAL but fast to replay it
may report a small backlog here while still being significantly behind.
=

IMHO, this change appears to not meet the = objective of routing connections/queries to the most up-to-date standby.
=C2=A0
Thanks,
Satya
--0000000000002fea6b064e2df36e--