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 1vRcP5-000TC8-27 for pgsql-performance@arkaria.postgresql.org; Fri, 05 Dec 2025 20:27:48 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vRcP3-009uKZ-0f for pgsql-performance@arkaria.postgresql.org; Fri, 05 Dec 2025 20:27:45 +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 1vRcP2-009uKQ-2Y for pgsql-performance@lists.postgresql.org; Fri, 05 Dec 2025 20:27:45 +0000 Received: from mail-200167.simplelogin.co ([176.119.200.167]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vRcP0-003KxQ-2l for pgsql-performance@lists.postgresql.org; Fri, 05 Dec 2025 20:27:44 +0000 ARC-Seal: i=1; a=rsa-sha256; d=simplelogin.co; s=arc-20230626; t=1764966461; cv=none; b=hLlhISBVRAUb8byXFa9Ay+cjj2dNc6DqBlQ1M+2b+eyjxOsznQ3TS8GMMbzVc/BrGoG0Ao6sQcm50FaWJXyDf1dfijhLhv5ZXWHH7jQ6uj3SxyrHoyJElz/FWJNUBknevsBmrzSKpyy2dLmaXVA9gLf3FW3B6zT+d0o3Ti4eVGD7OIt5A5rQ6Bpl6iQ4huiHdUuP5G8DKe9fyNDnsVwPcOOpyAEKhiEqxp5AaQoSKsEOeCC/9OOh4ev8a5eUo7NKqKka7fv/hlyuD3z0a2d/2ayBm/3KeWOsNd9zwEJuLqzvk4eofmqImvgDnuBGeLjf0EMNpynhDSD7ib68BrsOvQ== ARC-Message-Signature: i=1; a=rsa-sha256; d=simplelogin.co; s=arc-20230626; t=1764966461; c=relaxed/simple; bh=/tPuh/giC+fpPtTqCZV2vk7zaKCCtISYRy15MYsxqFc=; h=Subject:Date:In-Reply-To:From:To:Cc:References; b=TsrhZTLnv0QelC7L8omHa/rG2OjoS02v/zGG/x66ms/t2fgZrEWdDTlCu250seMKInG1yx3/zkp2ROPcV6zd1/EGNmtle/XYbTAAp/AndGyD6yOsDxqkSvQ04Mj8HYOzqwduLbejeX24B80dH5I7+cRddGwQe/+gDxQpR4oB4IFyiMKDCIPQyTLitnuyb5tkZwJ4130sAfMiHvQznbdVuqUbo8j/J8+Uqqt1F7o98GC85rF1194r6Nf3SLWRJJ5HLLC7IHk4su1etTFxdrJBf2GEZE1MsK6SI65d47XFMSc5+FYOIYs/ROvNrjkr7MLDo4UWm07JdPWYKC7vH4+MOQ== ARC-Authentication-Results: i=1; mail.protonmail.ch DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=georgiou.vip; s=dkim; t=1764966461; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yPI8sh8h2nz1yT/AZrrUG8+2J0nBsbP+IrC4QJWBjHg=; b=FzOJOWn28HIVv4LcH9zqVfdTHJOuZRfEGcOMGogEKHQMYOGQXnszF6t5O+Ekb7Vtcy4Zla SiSszWeepg7nid+Slw6Jg6PNI58jZRaX8noBeON3V/aqkWUdq/G5XCWbk1t59hu5HBpQpH p15lRwng3s/uLiQFhZL6u4A7kST8Jxw= Content-Type: multipart/alternative; boundary="Apple-Mail=_44D8BD1B-A556-4AFD-815E-EBD55B026AC7" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.200.81.1.6\)) Subject: Re: Seeking guidance on extremely slow pg_restore despite strong I/O performance Date: Fri, 5 Dec 2025 15:27:38 -0500 In-Reply-To: Content-Transfer-Encoding: 7bit From: pg254kl@georgiou.vip To: MentionTheElephant Cc: pgsql-performance@lists.postgresql.org Message-ID: <176496646088.6.4993161944894462260.1049766710@georgiou.vip> References: X-SimpleLogin-Type: Reply X-SimpleLogin-EmailLog-ID: 1049766713 X-SimpleLogin-Want-Signing: yes List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_44D8BD1B-A556-4AFD-815E-EBD55B026AC7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 If the dump was taken with pd_dump -Fd and pg_restore -j has no effect = on restore time, that=E2=80=99s a good clue. You can start with testing deferring checkpoints, by setting = wal_max_size =3D 1TB and checkpoint_timeout =3D 10h, and see how this = affects the pg_restore (should be limited by WAL write throughput). = Perhaps increase wal_buffers to 128MB. The idea being to identify (by = elimination) the write chock-point, before starting to tune for it. Irrelevant for your problem, you should set the *_io_concurrency to 200 = since you use SSDs. pg_restore rebuilds indices so also make sure the settings relevant to = index building are set appropriately (see max_parallel_* and = *_io_concurrency) Kiriakos Georgiou > On Dec 5, 2025, at 5:30=E2=80=AFAM, MentionTheElephant - = MentionTheElephant at gmail.com = wrote: >=20 > Hello, >=20 > I would greatly appreciate your insight into an issue where pg_restore > runs significantly slower than expected, even though the underlying > storage shows very high random write throughput. I am trying to > understand which PostgreSQL mechanisms or system layers I should > investigate next in order to pinpoint the bottleneck and improve > restore performance. >=20 > The central question is: What should I examine further to understand > why checkpoint processing becomes the dominant bottleneck during > restore, despite fsync=3Doff, synchronous_commit=3Doff, and excellent > random write latency? >=20 > Below is a detailed description of the environment, the behavior > observed, the steps I have already taken, and the research performed > so far. >=20 > During pg_restore, execution time remains extremely long: around 2+ > hours using a custom-format dump and over 4 hours using directory > format. The machine consistently demonstrates high random write > performance (median latency ~5 ms, ~45k random write IOPS), yet > PostgreSQL logs show very long checkpoints where the write phase > dominates (hundreds to thousands of seconds). Checkpoints appear to > stall the entire restore process. >=20 > I have tested multiple combinations of dump formats (custom and > directory) and parallel jobs (j =3D 1, 12, 18). The restore duration > barely changes. This strongly suggests that the bottleneck is not > client-side parallelism but internal server behavior=E2=80=94specificall= y the > checkpoint write phase. >=20 > Example log excerpts show checkpoint write times consistently in the > range of 600=E2=80=931100 seconds, with large numbers of buffers = written (from > hundreds of thousands to over 1.6 million). Sync times remain > negligible because fsync is disabled, reinforcing the suspicion that > PostgreSQL's internal buffer flushing and write throttling mechanisms > are the source of slowdown, not WAL or filesystem sync. >=20 > Given that: >=20 > * Storage is fast, > * fsync and synchronous commits are disabled, > * full_page_writes is off, > * wal_level is minimal, > * autovacuum is off, > * the restore is the only workload, >=20 > I am trying to determine what further PostgreSQL internals or Linux > I/O mechanisms may explain why these checkpoints are taking orders of > magnitude longer than the device=E2=80=99s raw write characteristics = would > suggest. >=20 > I am particularly looking for guidance on: >=20 > * Whether backend or checkpointer write throttling may still be > limiting write concurrency even during bulk restore, > * Whether XFS on Hyper-V VHDX + LVM + battery-backed SSD could > introduce any serialization invisible to raw I/O tests, > * Whether certain parameters (e.g., effective_io_concurrency, > maintenance_io_concurrency, wal_writer settings, combine limits, > io_uring behavior) could unintentionally reduce write throughput, > * Whether parallel pg_restore is inherently constrained by global > buffer flushing behavior, > * Any other PostgreSQL mechanisms that could cause prolonged > checkpoint write durations even with crash-safety disabled. >=20 > Below are the configuration values and environment details referenced = above. >=20 > Machine: > Hyper-V VM > 24 vCPU > 80 GB RAM > Ubuntu 24.04.3 (kernel 6.8.0-88) > PostgreSQL 18.1 >=20 > Database size: > ~700 GB across two tablespaces on separate disks (freshly restored) >=20 > Storage layout: > Each disk is its own VHDX > LVM on battery-backed SSD array > XFS for PGDATA > Barriers disabled >=20 > Random write performance (steady state): > Median latency: 5.1 ms > IOPS: ~45.6k >=20 > Restore tests: > pg_restore custom format: ~2h+ > pg_restore directory format: ~4h+ > Parallelism tested with j =3D 1, 12, 18, 24 >=20 > Representative checkpoint log entries: > (write phases ranging 76=E2=80=931079 seconds, buffer writes up to = 1.6M) >=20 > postgresql.conf (relevant parts): > shared_buffers =3D 20GB > work_mem =3D 150MB > maintenance_work_mem =3D 8GB > effective_io_concurrency =3D 1 > maintenance_io_concurrency =3D 1 > io_max_combine_limit =3D 512kB > io_combine_limit =3D 1024kB > io_method =3D io_uring >=20 > fsync =3D off > synchronous_commit =3D off > wal_sync_method =3D fdatasync > full_page_writes =3D off > wal_compression =3D lz4 >=20 > checkpoint_timeout =3D 60min > checkpoint_completion_target =3D 0.9 > max_wal_size =3D 80GB > min_wal_size =3D 10GB >=20 > effective_cache_size =3D 65GB > autovacuum =3D off > max_locks_per_transaction =3D 256 >=20 > If anyone has encountered similar behavior or can recommend specific > PostgreSQL subsystems, kernel settings, or I/O patterns worth > investigating, I would be very grateful for advice. My main goal is to > understand why checkpoint writes are so slow relative to the > hardware=E2=80=99s demonstrated capabilities, and how to safely = accelerate the > restore workflow. >=20 > Thank you in advance for any guidance. >=20 >=20 >=20 --Apple-Mail=_44D8BD1B-A556-4AFD-815E-EBD55B026AC7 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
If the dump was taken with pd_dump = -Fd and pg_restore -j has no effect on restore time, that=E2=80=99s a = good clue.
You can start with testing deferring checkpoints, = by setting wal_max_size =3D 1TB and checkpoint_timeout =3D 10h, and see = how this affects the pg_restore (should be limited by WAL write = throughput).  Perhaps increase wal_buffers to 128MB.  The idea = being to identify (by elimination) the write chock-point, before = starting to tune for it.

