These are thirteen things I measured in one sitting. Each one is small. A few of them surprised me anyway.
PostgreSQL 18.6, built from source, default settings (work_mem 4MB, shared_buffers 128MB, 2 parallel workers per gather). MacBook Air M5, 10 cores, 24 GB RAM, internal SSD. This is a different machine from my earlier posts, so don't compare times across posts.
Most tests use one table of 2,000,000 orders: 50,000 customers, 5% of rows with status open, created_at increasing every 10 seconds, and an md5 string in note. Query times are EXPLAIN (ANALYZE, BUFFERS, TIMING OFF) execution time, median of 5 runs after one warm-up run (3 runs for the slower ones). Buffers are from the top plan node. Sizes are decimal MB. The script and the raw results are linked at the bottom.
A partial index only holds the rows its WHERE clause allows.
| Index on customer_id | Size | Buffers for one customer's open orders |
|---|---|---|
| all rows | 14.2 MB | 43 |
WHERE status = 'open'
|
0.7 MB | 2 |
It only gets used when the query's WHERE matches the index condition.
BRIN stores a summary per block range instead of one entry per row. Rows were inserted in created_at order, which is the case it is built for.
| Index on created_at | Size | Count one day (8,640 rows) |
|---|---|---|
| B-tree | 44.9 MB | 0.55 ms, 134 buffers |
| BRIN | 24 kB | 0.63 ms, 137 buffers |
The table itself was 202.3 MB. I didn't test BRIN on shuffled
[...]My last post leaned hard on the DB-Engines ranking, and I admitted that ranking measures popularity, not installed base or revenue. Several of you called me on that, politely and otherwise. Fair enough.
So this time I went looking for evidence that does not come from one ranking site. Usage surveys: where the money is going, what cloud vendors are building, and what AI tools reach for when nobody tells them what to use. My conclusion has not changed, but I think the case is much stronger than I made it out to be.
The best usage number I can find comes from developers themselves. In the 2025 Stack Overflow Developer Survey, 55.6% of all respondents said they use PostgreSQL, up from 48.7% in 2024. Among professional developers it was 58.2%, roughly 18 points ahead of MySQL (summary of the survey). It also topped the admired and desired lists again.
That is still a survey, not an install count. But it is people saying "I use this," not people searching for it, and that is a different signal from the one DB-Engines measures.
Three caveats on my own napkin math from last time:
Last time I wrote that big data and AI vendors have been buying PostgreSQL companies, and I did not name them. Here they are.
|
Date |
Bu |
|---|
This year's PostgreSQL Conference Europe, PGConf.EU 2026, took place from October 20th to 23rd in wonderful Valencia, at the Palacio de Congresos. There was far too much going on to cover it all, so I'm just going to go over what I was involved with: a panel on Tuesday, a book signing on Wednesday, a talk on Thursday, and three Community Events on Friday. That still leaves out the hallway track, and the many discussions there on everything from Postgres heisenbugs to the core development workflow to community building.
Obligatory selfie from PGConf.EU 2026
On Tuesday afternoon I joined Ants Aasma, Mayuresh Bagayatkar, Hettie Dombrovskaya, Pavlo Golub and Teresa Lopes for Postgres On-Call Confessions: Worst Practices 101, a panel on the "Postgres in production" topics everyone shies away from. We started with the common threads in where we've seen Postgres fail at scale and in production, but also the most embarrassing and funniest incidents each of us has personally witnessed. Then the mic was open for anyone in the audience to come up and confess an "obvious fix" of their own that backfired in production.
The Postgres On-Call Confessions panel, left to right: Pavlo Golub, me, Mayuresh Bagayatkar, Ants Aasma, Teresa Lopes and Hettie Dombrovskaya
On Thursday morning I had the pleasure of presenting radar + radar-analyst: Agentless Diagnostic Snapshots for PostgreSQL.
The starting point is familiar to anyone who has worked in support. A monitoring agent only helps if it was already running before things went wrong, the Postgres log only shows what your queries did, and the rest of the picture takes a dozen emails back and forth. radar is a single static Go binary that collects a snapshot of PostgreSQL and the host it runs on into one zipfile, in seconds, and then exits. It collects metadata only (catalogs, statistics and configuration), and never row data or passwords.
radar-analyst is what you do
[...]In my last post I walked through a rolling major version upgrade: add a brand new node on the new version, let it join the Spock cluster, retire the old node. It works well, but it assumes you can stand up an extra server for every node you need to upgrade. A lot of customers I talk to cannot. Either the hardware is not there, or the database is too big to hold a second full copy.For them there is a second option. Upgrade each node in place with . The node being upgraded does go down, but in a multi-master cluster the other nodes keep taking writes the whole time, so the application never loses a writable endpoint. The downtime belongs to one node, not to your users.I tested this end to end on the same lab I used for the rolling post, taking one node from PostgreSQL 17.10 to 18.6, including its Patroni managed standby. It worked, but not without a few surprises that the standard playbook will not warn you about. This post covers exactly what I ran.
I just gave a new presentation at FOSS4G North America titled Can AI Write SQL? The talk is a follow-up to my Building an Mcp Server Using Postgres talk, and explores how well AI can write SQL queries, and how to help AI be more effective.
pg_settings, reload versus restart, max_connections, reserved connections and TCP keepalives
This is Part 1 of a four-part series based on the talk “The “default” postgresql.conf, step by step”, which I gave at PGConf.EU 2026 in Valencia on 21 October 2026. The slides can be found here.
A 45-minute talk leaves no room for test output, for the mechanism behind a setting, or for the questions people asked afterwards. A blog post has that room, so these posts contain a few extras that were not in the talk.
A new PostgreSQL installation starts with conservative defaults. They are chosen so that Postgres starts on almost any hardware, from a coffee machine to a small virtual machine, and they are not tuned for the server you actually run. The defaults improve from release to release, but you still need to read the documentation carefully to know which ones to change. Real servers have more memory, faster disks, unstable networks, connection poolers and applications that leave transactions open.
At Data Egret, we look after many PostgreSQL clusters. When we set up a new cluster or take over an existing one, we almost always start by applying the same set of changes. We call that set “our default postgresql.conf”. It is not a tuning guide for one specific workload. It is a baseline that is safe on most production servers and that a DBA who is new to PostgreSQL can apply and understand. Its values depend on the capabilities of your hardware and on common problems of a typical OLTP workload, not on one specific application. From this starting point, you adjust, test and improve further. This series goes through that baseline step by step: for each setting, what it does, what the default is, what we change it to and why, and what a change takes (a reload, a restart or just a SET in a session).
All defaults in this series are PostgreSQL 18 defaults, and all output was taken from PostgreSQL 18.6 from the community Debian pack
[...]On 27 Oct, the Warsaw PostgreSQL User Group met.
Organizers:
Speaker:
On 30 October, PostgreSQL PG Down Under 2026 took place.
Organizers:
Talk Selection Committee:
Speakers:
On 30 October, the Prague PostgreSQL User Group met, organized by Mayur B. and Gülçin Yıldırım Jelínek
Speakers:
Community Blog Posts:
Right after the Apache Software Foundation's Community Over Code in Glasgow, we found ourselves the following day in Edinburgh for our October meetup, where Elizabeth Christensen (Snowflake) went over what's new in Postgres 18 and 19.
Elizabeth Christensen walking us through the Postgres versions timeline
Thanks to everyone who came along on Thursday, October 15th, to Elizabeth for joining us all the way from Kansas, and to pgEdge for the pizza and refreshments. It was also great to see David Christensen there with Elizabeth.
Elizabeth Christensen (Snowflake)
Elizabeth is an open source advocate on the Postgres team at Snowflake, a Postgres contributor and a board member of the United States PostgreSQL Association, and she runs the online Postgres Meetup for All. She came to go over Postgres 19, which had been pencilled in for the end of October, and the parts of 18 that went by unnoticed.
The first thing to know about 19 is that it has slipped. An unusually large number of features were reverted during the beta, which Elizabeth framed as the sign of a healthy project, because the process caught things, and some of them, such as the SQL property graph queries, are already lined up again for 20. Testing the betas is one of the easiest contributions anyone can make, and with the community packages, Docker or Postgres.app it is a few minutes' work. The background on the reverts is in her post on the Snowflake blog, What Is Happening with PostgreSQL 19?
From there she went through the two releases in five parts, all demonstrated on Bluebox, her Pagila-derived sample database of DVD rentals, which is worth a look on its own if you ever teach or demo Postgres.
uuidv7(), virtual generated columns, and OLD and NEW in RETURNING from 18, then INSERT ... ON CONFLICT DO SELECT and IGNORE NULLS in window functions from 19. Temporal primary keys with WITHOUT OVERLAPS, also in 18, rThe November 2026 DB-Engines rankings are out. PostgreSQL is the only database in the top four whose line is going up and to the right.
Oracle, MySQL and Microsoft SQL Server all lost points this month, and all three are down from a year ago. PostgreSQL gained points on both counts. It now sits just 3.84 points behind SQL Server for third place. On the past year's trend, PostgreSQL could move ahead of SQL Server as early as next month.
So it's time to celebrate, right? Maybe not yet. Before anyone orders the cake, let's look at what the numbers say, why people are moving, and how hard the next step up will be.
Only PostgreSQL gained points this month, and only PostgreSQL is up from a year ago.
Source: DB-Engines Ranking of Relational DBMS, November 2026.
A little napkin math shows when the order could change:
The long-term chart tells the same story. PostgreSQL climbed from roughly 200 points in 2013 to almost 700 today. Over the same years, the top three slowly drifted lower. Further down the list, MariaDB has slipped since its 2022 peak.
One caveat: DB-Engines measures popularity, not installed base or revenue. The score comes from search interest, job postings, Stack Overflow questions, social media mentions, and similar signals. A rising score shows that people are talking about PostgreSQL, learning it and hiring for it. That isn't the same as running more production workloads on it.
In 2014, if you wanted Postgres servers on several continents, each of them accepting writes and all of them sharing their rows, there was one serious open source answer: BDR, from 2ndQuadrant. It needed a patched PostgreSQL 9.4 and a plugin, which means it needed a server that was not Postgres. Ten years of work on logical replication have since moved most of what BDR needed into the stock server, and in this article we build the same kind of system with Postgres 19 release candidate 1 and pg_auto_failover, to see how far that incremental progress has taken us, and what is still left to build.
This is the last article of a series on logical replication, and it should read fine on its own. In Part 1 we built a hub-and-workers system for write scalability, in Part 2 we consolidated several databases into one warehouse, and in Part 3 we did a zero-downtime major upgrade.
TL;DR We built five regions out of pg_auto_failover groups and core logical replication, and tested them by killing primaries under load. Every acknowledged row survived, every region ended with the same rows, and a fifth region joined the running system with five statements and no pause. Core now does the hard parts: row filters, loop prevention, failover-safe slots, sequence synchronization, and it counts conflicts. It still doesn’t replicate DDL, so schema changes are a short pause, or pglogical or pgcopydb when a pause isn’t an option. It doesn’t resolve conflicts or hand out unique ids to several writers either, and we avoid both by construction.
Again, apologies for the delay. PGConf.dev was back in May, and it has taken me until November to follow up on Part One.
This part is about "Establishing the PostgreSQL standard: What's Postgres compatible?", the session I ran with Hettie Dombrovskaya on the Tuesday afternoon in Vancouver, in the Community Discussion track of PGConf.dev 2026.
It follows on from the working session Hettie, Boriss Mejías and I organised at PGConf.EU 2025 in Riga, and from the talk at FOSDEM in February where Daniël van Eeden and I looked at the question from the Postgres and MySQL sides.
What came out of Riga is written up on the PostgreSQL wiki as the Riga Consensus, so I won't go over it again here, except to say that it moved us from a single pass/fail certification to a granular matrix of tests.
A discussion about testing compatibility gets further when there is something concrete to test with, so shortly before the session I published postgres-compat, a reference implementation of the Riga framework, and our slides walked through the decisions it makes.
It runs three test engines and writes one report. For most of the SQL language it writes no tests of its own, and instead runs PostgreSQL's own pg_regress and pg_isolation_regress suites verbatim against the target, 200 regression tests and 117 isolation specs, comparing the output byte for byte.
YAML probes cover what the upstream suites can't express against an arbitrary server, such as silent failures, runtime configuration and the behaviour of contrib extensions. The directory tree of the probes is the taxonomy itself, with one file per topic under each of the three Riga domains.
The decisions we put up for discussion were these:
This years conference took place in Valencia, Spain, from Tuesday October 20 until Friday, October 23. We had a whole conference center for the conference, the Palacio de Congresos Valencia.
In previous years the first day was training, later community stuff. Now it is the last day for the community day events.
In the opening talk Magnus Hagander introduced our new big Slonik.
I was honoured to be part of the Talk Selection Committee and part of the DBA and Internals Subcommittee.
We had more than 450 talks submitted. Some abstracts where near a whole talk. And as the committee has to read all of them to make fair choices, that is not fair to the committee members.
Some time ago I wrote a blog post about it.
This year I submitted a new version about Time Traveling PostgreSQL.
It included some new PostgreSQL 19 features.
As my computer disabled my network, the Docker container with PostgreSQL 19 release candidate 1 could be started, but not accessed.
But as a backup I had all queries and results copied in my slides. Being prepared for the worsed saved me.
The speaker gifts where really nice and unique.
The box contains some Spanish sweets.
A glazed tile with the conference logo.
Don’t underestimate the value of Hallway Talks. You can meet people again that you only meet at conferences, and you obviously can make new contacts.
Sometimes you are just doing smalltalk, sometimes it gets into ideas of how to solve a certain problem.
Sometimes a discussion ends in someone going deep down into a rabbit hole after the conference, read the block Radim Marek “Getting rid of a 4 TB table in PostgreSQL”.
I did not attend as much talks as I had planned to. But this year all talks where recorded if the speakers agreed to taking the videos.
There will be a lot of talks I have to see as soon
[...]
Every memtable table now has an arena with a proper lifecycle, but nothing is stored in it. This post stores rows in the arena and reads them back with a full table scan. Along the way it shows what tuple format to use for efficiency, how any backend finds the arena of a table, how space is handed out inside the arena, and the format of TIDs and why they are needed. It also settles which rows a transaction is allowed to see, since two backends can now work on the same table at the same time. Finally, it follows two sessions at work and revisits the TRUNCATE from Part 6 with rows in the table, which shows why each TRUNCATE gets a new arena.
In Part 4 to Part 6 you could see how an arena is created when a table is created, how it is released when the table is dropped, and how that stays correct when a transaction or a savepoint rolls back, or when the table is truncated. All of it happened without a single row in the arena. This post adds INSERT and SELECT. Rows can only be added and read at this point. There is no DELETE, no UPDATE, and no way to find a row other than reading all of them.
Before rows can be stored in the arena, there are three things to sort out:
A tuple table slot is a container holding rows for the executor. It is used, among other things, to pass information into and out from the table access method and also used in executing the plan tree. There are several different tuple table slot types defined in Postgres, and it is also possible for a table access method to define its own slot type.
Each scan, join, projection and sort use the callbacks for a tuple table slot instead of looking directly at the tuple representation. For example, a node can ask the slot for a particular attribute number of the tuple and get a datum back. All tuple table slots use a ba
[...]We’re excited to announce that sponsorship opportunities for 2027 Nordic PGDay are now available. Our event returns to Stockholm, bringing together attendees from all over the Nordic region. Developers, DBAs, and users, meet for a day of learning and networking.This years main conference will be held in Stockholm, Sweden, and for the first time we will also run an auxiliary event in Gothenburg - and sponsorships cover both!
Sponsoring is a great way to connect with the PostgreSQL community, gain visibility, and show your support for our open source community.
Details about sponsorship levels and benefits are available on our website. Spaces are limited and given on a first come first serve basis. Secure your spot early!
Please do not hesitate to reach out for any questions.
CloudNativePG is now a CNCF Incubating project, and it is a long way from the days when running PostgreSQL in Kubernetes was called an anti-pattern. This is a personal look at the road that led here: a cloud native initiative started at 2ndQuadrant in 2019, its quality-first mindset, the long-term support of EDB after the acquisition and the open sourcing of the project, a rejected Sandbox application in 2022 and the decision we took at KubeCon Atlanta. It also explains what Incubation means for PostgreSQL on Kubernetes, how the project governance and maintainer team are evolving, and our plan to apply for Graduation in 2027.
On Friday, 23 October 2026, the last day of PGConf.EU in Valencia, almost 40 practitioners, builders, and skeptics gave up a community-day morning to ask one question: how real is “Autonomous Postgres” today?
Marc Linster, Ryan Booz, and I organized the session as a working session, not a showcase. Ryan helped shape the agenda but couldn’t join us on the day. Marc has already shared his reflections, and I recommend reading them. This post is my own take: what I heard, the patterns I saw running underneath six very different talks, and where I think we, as a community, should build next.
Postgres is slowly changing from a system that DBAs operate to a system that increasingly operates itself. The talks showed that this change is already underway. They also showed where the real gap is.
Postgres is already one of the most trusted databases in the world. It doesn’t lose committed data, and it doesn’t hide what it did. The gap is that it can’t yet explain itself to an agent. What an agent needs to know depends on its job. A backup agent doesn’t need to know what “revenue” means, and an analyst agent doesn’t need the state of the WAL archive. But every agent needs its own slice of five things: what the system has, how it is organized, what the data means, how it normally behaves, and what it is allowed to change. Today, much of that knowledge lives in DBAs’ heads, runbooks, and dashboards, not in Postgres.
So the hard part is not making Postgres smarter. It is making Postgres legible: able to describe itself well enough that an agent can be trusted to act on it.
| What an agent needs to know | Who needs it most | What Postgres exposes today | What’s missing |
| What the system has | Every agent | Catalogs: databases, tables, indexes, extensions, settings |
Most database client reviews are a tour of the feature list. I wanted to know something narrower: when you open Navicat 18 and put it in front of a real table, which of the new features do you actually find, and which of them hold up?
So I connected it to PostgreSQL with a table of 10 million rows and went through the headline features one by one. This is the list of what I saw: what worked on the first try, what was hidden, and one AI answer that needed a second look.
A database holds your data, and to work with it you normally type SQL into a terminal (for PostgreSQL that is psql). A database client puts a window around that: you see the tables as a tree, write queries in an editor that warns you about mistakes, look at how a query will run, and move data between databases without writing scripts.
Navicat is one of the oldest of these clients. PremiumSoft, a company from Hong Kong, released the first version in 2002. Navicat Premium connects to many kinds of databases from one window: PostgreSQL, MySQL, MariaDB, Oracle, SQL Server, SQLite, MongoDB, Redis and Snowflake. It runs on Windows, macOS and Linux. It is commercial software, with a free Lite edition and a 14-day trial of the full version.
GitLab has a public story about deleting the wrong thing. In January 2017 an engineer who was trying to restore replication wiped a data directory they believed was on the secondary. It was on the primary. The postmortem they published afterwards is still one of the better things written about a database outage.
At PGConf.EU in Valencia last week a few people from GitLab came to me with the inverse problem. They have one table, 4 TB, on a primary with ten replicas, and they want it gone, on purpose, with as little impact as they can manage. It's an archival table: nothing writes to it, and nothing is supposed to read it.
DROP TABLE is the obvious answer and most of the time the right one. On eleven servers, a WAL (write-ahead log) archive and load balancer that routes reads by replica lag and the cost depends on three things. One is whether something still reads the table. The others are how much of it the kernel has cached and how the files sit on disk. So I measured it twice, on a Hetzner pair with a real streaming replica and on a GCE machine where a 1 TB table can't fit in the page cache. The other half is what happens when "nothing is supposed to read it" turns out to be only mostly true.
Everything ran on PostgreSQL 18.6 with data checksums on (the 18 default) and autovacuum off, so vacuum only runs when I say so. Sizes are as pg_size_pretty prints them, so a GB is 230 bytes. There are three setups.
A laptop (Docker, aarch64, 3 vCPUs, 12 GB RAM) with a 9.2 GB table, for everything that needs repeating. Two Hetzner machines on a private network, a ccx43 primary (16 dedicated vCPUs, 64 GB RAM, local NVMe) and a cpx62 replica (16 shared vCPUs, 32 GB RAM), both ext4 without discard, shared_buffers = 16GB, holding the same table at 192 GB, loaded by 16 parallel sessions.
And one GCE n2-standard-32 (128 GB RAM) with 16 local NVMe SSDs, used as one ext4 array for most runs, as an ext4 array and an XFS array of 8 SSDs each for the filesystem comparison, and with a standby con
It’s been exactly one month since I published my work porting Greenplum to PostgreSQL 19 and isolating the minimal PostgreSQL core patches needed to run this minimal fork. It all started as a way to extract its ORCA analytical query planner and turn PostgreSQL into a modern, vectorized, high-performance DBMS. And I pulled it off! After a month of development, the database keeps getting faster. I’m now working on a GPU version. Even as a rough draft, on my MSI Raider A18 HX A9W laptop it runs queries faster than LTS ClickHouse: on MergeTree, 1.9x faster by geometric mean and 1.3x by total time, and on vexec_parquet, 13x faster by geometric mean and 18x by total query time.
I’d like to share the results of pg_vexec, an experimental vectorized database that beats ClickHouse on query execution time on Parquet and nearly catches up on MergeTree. I’ve published the telemetry from its ClickBench runs. It should be an interesting read, with plenty of charts, metrics, DBMS logs and numbers from deep inside the engine: https://igor-suhorukov.github.io/sql_report/
What pg_vexec is: https://igor-suhorukov.github.io/blog/2026/10/07/vectorized-postgresql-extension/
Source code for the CPU version:
Number of posts in the past two months
Number of posts in the past two months
Get in touch with the Planet PostgreSQL administrators at planet at postgresql.org.