NewsDatabases

PostgreSQL 19 Beta 1 Is Out: 5 Features That Matter

Data visualization dashboard showing PostgreSQL 19 performance improvements with elephant logo and bar charts

PostgreSQL 19 Beta 1 landed on June 4, and it’s the most developer-friendly Postgres release in years. This one doesn’t just add features — it removes years of accumulated workarounds. ON CONFLICT DO SELECT delivers true atomic upsert semantics in a single statement, SQL/PGQ brings graph queries to your existing relational tables, and online table maintenance gets two major upgrades. The stable release targets September/October 2026. If you’re running Postgres in production, now is the time to test.

The Upsert Hack Is Finally Dead

Since Postgres 9.5 introduced ON CONFLICT in 2016, developers have been living with a workaround: ON CONFLICT DO UPDATE SET col = EXCLUDED.col. A no-op update that forces Postgres to return the existing row. It works. It’s also a hack — and after a decade, Postgres 19 kills it.

The new ON CONFLICT DO SELECT returns the conflicting row directly, atomically, in one statement. No race conditions. No transaction wrappers. No ghost updates in your audit log. According to Neon’s benchmarks of the PostgreSQL mailing list tests, DO SELECT runs nearly 4x faster than the DO UPDATE no-op approach and 24% faster than the DO NOTHING CTE workaround.

-- Before Postgres 19: the no-op hack
INSERT INTO tags (name) VALUES ('postgresql')
  ON CONFLICT (name) DO UPDATE SET name = EXCLUDED.name
  RETURNING id;

-- Postgres 19: clean and atomic
INSERT INTO tags (name) VALUES ('postgresql')
  ON CONFLICT (name) DO SELECT
  RETURNING id;

-- With row locking for concurrent writes
INSERT INTO entities (external_id, source)
VALUES ($1, $2)
ON CONFLICT (external_id, source)
DO SELECT FOR UPDATE
RETURNING *;

One caveat: RETURNING is required — DO SELECT without it is a syntax error. You must also specify a conflict target explicitly. That said, both constraints are straightforward and don’t limit the practical value of the feature.

Graph Queries Without a Graph Database

Postgres 19 implements SQL/PGQ, the SQL:2023 standard for property graph queries. You define a graph over your existing relational tables — no new storage engine, no data migration, no Neo4j license — and query relationships using pattern-matching syntax. The feature lands directly in your existing Postgres deployment with no extensions required.

-- Define a graph over existing tables (metadata only, no data moved)
CREATE PROPERTY GRAPH store_graph
  VERTEX TABLES (customers LABEL customer, products LABEL product)
  EDGE TABLES (
    purchases SOURCE customers DESTINATION products LABEL bought
  );

-- Find products bought by customers who also bought a specific title
SELECT DISTINCT p2.name
FROM GRAPH_TABLE (store_graph
  MATCH (c IS customer)-[IS bought]->(p1 IS product WHERE p1.name = 'Postgres in Action')
        -[IS bought]-(p2 IS product)
  COLUMNS (p2.name)
);

The use cases are concrete: user-follows-user social graphs, product recommendation engines, access control hierarchies, dependency trees. For moderate graph needs where your data already lives in Postgres, SQL/PGQ eliminates an entire infrastructure dependency. However, this implementation supports fixed-depth pattern matching only. Variable-length paths — needed for BFS, DFS, or shortest-path queries — are planned for a future release. For serious graph workloads requiring those capabilities, a dedicated graph database is still the right call. The official PostgreSQL 19 property graph documentation covers the full syntax and current limitations.

Production Maintenance Gets Two Real Upgrades

REPACK is now a built-in command. Previously, online table rebuilding required the external pg_repack extension — a widely used but separately maintained dependency. In Postgres 19, REPACK TABLE large_table CONCURRENTLY handles it natively. The key difference from VACUUM FULL: the ACCESS EXCLUSIVE lock is held only briefly during the final file swap, rather than for the entire rebuild duration. For large production tables, that distinction is measured in hours of downtime avoided.

Autovacuum also gains parallelism. The new autovacuum_max_parallel_workers setting lets autovacuum process multiple indexes on a table simultaneously, instead of sequentially. On heavily-indexed tables — the ones that take the longest to vacuum — this dramatically reduces maintenance windows. Both settings are configurable globally in postgresql.conf or overridden per-table with ALTER TABLE.

One Breaking Change to Check Before You Upgrade

JIT (just-in-time compilation) is now disabled by default in Postgres 19, reversing the behavior since Postgres 12. The rationale from the PostgreSQL contributor who proposed the change: “JIT costing has been determined to be unreliable, so sites that are doing many large analytical queries must now manually enable JIT.” For OLTP workloads — short queries, high transaction volume — this change is neutral or slightly positive. JIT overhead no longer kicks in for queries that don’t benefit from it.

However, if you rely on JIT for long-running analytical query acceleration, set jit = on explicitly in postgresql.conf after upgrading. RADIUS authentication is also removed entirely in Postgres 19. Check the full PostgreSQL 19 breaking changes guide before scheduling your upgrade.

Key Takeaways

  • ON CONFLICT DO SELECT replaces the decade-old DO UPDATE no-op hack with atomic get-or-create semantics — nearly 4x faster and far cleaner
  • SQL/PGQ brings graph queries to existing relational tables via the SQL:2023 standard; fixed-depth only in Postgres 19, with variable-length paths planned for a future release
  • REPACK is now built-in (no more pg_repack extension dependency), and autovacuum supports parallel workers for faster maintenance on large, heavily-indexed tables
  • JIT is disabled by default — OLTP workloads are unaffected, but analytical workloads need jit = on set explicitly after upgrading
  • PostgreSQL 19 Beta 1 is available now; stable release targets September/October 2026 — test your workloads before then
ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News