Irrelevant for your = problem, you should set the *_io_concurrency to 200 since you use = SSDs.
pg_restore rebuilds indices so also make sure the = settings relevant to index building are set appropriately (see = max_parallel_* and *_io_concurrency)

Kiriakos Georgiou

On Dec 5, 2025, at 5:30=E2=80=AFAM= , MentionTheElephant - MentionTheElephant at gmail.com = <mentiontheelephant_at_gmail_com_xpdkqvpqqa@simplelogin.co> = wrote:

Hello,

I would = greatly appreciate your insight into an issue where pg_restore
runs = significantly slower than expected, even though the = underlying
storage shows very high random write throughput. I am = trying to
understand which PostgreSQL mechanisms or system layers I = should
investigate next in order to pinpoint the bottleneck and = improve
restore performance.

The central question is: What = should I examine further to understand
why checkpoint processing = becomes the dominant bottleneck during
restore, despite fsync=3Doff, = synchronous_commit=3Doff, and excellent
random write = latency?

Below is a detailed description of the environment, the = behavior
observed, the steps I have already taken, and the research = performed
so far.

During pg_restore, execution time remains = extremely long: around 2+
hours using a custom-format dump and over 4 = hours using directory
format. The machine consistently demonstrates = high random write
performance (median latency ~5 ms, ~45k random = write IOPS), yet
PostgreSQL logs show very long checkpoints where the = write phase
dominates (hundreds to thousands of seconds). Checkpoints = appear to
stall the entire restore process.

