AI-First, AI-Ready, AI-Accountable, AI-Value-Driven. Four phrases now crowd enterprise strategy decks. They aren’t stages, and they aren’t interchangeable. They’re four questions every leader needs to answer about the same piece of work.
In more than twenty years of building data platforms for banks, insurers, telecoms, and healthcare organizations, I’ve rarely met an enterprise with an AI vocabulary problem. Most have an AI meaning problem.
Watch a leadership team over a single quarter, and you’ll see it. The organization declares itself AI-First in the town hall, asks whether it’s AI-Ready in the architecture review, worries about being AI-Accountable in the risk committee, and promises the board it will be AI-Value-Driven. Four phrases, four meetings, often four different owners, and rarely a shared understanding of how they relate. Are they stages to climb? Different ways of describing the same ambition? Slogans that change depending on who’s presenting?
They’re none of those. Each is a distinct executive question about the same piece of work. An organization that answers one and ignores the others ends up with an impressive demonstration, a production system nobody fully trusts, or a business case that quietly falls apart once the real costs surface.
I explored these distinctions in my LinkedIn series, Beyond AI Buzzwords, which built on my earlier series, What AI-Ready Actually Means. This article brings that thinking together and takes the argument further. An enterprise isn’t transformed by AI because it deploys more intelligence. It’s transformed when it can rethink how work gets done, execute reliably, govern the authority it delegates, and demonstrate sustained business value.
Abstractions are easy to agree with and harder to act on, so let’s examine all four terms through a single, ordinary business process: a customer refund.
It’s unglamorous, which is precisely why it’s useful. A refund touches customer reco
[...]
No, this is not in commemoration of the late Tim Curry. After repeatedly writing about the Swiss PGDay, I want to share a personal impression from the European PostgreSQL conference 2026.
PGConf EU is the main European PostgreSQL conference, and one of the biggest (or the biggest?) worldwide. With upwards of 700 attendees, it is a crowd rather than a family reunion. It attracts people not only from all parts of Europe, but from all around the world. The conference is held in a different city every year, and it is the place to go if you want to feel how strong PostgreSQL has grown over the years (the 2010 PGDay — the first I attended — was a cosy little event in comparison). In 2026, there are five parallel tracks of talks, and still I have to count myself lucky that my talk was accepted!
Slonik (from Slavic “slon”, which means “elephant”) is the name of the elephant logo and mascot of PostgreSQL. Now the PostgreSQL license is pretty liberal, but the project protects its trademarks with teeth and claws. Among them is the Slonik logo (the name “PostgreSQL” is also protected, but its use in blogs is explicitly allowed).
Slonik isn't only a logo. The elephant regularly makes an appearance at PostgreSQL conferences, greeting the crowd and posing for pictures. There are two mysteries around Slonik:
This blog is about the second question.
PostgreSQL conferences wouldn't be possible without the work of the organizers. Amazing as the work of this group is, you cannot run a conference of that size with just eleven people. It takes a lot of volunteers to take care of everything: the registration desk, room hosts, cleaning up, etc. Volunteering at a PostgreSQL conference is a great way to get to know the peop
[...]On 4 November, the PostgreSQL Meetup Group Berlin met.
Organized by:
Speakers:
On 6 November, Claire Giordano and Aaron Wislang hosted and published a new podcast episode “How I got started in Postgres with Magnus Hagander from the Talking Postgres series.
On 6 November, the Hyderabad PostgreSQL User Group met, organized by
Speakers:
Multimedia contributions:
Also posted in Microsoft Blog for PostgreSQL
I recently worked with a customer planning a migration from on-premises PostgreSQL to Azure Database for PostgreSQL. During performance testing, they noticed something troubling: a query that completed in tens of milliseconds would now take 1-2 seconds in the Azure environment being evaluated.
The query was using an index scan, and running it again was fast. But once the relevant data was evicted from cache, the long execution time came back. Naturally, the conversation turned toward storage performance. There was a clear difference in IOPS consumption, with the to-be-production server having 10-20% more IOPS consumption than a server they stood up for comparison purposes. A cold-cache query execution that performed a single Index Scan pulled over 100 pages from heap, whereas the other server only pulled 60 pages. The natural inclination was to think that somehow bloating and/or fragmentation was the cause, so they tried VACUUM FULL but did not see any improvement. That’s when they turned to us.
The primary concern that the customer had – an Index Scan was not performing as well as expected – surfaced two hypotheses: something was wrong with the index, (i.e., bloat, leaf density, fragmentation), or something was wrong with the storage. Digging in with pg_stattuple and pg_statindex, we didn’t see anything glaringly wrong with leaf density or fragmentation. We also saw nothing from our telemetry that anything was wrong with the storage. With the usual suspects out of the picture, we needed to get back to the basic principles of indexing.
It is important to remember that when it comes to indexing a table, a regular index scan uses the index to locate matching tuples, then visits the table’s heap pages to retrieve them. The index is ordered; the heap doesn’t have to be.
Suppose a query returns 200 rows. If those rows live on five heap pages, Postgres can retrieve t
[...]In the previous post I argued that migrations don’t earn Git’s protections by being made of files: two incompatible schema changes live in two separate migration files, so there is nothing to textually conflict, and both branches merge clean. The repository accepts the pair without comment.
That post ended with a claim: the collision is not resolved in the repo, so it must be resolved somewhere else — at apply time, per environment, inside the database. This post is that claim, run for real. What actually happens when the pair lands?
I ran the collisions on PostgreSQL 16 to find out. The answer comes in two flavors — one loud, one silent — and the silent one is worse.
None of what follows is an argument against migrations, or against the defensive idioms people write in them. Every tool below does exactly what it promises. The point is what those promises do and don’t cover once two branches meet.
Branch A adds a column to users. Branch B renames users to accounts. Semantically incompatible; textually invisible to Git; both merged.
Each environment applies the migrations in whatever order they arrive — and the order can differ between environments, because branch merge order and migration timestamp order are two different clocks. So I built two databases and applied the pair in both orders:
-- env_one: add column, then rename
ALTER TABLE ✓
ALTER TABLE ✓
-- env_two: rename, then add column
ALTER TABLE ✓
ERROR: relation "users" does not exist
env_one is fine. env_two is broken — and its migration run has now halted partway, with everything after the failed file left unapplied.
Note what this means operationally: the same pair of migrations produces a healthy database in one environment and a failed deploy in another, decided by application order alone. If your staging environment happened to apply them in the survivable order, staging is green and the failure is waiting in production. The
[...]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.
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.