PostgreSQL

PostgreSQL

The wal_level You Set Is Not the wal_level You Get

For as long as logical replication has existed in PostgreSQL, the rule has been: if you ever might want to use it, set wal_level = logical at server start and live with the WAL volume forever. The cost wasn’t disastrous, but it was always-on. Set it once, pay it forever, including for the 364 days a year you weren’t using

All Your GUCs in a Row: autovacuum_work_mem

autovacuum_work_mem sets the maximum memory each autovacuum worker may use for tracking dead tuple identifiers (TIDs) during a vacuum. Default is -1, which means “inherit from maintenance_work_mem.” Context is sighup. The parameter exists so that autovacuum’s memory consumption can be tuned independently of the memory used by manual VACUUM, CREATE INDEX, REINDEX, and other

All Your GUCs in a Row: autovacuum_vacuum_scale_factor and autovacuum_vacuum_threshold

The classic vacuum-trigger pair, finally. We have spent the last several posts on parameters that modify, cap, or supplement the trigger formula governed by these two; now we get to the originals.

The formula:

1vacuum threshold = autovacuum_vacuum_threshold
2 + autovacuum_vacuum_scale_factor × reltuples

When the number of obsoleted tuples (rows updated or deleted) since

All Your GUCs in a Row: autovacuum_vacuum_max_threshold

New in PostgreSQL 18. This parameter is the project’s first-class fix for a problem the entire community has been working around for roughly fifteen years: on very large tables, the default vacuum trigger formula waits absurdly long before doing anything.

The original formula:

1vacuum threshold = autovacuum_vacuum_threshold
2 + autovacuum_vacuum_scale_factor × reltuples

With the

A Field Guide to Alternative Storage Engines for PostgreSQL

PostgreSQL 12 shipped the table access method API in October 2019, and the community spent the next six years figuring out what to do with it. The early prediction was that within a few releases we would have a thriving ecosystem of pluggable storage engines — columnar for analytics, undo-log for OLTP, in-memory for hot workloads — and the heap

pg_lake vs Lakebase: Two Very Different Things Called “Postgres + Lakehouse”

Snowflake and Databricks are now both selling something called PostgreSQL, both pitched at the same general use case (“the operational database next to your lakehouse”), and both with the word “lake” in the product name. Snowflake calls theirs pg_lake (a set of open-source extensions, plus the managed Snowflake Postgres service that wraps them). Databricks calls theirs Lakebase (a managed service

All Your GUCs in a Row: autovacuum_vacuum_insert_scale_factor and autovacuum_vacuum_insert_threshold

These two are the third matched pair in the autovacuum suite, after the analyze pair and the regular vacuum pair (the latter coming up next). They control when autovacuum runs VACUUM against a table based on the number of inserts since the last vacuum — not updates, not deletes, just inserts. They were added in PostgreSQL 13, and they exist

The Maintainer Is Not the Owner

“You never actually own a project, you merely look after it for the next generation.”
— with apologies to Patek Phillippe.

In early March 2026, Dan Blanchard published chardet 7.0.0. The package metadata was familiar — same name on PyPI, same import path, same public API. The license was not. Versions 1.1 through 6.x had shipped

Eight Bytes Is the Easy Part

PostgreSQL 19 widens multixact members to 64 bits, retiring one of the more interesting failure modes the database can produce in production. The members-space wraparound on the multixact SLRU was a genuine outage class — Metronome ate four of them in a single migration last May — and it is gone in 19. Good. Onward.

The obvious next question,

All Your GUCs in a Row: autovacuum_naptime, autovacuum_vacuum_cost_delay, autovacuum_vacuum_cost_limit

These three parameters together set the pace of autovacuum: how often it considers running, how hard it works while running, and how long it pauses to keep from monopolizing your I/O. Like the analyze pair, they are best understood as a unit.