I have tested = multiple combinations of dump formats (custom and
directory) and = parallel jobs (j =3D 1, 12, 18). The restore duration
barely changes. = This strongly suggests that the bottleneck is not
client-side = parallelism but internal server behavior=E2=80=94specifically = the
checkpoint write phase.

Example log excerpts show = checkpoint write times consistently in the
range of 600=E2=80=931100 = seconds, with large numbers of buffers written (from
hundreds of = thousands to over 1.6 million). Sync times remain
negligible because = fsync is disabled, reinforcing the suspicion that
PostgreSQL's = internal buffer flushing and write throttling mechanisms
are the = source of slowdown, not WAL or filesystem sync.

Given = that:

* Storage is fast,
* fsync and synchronous commits are = disabled,
* full_page_writes is off,
* wal_level is minimal,
* = autovacuum is off,
* the restore is the only workload,

I am = trying to determine what further PostgreSQL internals or Linux
I/O = mechanisms may explain why these checkpoints are taking orders = of
magnitude longer than the device=E2=80=99s raw write = characteristics would
suggest.

I am particularly looking for = guidance on:

* Whether backend or checkpointer write throttling = may still be
limiting write concurrency even during bulk = restore,
* Whether XFS on Hyper-V VHDX + LVM + battery-backed SSD = could
introduce any serialization invisible to raw I/O tests,
* = Whether certain parameters (e.g., = effective_io_concurrency,
maintenance_io_concurrency, wal_writer = settings, combine limits,
io_uring behavior) could unintentionally = reduce write throughput,
* Whether parallel pg_restore is inherently = constrained by global
buffer flushing behavior,
* Any other = PostgreSQL mechanisms that could cause prolonged
checkpoint write = durations even with crash-safety disabled.

