default_toast_compression sets which algorithm PostgreSQL uses to compress values bound for TOAST — the out-of-line storage that holds field values too big to sit inline in an 8KB heap page. The choices are pglz and lz4; the default, on every released version as of today, is pglz; the context is user, and it can be overridden per column with the COMPRESSION option on CREATE TABLE or ALTER TABLE. The parameter has existed since PostgreSQL 14, and the more interesting fact is that its default is, finally, about to change.

A word on what’s being compressed

TOAST compresses individual oversized column values, not whole rows. When a value in a compressible column (text, jsonb, bytea, and friends) pushes a tuple past the TOAST threshold — roughly 2KB — PostgreSQL tries compressing the wide values; if the result fits, it stays inline compressed, and if not, it’s pushed out to the table’s TOAST relation, compressed there. This is automatic, transparent, and on by default for every table with a toastable column, which is nearly all of them. default_toast_compression only chooses the algorithm; everything else about TOAST happens regardless.

The two algorithms make a clean tradeoff. pglz is PostgreSQL’s own venerable compressor, embedded in the source, available in every build since forever. lz4 — added as a TOAST option in PostgreSQL 14 — is faster at both ends, often dramatically so, for a usually-modest cost in ratio. Benchmarks land around pglz compressing perhaps 7% tighter on average while lz4 runs several times faster to compress and decompress. There’s also a quieter behavioral difference: pglz only keeps the compressed form if it saves at least 25%, while lz4 keeps it whenever it comes out any smaller at all, so the two don’t even make the same keep-or-discard decision on marginally-compressible data. For the overwhelming majority of workloads — where TOAST reads and writes cost CPU you’d rather spend elsewhere, and 7% of the disk under your large values is noise — lz4 is the better default, and has been the right manual choice since 14.

The default is changing

For five releases the default stayed pglz for one defensible reason: it is always present, while lz4 requires that the build include the LZ4 library, and a default that isn’t guaranteed available is awkward. As of a commit on the master branch in early 2026 — Euler Taveira’s work, reviewed by Peter Eisentraut and Aleksander Alekseev — that changes. In PostgreSQL 19, a fresh cluster defaults to lz4 whenever the build supports it, falling back to pglz only where it doesn’t. The old --with-lz4 build flag is retired in favor of --without-lz4, the same opt-out treatment readline and ICU already get: LZ4 is now assumed present unless you go out of your way to exclude it. The reasoning in the commit is the one this post has been making — lz4 uses less CPU and compresses better on average, and after five releases the feature is plainly stable enough to be the default.

The thing to keep straight: this is PostgreSQL 19. As of mid-2026, every version you can actually run in production — 14 through 18 — still ships pglz as the default, and on those you get lz4 only by setting it.

What to do

On 14 through 18: set it to lz4. Confirm the build has LZ4 first — SHOW default_toast_compression will error on an attempt to set lz4 if it doesn’t, and distribution packages almost universally include it — then set it per-database or cluster-wide and enjoy faster TOAST handling on every new column. The one genuinely reassuring property here is that the change is perfectly safe: switching the default never touches existing data. TOAST values are compressed when written and carry their own algorithm marker, so old pglz values keep decompressing as pglz while new writes use lz4, and a single column can hold a mix indefinitely. There is no migration, no rewrite, no risk — pg_column_compression() will even show you which algorithm any given stored value used.

If you want existing data converted rather than just new writes, that takes an actual rewrite — ALTER TABLE ... ALTER COLUMN ... SET COMPRESSION lz4 changes the column’s future behavior, but only a table rewrite (or a dump and reload) re-compresses what’s already there. For most people that’s not worth doing; let the old values age out naturally and let lz4 handle everything new. On PostgreSQL 19 and later, the decision is made for you, correctly, and the only reason to touch this parameter will be the rare workload that specifically wants pglz’s slightly better ratio and doesn’t mind paying CPU for it.