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 1vqCus-006Xai-0O for pgsql-bugs@arkaria.postgresql.org; Wed, 11 Feb 2026 16:18:15 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vqCuq-004TIB-3C for pgsql-bugs@arkaria.postgresql.org; Wed, 11 Feb 2026 16:18:13 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vq6yS-0039gb-0N for pgsql-bugs@lists.postgresql.org; Wed, 11 Feb 2026 09:57:33 +0000 Received: from mail-ed1-x532.google.com ([2a00:1450:4864:20::532]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vq6yQ-000000007zi-2wPT for pgsql-bugs@lists.postgresql.org; Wed, 11 Feb 2026 09:57:32 +0000 Received: by mail-ed1-x532.google.com with SMTP id 4fb4d7f45d1cf-65941c07fb4so10175229a12.3 for ; Wed, 11 Feb 2026 01:57:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1770803849; cv=none; d=google.com; s=arc-20240605; b=ASaaD/UAJiB23TqpU8Jg4tsYB8Fkl3/HgAYJLgvSkN6PjBCDQijgkAJQRx3EsWhpK/ qiLXkJQu05mPFFC9LIW91EffvvcI/uFJ55eIwuCjtjPu6fIsWfchgU8pru0KJvx9z806 bOf8gYN5lyl3qdjSaCpNhUchY0d5VMTuKorhfNVUPwWh4tPXK4JttJnaAvqa0RxbrEtx qFhkcaSxcRc0FLpE4A2D4xyhYC4enm28j7ANlzu4MTNtsnohfs2foAZqb2TJU4t09opu YoXzRdb7Wn9LnypYmF2fzPndIOlgystmexB+jNx8xpvR22mV+hmL+/OE13fRfdZah6qs O3Tw== 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=Vfsd+sEECiqmli2i4G16DIOxP64cNPapObEm6cw5i/w=; fh=0WOE0YaIKU2zERByoXRA8PU7NhgtWVw3IqVklLkLZic=; b=UhF8AjbiRq/nqEDq6XV4o9InF6FjsdObL2sq2NLr4pOEoSrgphfH/mcsVT4x3Yozyz Y4mVVpp7eL6tiXyiTOf/Q78ICEQh1wXf75MjeoLmF4M2yR0DPVY15ou3w4K/abPzb+bN GNjAw1P//4QkkWV9VUSFoVE2aJwmnN2coPcPoJ45g/Wg4IPcnDwaGt278lIQwxjNAugk xyYTDtKx9n/ILt2UiJAHx4IFWJGrXI3Iy2axiWI+s+ITQmkUOTfv8cqfuCvxqZE3BUvA yjrhOJseRzAJEbCyryznGKrsYhgOdFxVGbeyUM79Fmrsd83sFsHHJl4vCYcXQjPQLrb8 ri7A==; 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=atmotrack-fr.20230601.gappssmtp.com; s=20230601; t=1770803849; x=1771408649; 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=Vfsd+sEECiqmli2i4G16DIOxP64cNPapObEm6cw5i/w=; b=2Yh3AmuShsUC2gfZpXRcPYBDqV7BsFXTbZ1HwQD/FRStWzlpr0tsJSe9B8pxguJY1D XcknMocDymv7c8AHMKj9Ot8ytqZzWbghTntHN8mskfW2yQI7SaNK3VYxre7W0MKllPw6 lK43I7yDWENRr6vPArnwjZtiziWB4rsFd4eqeyjWr/jAa7/0A1aHO0TpK5CuxX26uJlz dfSEG4yydz2BMvbjdp6kf02Qv0eyIQaejeyz4n7C0XXNKib903a5PnIQxPecMOtbf32V H1KExYLwPH4SQ0ZnL0b+FqHt5PqNI7YWvdMYWr80yxvICn0B6uJ5SRx3p7MusZkctPPX r+8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770803849; x=1771408649; 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=Vfsd+sEECiqmli2i4G16DIOxP64cNPapObEm6cw5i/w=; b=YAERdfsiaE5rE9UI7jzQ9BOHMwYe1ldpDj8ceOBpmBxTUCORI0YW6mT2QNxjCsB2DN ypaKYZZQSsC7VYUZKyk55BGtrFdNaSR59bV7qkOoSy91VA9Nbfgqrf6Fmj0xFcLkjajE YmdFPbPuTKdIv3hfbRzi1vDHXHa01fd/jEyvolOvSCWkM59lQqcc4wfHqlEz6Y1/ZRCy CXzdnAcl7FefSjl3pAN60c2X8N65FDBmJ5Uif3yAdO+60jgE+py4/q3eU5IfmEIJFYOl hrNU6WSNbnWGNNzcx/96FIDi6i/H3eVIj4FS53zG8QQji8B4sE60BUnQgjvsGupbxRBb tsYA== X-Gm-Message-State: AOJu0Yx5UhZPNJAXlHEfmhB+5CyGiX33INs9f/2OuoyI2yVW2Sl8NAEM C6en08zqyyWY4sOsE+hpnEBuVrmXhlPGOATMuH7R8KOvlM6dJaaezLyoLEnr3eUP5hwHdwcfdr+ vHKY27QV+fR5S72kozPeEZoWeVkrz0C3QeURVd9u3wCd8/rDkenFs0skh4A== X-Gm-Gg: AZuq6aIhnO4GDgaXwWJ01I9noS+nHavBxKhr03v4DKRvsKTPxM6Bp+wGLm9+sYudC38 5jdMShch+KtZWbRGniCQ/mbh5Ee7FndWZnyoDoCbL+fgMw/sLadfJr7EQqbVl1sqlt+QJS1vH1m BBXH9NniSbAm67tqp7BEEkmIZW7NJ2YT19BnW8u8VZtqiWYBQXbe8nQl/lP9J9xbBzN9xrLhbG+ fq18I0kZWiDFSoqxXvyYORxPU4CS65zBGV2LFovFKW5qnr1bFavTXcPr+jX7cGVtALXkMcLpFcP YYM7/jyFrGIc3bH9Iv9D+BP7mPuEdvKgKYot727ANK5aLNFuS9XnqyNc7qSMJqjN0Em4h0r/1e8 B7thPGg== X-Received: by 2002:a17:906:6a1f:b0:b88:6fd3:d5fc with SMTP id a640c23a62f3a-b8f546a3a0emr331869166b.46.1770803849335; Wed, 11 Feb 2026 01:57:29 -0800 (PST) MIME-Version: 1.0 References: <19400-c889fc7fffc7c658@postgresql.org> In-Reply-To: From: =?UTF-8?Q?Rapha=C3=ABl_Perissat?= Date: Wed, 11 Feb 2026 10:56:53 +0100 X-Gm-Features: AZwV_QiQSt8e9rEYaoKKQNVWhRxz5s7_xX5il0BJNHFDfFNseMzHDvcV91XloJ0 Message-ID: Subject: Re: BUG #19400: Memory leak in checkpointer and startup processes on PostgreSQL 18 To: Andres Freund Cc: pgsql-bugs@lists.postgresql.org Content-Type: multipart/alternative; boundary="000000000000682abf064a896634" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000682abf064a896634 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi and thanks for the explanation. Indeed the pmap seems to confirm that the private memory usage is correct # pmap -d -p $(pgrep -f "postgres.*checkpointer") | tail -n 1 mapped: 8647256K writeable/private: 2632K shared: 8574584K I used pg_log_backend_memory_contexts() with the pid of the checkpointer process and I can't see much on this side as well : 2026-02-11 08:58:13.794 UTC [1988622] LOG: logging memory contexts of PID 1988622 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 1; TopMemoryContext: 61568 total in 3 blocks; 2768 free (0 chunks); 58800 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; smgr relation table: 32768 total in 3 blocks; 16904 free (9 chunks); 15864 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; Checkpointer: 24576 total in 2 blocks; 24296 free (13 chunks); 280 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; LOCALLOCK hash: 8192 total in 1 blocks; 616 free (0 chunks); 7576 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; WAL record construction: 50200 total in 2 blocks; 6400 free (0 chunks); 43800 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; PrivateRefCount: 8192 total in 1 blocks; 2672 free (0 chunks); 5520 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; MdSmgr: 8192 total in 1 blocks; 7952 free (62 chunks); 240 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; Pending ops context: 8192 total in 1 blocks; 7952 free (5 chunks); 240 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 3; Pending Ops Table: 16384 total in 2 blocks; 6712 free (3 chunks); 9672 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; Rendezvous variable hash: 8192 total in 1 blocks; 616 free (0 chunks); 7576 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 2; GUCMemoryContext: 32768 total in 3 blocks; 3264 free (19 chunks); 29504 used 2026-02-11 08:58:13.794 UTC [1988622] LOG: level: 3; GUC hash table: 32768 total in 3 blocks; 10664 free (6 chunks); 22104 used 2026-02-11 08:58:13.795 UTC [1988622] LOG: level: 2; Timezones: 104112 total in 2 blocks; 2672 free (0 chunks); 101440 used 2026-02-11 08:58:13.795 UTC [1988622] LOG: level: 2; ErrorContext: 8192 total in 1 blocks; 7952 free (5 chunks); 240 used 2026-02-11 08:58:13.795 UTC [1988622] LOG: Grand total: 404296 bytes in 26 blocks; 101440 free (122 chunks); 302856 used I monitor my servers metric on ELK (grafana-like) and I can clearly see the memory usage growing with approx 100MB/hour until it reaches 8GB for the postgres process, causing patroni to crashout on the primary. The fact that this memory "leak" is appearing on both the primary and the 2 replicas make me think that this is not caused by some ingest delay / index creation but maybe I'm wrong. I restarted the 3 nodes yesterday and here is the output of the watch command on the primary : total used free shared buff/cache available Mem: 31988 5861 670 4571 30530 26126 Swap: 4095 55 4040 free is only showing 670 already, and I can see it going down in real-time like a countdown. Based on this output on the replicas : :~# ps aux --sort=3D-%mem | head -20 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND postgres 62338 0.1 10.6 8652016 3492940 ? Ss Feb10 1:04 postgres: atmo_data: checkpointer postgres 62340 0.2 9.8 8655736 3227356 ? Ss Feb10 2:36 postgres: atmo_data: startup recovering 0000001E00000246000000C9 Couldn't the startup recovery process be causing this ? I do this command on the same replica time to time and I can clearly see that the %MEM used by those 2 processes are growing over time. Thanks for your help. Le mar. 10 f=C3=A9vr. 2026 =C3=A0 20:58, Andres Freund = a =C3=A9crit : > Hi, > > On 2026-02-10 15:28:38 +0000, PG Bug reporting form wrote: > > I recently migrated my cluster with 3 dedicated servers to a new > cluster. I > > was running on PG12 and I am now on PG18.1. > > I noticed an increasing memory usage on all of my 3 node, until at some > > point there is no memory left and patroni crashes on the leader, leavin= g > the > > cluster with no available primary. > > The cluster is a Data Warehouse type using TimescaleDB, ingesting > approx. 1M > > of time-serie a day. > > It appears that the memory leak is affecting both the checkpointer and > > startup (WAL replay) processes in PostgreSQL 18.0 and 18.1. > > I never had such issue on the old cluster with PG12 and the server's > > configuration and cluster usage are the same (except the upgrade of PG) > > > > SYMPTOMS: > > - Checkpointer process grows to 5.6GB RSS after 24 hours > > - Startup process on replicas grows to 3.9GB RSS > > - Memory growth rate: approximately 160-200MB per hour > > - Eventually causes out-of-memory conditions > > > > CONFIGURATION: > > - PostgreSQL version: Initially 18.0, upgraded to 18.1 - same issue > persists > > - Platform: Debian 13 > > - TimescaleDB: 2.23.0 > > - Deployment: 3-node Patroni cluster with streaming replication > > - WAL level: logical > > - Hot standby enabled > > > > SYSTEM RESOURCES: > > RAM: 32GB > > Proc: 12 core of Intel(R) Xeon(R) E-2386G 3.50GHz > > > > KEY SETTINGS: > > - wal_level: logical > > - hot_standby: on > > - max_wal_senders: 20 > > - max_replication_slots: 20 > > - wal_keep_size: 1GB > > - shared_buffer: 8GB > > > > WAL STATISTICS (over 7 days): > > - Total WAL generated: 2.3TB (approximately 31GB/day) > > - Replication lag: 0 bytes (replicas are caught up) > > - No long-running transactions > > > > MEMORY STATE AFTER 24 HOURS: > > On primary: > > postgres checkpointer: 3.9GB RSS > > > > On replicas: > > postgres checkpointer: 5.6GB RSS > > postgres startup recovering: 3.9GB RSS <-- This is abnormal > > The RSS slowly increasing towards shared_buffers is normal if you're not > using > huge_pages. The OS only counts pages in shared memory as part of RSS once= a > page has been used in the process. Over time the checkpointer process > touches > more and more of shared_buffers, thus increasing the RSS. > > You can use "pmap -d -p $pid_of_process" to see how much of the RSS is > actually shared memory. > > To show this, here's a PS for a new backend: > > ps: > USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAN= D > andres 2544694 0.0 0.0 8719956 25744 ? Ss 14:55 0:00 > postgres: dev assert: andres postgres [local] idle > > and then after reading in a relation 1.3GB relation: > > andres 2544694 1.7 2.2 8720972 1403576 ? Ss 14:55 0:00 > postgres: dev assert: andres postgres [local] idle > > So you can see that RSS increased proportionally with the amount of touch= ed > data. > > Whereas with pmap: > > pmap -d -p 2544694|tail -n 1 > mapped: 8721924K writeable/private: 5196K shared: 8646284K > > > I think you would need to monitor the real memory usage of various > processes > to know why you're OOMing. > > You can use pg_log_backend_memory_contexts() to get the memory usage > information of backend processes. > > Greetings, > > Andres Freund > --000000000000682abf064a896634 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi and thanks for the explanation.

Indeed the pmap seems to confirm that the private memory usage is co= rrect=C2=A0
# pmap -d -p $(pgrep -f "postgres.*checkpointer&= quot;) | tail -n 1
mapped: 8647256K =C2=A0 =C2=A0writeable/private: 2632= K =C2=A0 =C2=A0shared: 8574584K

I used=C2=A0pg_log= _backend_memory_contexts() with the pid of the checkpointer process and I c= an't see much on this side as well :
2026-02-11 08:58:13.794 = UTC [1988622] LOG: =C2=A0logging memory contexts of PID 1988622
2026-02-= 11 08:58:13.794 UTC [1988622] LOG: =C2=A0level: 1; TopMemoryContext: 61568 = total in 3 blocks; 2768 free (0 chunks); 58800 used
2026-02-11 08:58:13.= 794 UTC [1988622] LOG: =C2=A0level: 2; smgr relation table: 32768 total in = 3 blocks; 16904 free (9 chunks); 15864 used
2026-02-11 08:58:13.794 UTC = [1988622] LOG: =C2=A0level: 2; Checkpointer: 24576 total in 2 blocks; 24296= free (13 chunks); 280 used
2026-02-11 08:58:13.794 UTC [1988622] LOG: = =C2=A0level: 2; LOCALLOCK hash: 8192 total in 1 blocks; 616 free (0 chunks)= ; 7576 used
2026-02-11 08:58:13.794 UTC [1988622] LOG: =C2=A0level: 2; W= AL record construction: 50200 total in 2 blocks; 6400 free (0 chunks); 4380= 0 used
2026-02-11 08:58:13.794 UTC [1988622] LOG: =C2=A0level: 2; Privat= eRefCount: 8192 total in 1 blocks; 2672 free (0 chunks); 5520 used
2026-= 02-11 08:58:13.794 UTC [1988622] LOG: =C2=A0level: 2; MdSmgr: 8192 total in= 1 blocks; 7952 free (62 chunks); 240 used
2026-02-11 08:58:13.794 UTC [= 1988622] LOG: =C2=A0level: 2; Pending ops context: 8192 total in 1 blocks; = 7952 free (5 chunks); 240 used
2026-02-11 08:58:13.794 UTC [1988622] LOG= : =C2=A0level: 3; Pending Ops Table: 16384 total in 2 blocks; 6712 free (3 = chunks); 9672 used
2026-02-11 08:58:13.794 UTC [1988622] LOG: =C2=A0leve= l: 2; Rendezvous variable hash: 8192 total in 1 blocks; 616 free (0 chunks)= ; 7576 used
2026-02-11 08:58:13.794 UTC [1988622] LOG: =C2=A0level: 2; G= UCMemoryContext: 32768 total in 3 blocks; 3264 free (19 chunks); 29504 used=
2026-02-11 08:58:13.794 UTC [1988622] LOG: =C2=A0level: 3; GUC hash tab= le: 32768 total in 3 blocks; 10664 free (6 chunks); 22104 used
2026-02-1= 1 08:58:13.795 UTC [1988622] LOG: =C2=A0level: 2; Timezones: 104112 total i= n 2 blocks; 2672 free (0 chunks); 101440 used
2026-02-11 08:58:13.795 UT= C [1988622] LOG: =C2=A0level: 2; ErrorContext: 8192 total in 1 blocks; 7952= free (5 chunks); 240 used
2026-02-11 08:58:13.795 UTC [1988622] LOG: = =C2=A0Grand total: 404296 bytes in 26 blocks; 101440 free (122 chunks); 302= 856 used

I monitor my servers metric on ELK (g= rafana-like) and I can clearly see the memory usage growing with approx 100= MB/hour until it reaches 8GB for the postgres process, causing patroni to c= rashout on the primary.=C2=A0
The fact that this memory "lea= k" is appearing on both the primary and the 2 replicas make me think t= hat this is not caused by some ingest delay / index creation but maybe I= 9;m wrong.

I restarted the 3 nodes yesterday=C2=A0= and here is the output of the watch command on the primary :
tota= l =C2=A0 =C2=A0 =C2=A0 =C2=A0used =C2=A0 =C2=A0 =C2=A0 =C2=A0free =C2=A0 = =C2=A0 =C2=A0shared =C2=A0buff/cache =C2=A0 available
Mem: =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 31988 =C2=A0 =C2=A0 =C2=A0 =C2=A05861 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 670 =C2=A0 =C2=A0 =C2=A0 =C2=A04571 =C2=A0 =C2=A0 =C2=A0 3053= 0 =C2=A0 =C2=A0 =C2=A0 26126
Swap: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 40= 95 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A055 =C2=A0 =C2=A0 =C2=A0 =C2=A04040

free is only showing 670 already, and I can see it go= ing down in real-time like a countdown.

Based on t= his output on the replicas :
:~# ps aux --sort=3D-%mem | head -20=
USER =C2=A0 =C2=A0 =C2=A0 =C2=A0 PID %CPU %MEM =C2=A0 =C2=A0VSZ =C2=A0 = RSS TTY =C2=A0 =C2=A0 =C2=A0STAT START =C2=A0 TIME COMMAND
postgres =C2= =A0 62338 =C2=A00.1 10.6 8652016 3492940 ? =C2=A0 =C2=A0 Ss =C2=A0 Feb10 = =C2=A0 1:04 postgres: atmo_data: checkpointer
postgres =C2=A0 62340 =C2= =A00.2 =C2=A09.8 8655736 3227356 ? =C2=A0 =C2=A0 Ss =C2=A0 Feb10 =C2=A0 2:3= 6 postgres: atmo_data: startup recovering 0000001E00000246000000C9

Couldn't the startup recovery process be causing this = ? I do this command on the same replica time to time and I can clearly see = that the %MEM used by those 2 processes are growing over time.
Thanks for your help.

=

Le=C2=A0mar. 10 f= =C3=A9vr. 2026 =C3=A0=C2=A020:58, Andres Freund <andres@anarazel.de> a =C3=A9crit=C2=A0:
Hi,

On 2026-02-10 15:28:38 +0000, PG Bug reporting form wrote:
> I recently migrated my cluster with 3 dedicated servers to a new clust= er. I
> was running on PG12 and I am now on PG18.1.
> I noticed an increasing memory usage on all of my 3 node, until at som= e
> point there is no memory left and patroni crashes on the leader, leavi= ng the
> cluster with no available primary.
> The cluster is a Data Warehouse type using TimescaleDB, ingesting appr= ox. 1M
> of time-serie a day.
> It appears that the memory leak is affecting both the checkpointer and=
> startup (WAL replay) processes in PostgreSQL 18.0 and 18.1.
> I never had such issue on the old cluster with PG12 and the server'= ;s
> configuration and cluster usage are the same (except the upgrade of PG= )
>
> SYMPTOMS:
> - Checkpointer process grows to 5.6GB RSS after 24 hours
> - Startup process on replicas grows to 3.9GB RSS
> - Memory growth rate: approximately 160-200MB per hour
> - Eventually causes out-of-memory conditions
>
> CONFIGURATION:
> - PostgreSQL version: Initially 18.0, upgraded to 18.1 - same issue pe= rsists
> - Platform: Debian 13
> - TimescaleDB: 2.23.0
> - Deployment: 3-node Patroni cluster with streaming replication
> - WAL level: logical
> - Hot standby enabled
>
> SYSTEM RESOURCES:
> RAM: 32GB
> Proc: 12 core of Intel(R) Xeon(R) E-2386G 3.50GHz
>
> KEY SETTINGS:
> - wal_level: logical
> - hot_standby: on
> - max_wal_senders: 20
> - max_replication_slots: 20
> - wal_keep_size: 1GB
> - shared_buffer: 8GB
>
> WAL STATISTICS (over 7 days):
> - Total WAL generated: 2.3TB (approximately 31GB/day)
> - Replication lag: 0 bytes (replicas are caught up)
> - No long-running transactions
>
> MEMORY STATE AFTER 24 HOURS:
> On primary:
>=C2=A0 =C2=A0postgres checkpointer: 3.9GB RSS
>
> On replicas:
>=C2=A0 =C2=A0postgres checkpointer: 5.6GB RSS
>=C2=A0 =C2=A0postgres startup recovering: 3.9GB RSS=C2=A0 <-- This i= s abnormal

The RSS slowly increasing towards shared_buffers is normal if you're no= t using
huge_pages. The OS only counts pages in shared memory as part of RSS once a=
page has been used in the process. Over time the checkpointer process touch= es
more and more of shared_buffers, thus increasing the RSS.

You can use "pmap -d -p $pid_of_process" to see how much of the R= SS is
actually shared memory.

To show this, here's a PS for a new backend:

ps:
USER=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0PID %CPU %MEM=C2=A0 =C2=A0 VSZ=C2=A0 = =C2=A0RSS TTY=C2=A0 =C2=A0 =C2=A0 STAT START=C2=A0 =C2=A0TIME COMMAND
andres=C2=A0 =C2=A02544694=C2=A0 0.0=C2=A0 0.0 8719956 25744 ?=C2=A0 =C2=A0= =C2=A0 =C2=A0Ss=C2=A0 =C2=A014:55=C2=A0 =C2=A00:00 postgres: dev assert: a= ndres postgres [local] idle

and then after reading in a relation 1.3GB relation:

andres=C2=A0 =C2=A02544694=C2=A0 1.7=C2=A0 2.2 8720972 1403576 ?=C2=A0 =C2= =A0 =C2=A0Ss=C2=A0 =C2=A014:55=C2=A0 =C2=A00:00 postgres: dev assert: andre= s postgres [local] idle

So you can see that RSS increased proportionally with the amount of touched=
data.

Whereas with pmap:

pmap -d -p 2544694|tail -n 1
mapped: 8721924K=C2=A0 =C2=A0 writeable/private: 5196K=C2=A0 =C2=A0 shared:= 8646284K


I think you would need to monitor the real memory usage of various processe= s
to know why you're OOMing.

You can use pg_log_backend_memory_contexts() to get the memory usage
information of backend processes.

Greetings,

Andres Freund
--000000000000682abf064a896634--