Build1 distinct publisher3 min readUpdated
A published walkthrough of pg_basebackup --incremental shows the real cost: a GUC change plus a restart before the fact, and a mandatory pg_combinebackup step in every restore.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
A walkthrough published on dev.to runs PostgreSQL 18's incremental pg_basebackup end to end: set the required parameters, take a full backup, change data, take an incremental against the full backup's manifest, then use pg_combinebackup to combine and restore [1]. The feature itself is unremarkable in operation; what it adds to a runbook is two preconditions that are easy to discover at the wrong moment.
The first is `summarize_wal`. It enables WAL summarization and is required for incremental backups [3]. In the walkthrough it goes into postgresql.conf alongside `wal_level = replica`, `archive_mode = on` and an `archive_command` that copies segments with `cp` [2], and the server is restarted before any backup is taken [4][2]. Treat that ordering as the requirement rather than as something to find out during your first incremental run.
The second is that `backup_manifest` becomes an operational input, not an archived artifact. The manifest is what identifies the contents of a backup when an incremental is created [7], and the incremental command points directly at it: `pg_basebackup -D /PGbackup/Incremental/ --incremental /PGbackup/Full/backup_manifest -P` [10]. The full backup directory listing shows that manifest at 138,089 bytes next to a complete data directory [6].
The scale numbers are worth reading carefully because they are demo scale. The full backup reported 23,648 of 23,648 kB across one tablespace [5]. Between backups the author created a database, a two-column table and inserted a single row [8], changes the full backup does not contain [9]. The incremental directory then lists a total of 252K, of which the new backup_manifest is 184K [12]. That is roughly 1 percent of the bytes the full backup moved [15], and about three quarters of the incremental is manifest [16]; the manifest also grew about 36 percent against the full backup's copy [20]. At real data volumes the ratio inverts, but the metadata floor is real.
One caution on instrumentation: the incremental run's progress line reads 11,477 of 31,360 kB (36%) [10], a denominator 7,712 kB larger than the full backup's total [17]. The source does not explain that, and the line is a mid-run snapshot, so incremental progress percentages are not a measure of delta size. The directory listing is. File timestamps put the two backups four minutes apart [13][14], which tells you nothing transferable about your own window.
The consequence for retention is the part to write down. Because the incremental contains only the data required to update the referenced backup [11], the referenced full backup and its manifest sit inside the restore path [18]. Expiring the full backup after a successful incremental leaves you with something that will not restore. And restore is no longer a copy of a data directory into place: it requires pg_combinebackup [1]. The excerpt available stops partway through the incremental directory listing, so verify the exact invocation and flags against the manual rather than against this walkthrough.
Watch three things: whether `summarize_wal` is already on in every PG18 cluster you own, what manifest size does relative to data as clusters grow [16], and whether your restore automation and your drills actually call pg_combinebackup [1].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The article demonstrates creating a full backup and an incremental backup with pg_basebackup in PostgreSQL 18, then using pg_combinebackup to combine the backups and restore the database.
Required parameters were added or modified in /var/lib/pgsql/18/data/postgresql.conf: wal_level = replica, archive_mode = on, archive_command = 'cp "%p" "/archive/%f"', summarize_wal = on.
The summarize_wal parameter enables WAL summarization, which is required for incremental backups.
After changing the parameters, PostgreSQL was restarted with pg_ctl restart; the server stopped and then started.
The full backup was taken with pg_basebackup -D /PGbackup/Full/ -P and reported 23648/23648 kB (100%), 1/1 tablespace.
The full backup directory contained a complete PostgreSQL data directory, including backup_label, backup_manifest of 138089 bytes, base, global, pg_wal and postgresql.conf.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Reproducible single-host transcript, no corroboration
Claims rest on one self-published walkthrough that includes verbatim commands, config settings, progress lines and directory listings, which is checkable and internally consistent. But it is a single publisher, a single small lab database, and the supplied body is truncated before pg_combinebackup runs, so the restore half of the workflow is unverified here. No second source, no vendor documentation, and no production-scale figures are present.
One practitioner lab run
Observed usage amounts to a single hands-on run on one Oracle Linux 8 host with PostgreSQL 18, plus the size figures from that run. There is no disclosure of production use, fleet rollout, or third-party tooling integration in the supplied material, so adoption evidence is real but minimal.
Savings framing slightly outruns the shown numbers
The post's 'much smaller than the full backup' framing is directionally supported (252K directory vs 23648 kB transferred), but the shown artifacts complicate it: the manifest alone is about three quarters of the incremental directory, the incremental run's progress denominator is 7712 kB larger than the full backup's transferred total with no explanation, and the workflow adds a mandatory restart-before-the-fact plus a combine step in every restore that the supplied body never demonstrates. Modestly overstated rather than misleading; the tone is otherwise sober and unpromotional.
Individual tutorial, no vendor stake visible
The single source is a personal technical post on a general developer publishing platform, with no product being sold, no sponsor disclosure, no pricing or licensing pitch, and no comparison favouring a commercial tool. Residual incentive is the ordinary practitioner-visibility motive for publishing a walkthrough, which can favour a clean happy path over failure modes, consistent with the truncated restore section.
Mechanics well shown, breadth and restore verification thin
High confidence that the prerequisite configuration, restart, and command sequence are as reported, since they are quoted verbatim and internally consistent. Low confidence in generalising the size or effort figures beyond a tiny lab database, and no confidence that the combine/restore step behaved as claimed, because that portion is not in the supplied body and no second publisher corroborates it.
build
Your "Index Only Scan" Did 2,847 Heap Fetches: Covering Indexes Are a Vacuum Problem1 distinct publisher
build
The optional EntityManager is the bug: moving the transaction boundary into AsyncLocalStorage1 distinct publisher
build
Three attackers hide behind one connect button, and encryption only stops one of them1 distinct publisher
build
Three services you can delete: queue, cache and search in one Postgres1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 19, 2026