Below are the = configuration values and environment details referenced = above.

Machine:
Hyper-V VM
24 vCPU
80 GB RAM
Ubuntu = 24.04.3 (kernel 6.8.0-88)
PostgreSQL 18.1

Database = size:
~700 GB across two tablespaces on separate disks (freshly = restored)

Storage layout:
Each disk is its own VHDX
LVM on = battery-backed SSD array
XFS for PGDATA
Barriers = disabled

Random write performance (steady state):
Median = latency: 5.1 ms
IOPS: ~45.6k

Restore tests:
pg_restore = custom format: ~2h+
pg_restore directory format: ~4h+
Parallelism = tested with j =3D 1, 12, 18, 24

Representative checkpoint log = entries:
(write phases ranging 76=E2=80=931079 seconds, buffer writes = up to 1.6M)

postgresql.conf (relevant parts):
shared_buffers =3D= 20GB
work_mem =3D 150MB
maintenance_work_mem =3D = 8GB
effective_io_concurrency =3D 1
maintenance_io_concurrency =3D = 1
io_max_combine_limit =3D 512kB
io_combine_limit =3D = 1024kB
io_method =3D io_uring

fsync =3D = off
synchronous_commit =3D off
wal_sync_method =3D = fdatasync
full_page_writes =3D off
wal_compression =3D = lz4

checkpoint_timeout =3D 60min
checkpoint_completion_target = =3D 0.9
max_wal_size =3D 80GB
min_wal_size =3D = 10GB

effective_cache_size =3D 65GB
autovacuum =3D = off
max_locks_per_transaction =3D 256

If anyone has = encountered similar behavior or can recommend specific
PostgreSQL = subsystems, kernel settings, or I/O patterns worth
investigating, I = would be very grateful for advice. My main goal is to
understand why = checkpoint writes are so slow relative to the
hardware=E2=80=99s = demonstrated capabilities, and how to safely accelerate the
restore = workflow.

Thank you in advance for any = guidance.




= --Apple-Mail=_44D8BD1B-A556-4AFD-815E-EBD55B026AC7--