<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg" -->

---
title: Postgres 19: How Our Advice Has Changed Since... | daily.dev
description: A deep retrospective revisits years of Crunchy Data's Postgres advice on COPY, TOAST, BRIN indexes, covering indexes, and partitioning, mapping which Postgres...
canonical: https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Postgres 19: How Our Advice Has Changed Since... | daily.dev
og:description: A deep retrospective revisits years of Crunchy Data's Postgres advice on COPY, TOAST, BRIN indexes, covering indexes, and partitioning, mapping which Postgres...
og:url: https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg
og:image: https://api.daily.dev/og/posts/viIa8jZFG.png
og:image:alt: Postgres 19: How Our Advice Has Changed Since...
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Postgres 19: How Our Advice Has Changed Since...

**[Crunchy Data](https://daily.dev/sources/crunchydata)** · 17 min read · 38 upvotes · 3 comments

## Summary

A deep retrospective revisits years of Crunchy Data's Postgres advice on COPY, TOAST, BRIN indexes, covering indexes, and partitioning, mapping which Postgres versions (14 through the upcoming 19) changed the underlying mechanics while the core recommendations largely held. Highlights for Postgres 19 (currently in beta) include SIMD-accelerated COPY parsing, ON_ERROR SET_NULL, LZ4 becoming the default TOAST compression algorithm, native REPACK CONCURRENTLY, native MERGE/SPLIT PARTITION syntax, COPY TO working directly on partitioned parents, autoscaling async I/O workers, parallel autovacuum workers, and JIT being turned off by default after being on since version 12. The piece closes with a checklist of advice that remains unchanged across all these releases.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.crunchydata.com/blog/postgres-19-how-our-advice-has-changed-since-we-wrote-it>

## Questions this post answers

### What is the default TOAST compression algorithm in Postgres 19?

LZ4 becomes the default TOAST compression algorithm in Postgres 19, replacing pglz, via the default_toast_compression setting flipping from pglz to lz4. LZ4 has been available since Postgres 14 via explicit configuration, but as of Postgres 19 new toasted values use it automatically with no extra config. Existing toast values from before the upgrade keep whatever algorithm compressed them until rewritten.

_Teams tuning storage costs on Postgres upgrades can track compression and TOAST changes like this on daily.dev._

### How does Postgres 19's COPY ON_ERROR SET_NULL option work during bulk loads?

ON_ERROR SET_NULL, new in Postgres 19, keeps a row during a COPY load but replaces only the invalid field's value with NULL instead of discarding the entire row, unlike ON_ERROR ignore which drops the whole line. It pairs with LOG_VERBOSITY to report what was nulled and can be combined with REJECT_LIMIT (from Postgres 18) to cap tolerated bad rows when using ignore mode.

_Developers hardening CSV and JSON ingestion pipelines can follow COPY option changes like this via daily.dev._

### Is JIT compilation on or off by default in Postgres 19?

JIT is off by default in Postgres 19, reversing the behavior it had since Postgres 12 when it was enabled by default. The change happened because the old cost model for deciding when to JIT-compile was unreliable, so large analytical or parallel scans that previously compiled at runtime will no longer do so unless jit is explicitly re-enabled after upgrading.

_Engineers planning a Postgres 19 upgrade can watch for default flips like this through daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@agustinbarrientos** · 0 upvotes

> ON_ERROR finally takes some drama out of dirty imports

**@pdfopsdev** · 0 upvotes

> the JIT flip is the interesting part, defaulting off after years of on because the cost model can't be trusted is postgres basically admitting the heuristic never worked well. worth rechecking explain plans on analytical workloads before you upgrade, don't assume 14->19 parity.

**@rizzdev** · 0 upvotes

> REPACK CONCURRENTLY leaves pre-swap snapshots looking at an empty table

---

Tags: [#database](https://daily.dev/tags/database), [#postgresql](https://daily.dev/tags/postgresql), [#data-engineering](https://daily.dev/tags/data-engineering)

[View this post on daily.dev](https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Postgres 19: How Our Advice Has Changed Since...","url":"https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg"},"datePublished":"2026-08-18T19:11:09.036Z","dateModified":"2026-09-13T19:32:51.112Z","description":"A deep retrospective revisits years of Crunchy Data's Postgres advice on COPY, TOAST, BRIN indexes, covering indexes, and partitioning, mapping which Postgres...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8823d01a6373dba5ab7e3b2066bb7386?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8823d01a6373dba5ab7e3b2066bb7386?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Crunchy Data","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Crunchy Data","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/689da8cf2d2a4fa4b09736e4f4b18fce","url":"https://daily.dev/sources/crunchydata"},"commentCount":3,"discussionUrl":"https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":38},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":3}],"keywords":"database,postgresql,data-engineering","timeRequired":"PT17M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Crunchy Data","item":"https://daily.dev/sources/crunchydata"},{"@type":"ListItem","position":3,"name":"Postgres 19: How Our Advice Has Changed Since..."}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg","comment":[{"@type":"Comment","text":"ON_ERROR finally takes some drama out of dirty imports","datePublished":"2026-08-21T01:33:40.744Z","url":"https://daily.dev/posts/viIa8jZFG#c-6cheloTtN","author":{"@type":"Person","name":"Agustin Barrientos","url":"https://daily.dev/agustinbarrientos","image":"https://media.daily.dev/image/upload/s--5ayxQnqn--/f_auto/v1788281802/avatars/avatar_wQYYVe5Tbj0NJ7C7qPoa8?_a=BAMAMicg0"}},{"@type":"Comment","text":"the JIT flip is the interesting part, defaulting off after years of on because the cost model can’t be trusted is postgres basically admitting the heuristic never worked well. worth rechecking explain plans on analytical workloads before you upgrade, don’t assume 14-&gt;19 parity.","datePublished":"2026-08-19T18:04:24.467Z","url":"https://daily.dev/posts/viIa8jZFG#c-VsyRJjAq9","author":{"@type":"Person","name":"PDFops","url":"https://daily.dev/pdfopsdev","image":"https://media.daily.dev/image/upload/s---8isRBKc--/f_auto/v1782922291/avatars/avatar_orjMeK8QKaaVZwGq7ScPz?_a=BAMAMicg0"}},{"@type":"Comment","text":"REPACK CONCURRENTLY leaves pre-swap snapshots looking at an empty table","datePublished":"2026-08-21T16:53:46.947Z","url":"https://daily.dev/posts/viIa8jZFG#c-tmdM4xSOn","author":{"@type":"Person","name":"Andrew","url":"https://daily.dev/rizzdev","image":"https://media.daily.dev/image/upload/s--35vRfXAA--/f_auto/v1785413727/avatars/avatar_fQ7ttCKtPuu6tDvcgQXv5?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/postgres-19-how-our-advice-has-changed-since--viia8jzfg#faq","mainEntity":[{"@type":"Question","name":"What is the default TOAST compression algorithm in Postgres 19?","acceptedAnswer":{"@type":"Answer","text":"LZ4 becomes the default TOAST compression algorithm in Postgres 19, replacing pglz, via the default_toast_compression setting flipping from pglz to lz4. LZ4 has been available since Postgres 14 via explicit configuration, but as of Postgres 19 new toasted values use it automatically with no extra config. Existing toast values from before the upgrade keep whatever algorithm compressed them until rewritten. Teams tuning storage costs on Postgres upgrades can track compression and TOAST changes like this on daily.dev."}},{"@type":"Question","name":"How does Postgres 19's COPY ON_ERROR SET_NULL option work during bulk loads?","acceptedAnswer":{"@type":"Answer","text":"ON_ERROR SET_NULL, new in Postgres 19, keeps a row during a COPY load but replaces only the invalid field's value with NULL instead of discarding the entire row, unlike ON_ERROR ignore which drops the whole line. It pairs with LOG_VERBOSITY to report what was nulled and can be combined with REJECT_LIMIT (from Postgres 18) to cap tolerated bad rows when using ignore mode. Developers hardening CSV and JSON ingestion pipelines can follow COPY option changes like this via daily.dev."}},{"@type":"Question","name":"Is JIT compilation on or off by default in Postgres 19?","acceptedAnswer":{"@type":"Answer","text":"JIT is off by default in Postgres 19, reversing the behavior it had since Postgres 12 when it was enabled by default. The change happened because the old cost model for deciding when to JIT-compile was unreliable, so large analytical or parallel scans that previously compiled at runtime will no longer do so unless jit is explicitly re-enabled after upgrading. Engineers planning a Postgres 19 upgrade can watch for default flips like this through daily.dev."}}]}
```

