Re: Compression of bigger WAL records

From: Andrey Borodin <x4mmm(at)yandex-team(dot)ru>
To: Anthonin Bonnefoy <anthonin(dot)bonnefoy(at)datadoghq(dot)com>
Cc: surya poondla <suryapoondla4(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>, Matthias van de Meent <boekewurm+postgres(at)gmail(dot)com>
Subject: Re: Compression of bigger WAL records
Date: 2026-08-19 11:19:38
Message-ID: E4D62FA5-8234-41F9-8CDA-F44FD87B8BA3@yandex-team.ru
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> On 19 Aug 2026, at 11:11, Anthonin Bonnefoy <anthonin(dot)bonnefoy(at)datadoghq(dot)com> wrote:
>
> On a second look, 1.3MB is the size reported by ZSTD_estimateCCtxSize
> with the default compression level for the worst case. So it's the
> maximum memory a cctx can use, and my test was probably not enough to
> reach this.

Hi Anthonin,

Thanks for profiling it, and for noting the 1.3MB mistake.

A compression context sizes itself for the largest input it has been
given. Measured with ZSTD_sizeof_CCtx at the default level:

fresh 5248
after one 8kB page image 154616
after 1000 page images 154616
after one 274300-byte record 1303544
ZSTD_estimateCCtxSize(3) 1303544

So 152kB is what a backend holds if we actually use only step 1.

Where I had thought about context size was 0003, since that is where a
context stays alive across many records and holds a window of history,
and where I measured what a stream costs a reader. What I had not
understood is that the allocation is gradual.

While measuring I also took the decompression side, since 0001 now
keeps one of those too: a DCtx is 95992 bytes and does not grow, which
matches ZSTD_estimateDCtxSize() exactly. So every reader (startup process,
walsender, pg_waldump) pays about 94kB.

> Would it be worth it to register ZSTD_freeCCtx using on_proc_exit? I
> imagine this will be tagged as leaked memory since it's never freed.

I do not think it will be tagged: the context is reachable from a
file-scope static for the life of the process, so a leak checker
classes it as still reachable rather than lost. In basebackup_zstd.c
and astreamer_zstd.c, are tied to the lifetime of a sink or a streamer
rather than of the process.

That said it is one line and I have no strong feeling about it, so if
you or anyone else would rather see it registered, say so and I will
add it.

Thank you!

Best regards, Andrey Borodin.

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Daniel Gustafsson 2026-08-19 11:21:49 Re: Python/pytest test framework take two
Previous Message Cagri Biroglu 2026-08-19 11:10:04 Re: Per-table resync for logical replication subscriptions