After more than 20 years working with PostgreSQL, I keep seeing the same problems surface at the worst possible times - bloat that sneaks up on you, replication slots quietly holding back WAL, transaction ID wraparound that nobody caught in time, backups that silently stopped working weeks ago. There are also data and catalog corruption issues like TOAST table corruption or a mismatch between heap state and VM state causing problems with vacuum operations. What I always wanted was a single tool I could point at any PostgreSQL instance and get a clear, actionable picture of its health. So I built one.pg-healthcheck is an open source utility written in Go that runs 180+ checks across 14 groups, querying live PostgreSQL system catalog views directly… no estimates, no simulated data. It works against single PostgreSQL instances as well as pgEdge multi-node Spock clusters, and gives you either coloured terminal output or structured JSON you can feed into a monitoring pipeline.
Hot off the press: pgcopydb v0.18 is out!
It’s the biggest release the project has had — 88 commits since v0.17, which shipped in August 2024. I took a break from my Open Source responsibilities for a while, because I was lacking employer support to make it happen.
pgcopydb copies a PostgreSQL database to another PostgreSQL server, as fast as possible when physical file copy isn’t available. It parallelises the COPY across all tables simultaneously, builds indexes in parallel after data is loaded, and supports Change Data Capture via logical replication for minimal-downtime migrations. It is designed to be restartable: state is tracked in a local SQLite catalog so an interrupted run can resume where it left off.
v0.18 brings compatibility with PostgreSQL 16, 17, and 18; a pgoutput-default CDC engine with significant reliability and performance improvements; regular-expression-based filtering; Citus-to-Citus migration support; and 24 bug fixes.
The source code is available on Codeberg.
The extension is also available on PGXN.
The extension is also availabe through the PostgreSQL rpm packages.
This minor update solves a problem in the deinstallation script.
Due to the changes in version 1.0 with installation of objects in a schema of its own, the generated uninstall script did not work anymore.
The deinstallation does now also work when the extension is installed in a different schema name.
PostgreSQL community images address a real gap in how a Kubernetes database operator earns your trust. Running a database operator on Kubernetes means trusting two things: the code, and the container images the operator pulls. The code is on GitHub, easy to inspect, easy to fork. The container images, the registry that hosts them, and the license that governs them all sit with the vendor, and any of those three can change without the source repository changing at all. Starting with Percona Operator for PostgreSQL 3.0.0, you can run the operator against community images you build yourself from the official PostgreSQL packages on download.postgresql.org, in a registry you control.
In this post:
Open source has changed in the last few years, and not always for the better. Companies have learned that you can keep a project’s source code fully open and still capture most of the lock-in by quietly closing the parts that matter in production: the release artifacts, the container images, the supported OS list, the certified Kubernetes distributions, the marketplace listings.
You can have a fully community CNCF proj
[...]

© Laurenz Albe 2026 (see here for more background)
Recently, I helped a customer investigate database problems. It turned out that these problems could be traced back to too many tables in the database. Since this may come as a surprise to many users, I thought it worth the while to write about it.
There were two problems that sounded like they might or might not be related to each other:
The first step in investigating OOM problems is always to disable memory overcommit. I originally suspected other software running on the machine to cause the memory shortage, but memory context dumps showed that PostgreSQL was at fault.
There are several typical causes for high memory usage in PostgreSQL:
work_mem
However, it turned out that in this case, it was something else that hogged the memory.
After disabling memory overcommit, we got memory context dumps in the log file, as well as log entries from autovacuum workers that failed to fork because there was too little memory. Initially, the memory context dumps did not show anything interesting: they were from victims of memory starvation rather than from the culprits. That is also why I originally suspected causes external to PostgreSQL. But then we got some memory context dumps that looked as follows:
TopMemoryContext: 355016[...]
The most recent meeting of ISO/IEC JTC1 SC32 WG3 “Database Languages” took place from the 15th to the 19th of June 2026 in Stockholm. “WG3”, as we call it, works on standardizing the database languages SQL and GQL. In that meeting, a number of proposals that are of interest to SQL and PostgreSQL were accepted, which I want to report about here.
The meeting code of this meeting was “BMA”, which is the code for a small airport in Stockholm. All in-person WG3 meetings are named after a nearby airport. In this case, the code “ARN” for Stockholm’s main airport had already been used for a meeting in 2003. (It is whimsically intentional that this system prevents the group from meeting in the same place too many times.)
Now let’s look at the new SQL features that were discussed. (Regards to all the GQL practitioners, but I’m not qualified enough to report on that.)
(Note that when I write below that something has been accepted into the standard, that means it’s now in a working draft. There is still a bit of a road until all of this is an approved actual standard.)
The QUALIFY clause has been accepted into the standard. This clause is a filter like WHERE or HAVING but is applied after window functions. For example1:
SELECT product_name, category, price
FROM products
QUALIFY price > avg(price) OVER (PARTITION BY category);
Previously, you would have to do this filtering by wrapping the query in a subquery, like
SELECT product_name, category, price
FROM (
SELECT product_name, category, price,
avg(price) OVER (PARTITION BY category)
AS category_avg
FROM products
) AS q
WHERE q.price > q.category_avg
The QUALIFY clause is already a nonstandard extension in many SQL implementations. A patch for PostgreSQL was in progress for PostgreSQL 19, but it was paused because some definitional issues had to be resolved, which has now been done with the change proposal to the standard. So I think we can look forward to seeing progress on that for PostgreSQL 20.
Upgrading PostgreSQL 19 clusters has become more seamless with tools like pg_upgrade and pg_createsubscriber, which together enable near-zero-downtime upgrades by first converting physical replicas into logical subscribers and then performing the upgrade with minimal service interruption.
However, this approach exposes a long-standing gap in logical replication: sequence state is not replicated.
Having written about the Swiss PGDay in 2024, I need not repeat all I said back then. Nonetheless, I'd like to share my impressions from the Swiss PGDay 2026 with you.
The Swiss PGDay traditionally takes place on the campus of the University of Applied Sciences at Rapperswil. It is perhaps the most inappropriately named PostgreSQL event I know. Only a strong feeling for tradition can maintain the name “PGDay” for a two-day event with two tracks of talks!
Another tradition is the speaker's and organizer's dinner on the evening before the conference. Since I was lucky enough to have my talk selected, I knew that I could look forward to a pleasant evening good food and with friends. Friends? Yes, it is a business trip for me, and yes, some of the people there work for competing companies. But then, we can leave the competition to the sales departments, and let's be honest: PostgreSQL keeps growing in a healthy fashion, and there should be enough cake for everybody to get happy.
This time, the dinner took place in the fancy restaurant on the city hall building, prominently situated in the main town square. The food was truly excellent, and the friendly waiters made sure that the wine glasses didn't run dry. The high temperature that prevailed during the entire event couldn't quell a happy reunion with Dirk, Daniel and Tobias, who happened to share my table.
This year, my co-worker Svitlana was also present at the dinner — she has helped organize the event. Her example may serve to highlight what PostgreSQL conferences do to you: her professional duties don't revolve around core PostgreSQL, as she is the leading developer of our commercial CYPEX database application generator. Still, she attended last year's Swiss PGDay, and — what shall I say? — it looks like she got hooked.
If all this sounds to you like PostgreSQL is some kind of weird cult that sucks in innocent people and takes over their p
[...]In the previous post, I tried to lay out the framing half of this material: what actually counts as a disaster, why preparation and prevention aren’t the same as recovery, and how RPO and RTO end up being conversations with leadership rather than numbers an infrastructure team gets to declare on its own.
That part is largely about understanding the problem. This part is about actually building the capability to deal with it. And in my experience, this is where most teams quietly stumble – not because they don’t have backups or replication, but because they’ve never really practiced using either of them under stress.
Once you’ve accepted that DR is a process, the natural next step is to write some runbooks. And in my experience, this is where a lot of teams quietly stumble.
Runbooks usually get written by experts, for experts, in a calm conference room. That’s almost the opposite of the environment they’ll actually be run in. Real recovery happens at 3AM, under stress, often with incomplete information and sometimes with someone who isn’t deeply familiar with the system. A runbook’s job, really, is to reduce ambiguity in that moment – not to be a comprehensive description of the system, but to be the thing you can follow even when you’re tired and scared.
That framing alone changes what a good runbook looks like.
A few patterns I see often that make runbooks worse, not better:
On June 23 2026, the London PostgreSQL Meetup Group met. Organized by:
Speakers:
On June 23, 2026, the Meetup PostgreSQL Lille met. Organized by Stefan Fercot and Yoann La Cancellera. Both delivered a talk at this meetup.
Postgres User Group Frankfurt am Main met on 24 June 2026 where Marc Linster delivered a talk. The Meetup was organized by
On June 25 2026 the PostgreSQL User Group NL met for their Summer Edition. Organized by Gerard Zuidweg and Feike Steenbergen.
Speakers:
The Program Committee of PGDay UK 2026 met to finalize the schedule:
Swiss PGDay 2026 took place from June 25-26 2026. Organized by:
Talk selection team:
Speakers:
Lightning Talk Speakers:
Everyone knows not to store money as a double precision. One can hope. The rule is so well drilled that it has stopped being interesting, and it is also not where the trouble usually starts. The float is already in the schema before anyone weighs in on it: a measurement column someone later sums for a report, telemetry that drifts into a finance dashboard, a third-party feed ingested as double precision because that is how it arrived.
Here is the part the rule does not warn you about. Take a table of five million floating-point readings, sum the column, and run it three times in a row. Nothing else touches the table. Same connection, same data, same statement.
SELECT sum(reading) FROM measurements;
sum
--------------------
2500519211.7874823
sum
-------------------
2500519211.787477
sum
--------------------
2500519211.7874575
Three runs, three different totals. No UPDATE, no concurrent writer, no random seed. The rows did not change between runs, and the query is the same character for character. Yet the answer is not.
This is not a Postgres bug, and it is not specific to Postgres. It is what happens when floating-point arithmetic meets parallel aggregation, and it has been generating "my dashboard total changed and I have no idea why" tickets for as long as databases have parallelized. The non-determinism does not wait for you to opt into bad practice; it shows up the moment a parallel plan runs over whatever floats you happen to have.
One column of double precision, five million rows.
CREATE TABLE measurements (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
reading double precision NOT NULL
);
INSERT INTO measurements (reading)
SELECT random() * 1000
FROM generate_series(1, 5000000);
ANALYZE measurements;
Five million rows is enough that Postgres parallelizes the sum on its own. No settings forced, defaults all the way:
EXPLAIN (COSTS OFF) SELECT sum(reading) FROM measurements;
QUERY PLAN
--------------[...]
Why do we still waste time browsing YouTube and news sites looking for interesting content? Why rely on someone else's algorithm — when Claude, for instance, retains conversation history in one form or another and can therefore assess our actual interests? Maybe it's time to take control of shaping our own "information bubble"?
In systems programming, reliability, maintainability, and extensibility usually matter more than new features. That makes AI agents genuinely hard to apply well. If I'm being honest, I can't claim the technology has meaningfully moved the needle on our productivity — the bottleneck still sits squarely in review and QA. So when frontend colleagues share their excitement and start planning which industry to pick up next, I can only look on with envy.
That said, research, analysis, and internet scanning have become dramatically easier — I can now read Chinese colleagues' work without friction. Exploring the source code of adjacent OSS projects is where it genuinely shines: in five minutes, in a language I barely know, without any prior knowledge of the project structure, I can get answers to real questions, steal a few useful patterns, and learn from both the smart and the questionable architectural decisions. The pity is that work like this isn't my main job.
There is, though, one area where AI has become genuinely indispensable — saving me time and sanity every day: news filtering.
The technical infosphere — Planet PostgreSQL being a prime example — has increasingly filled with two kinds of content: posts that re-explain familiar database concepts for the thousandth time, and thinly veiled marketing whose real goal is to put a product in front of you. I have nothing against good marketing, but those of us who are here for the technology rather than the buying decisions find that it generates a persistent low-level background noise.
There is another dimension: pgsql-hackers has quietly started accumulating AI-assisted content. I’ve seen review feedback containing argum
[...]We often hear that open source is about people.
People who contribute their time and, in a way, parts of their lives to work on software that is available for everyone without limitations and without licensing costs.
The more popular a project becomes, the more often we also hear about the need for sustainable open source. Nothing surprising here. Often projects start off as “scratching ones itch” and it’s very appreciated when others notice the work done. The more time passes and the more the work becomes appreciated, the higher the chances that there will be a need to spend more time on the project.
Postgres has had native support for declarative partitions since version 10, and every release since has filed off another rough edge. We got partition-wise joins, default partitions, hash partitioning, and the ability to attach and detach partitions concurrently. By any reasonable measure, declarative partitioning is one of the great success stories of modern Postgres.Despite the power here, it's always been a kind of one-way ratchet. Creating or dropping partitions was easy. But reorganizing existing ones was a different beast entirely. There's no syntax or tool to assist in the event we want to convert a table to a partition set, or revise an existing design. Instead, it's just a long series of manual statements to carve the table up into partitions, or perhaps leveraging pg_partman to do it instead.Well, Postgres 19 finally has an answer to that. Let's talk about the current state of the art, and how the new and syntax for ALTER TABLE may change the story.
In the previous post, we discussed the basic syntax of graph queries in PostgreSQL 19 and discussed some simple SQL/PGQ examples. However, more often than not applications are more complex and need more than just two basic tables. Therefore, we want to dig a little deeper and see how we can write more complex queries and model some more sophisticated graphs based on real world scenarios.
To demonstrate a couple queries, which happen to be increasingly advanced, we have compiled some simple test data. The idea of the following data structure is to store friendship as well as work relations:
-- People (six rows, three cities)
CREATE TABLE person (
id int PRIMARY KEY,
name text NOT NULL,
age int NOT NULL,
city text NOT NULL
);
INSERT INTO person VALUES
(1, 'Alice', 30, 'Berlin'),
(2, 'Bob', 25, 'Berlin'),
(3, 'Carol', 35, 'Paris'),
(4, 'Dan', 28, 'Paris'),
(5, 'Eve', 40, 'London'),
(6, 'Frank', 33, 'London');
-- "Knows" edges between people (nine rows, two mutual pairs)
CREATE TABLE knows (
a int NOT NULL REFERENCES person(id),
b int NOT NULL REFERENCES person(id),
since int NOT NULL,
PRIMARY KEY (a, b)
);
INSERT INTO knows VALUES
(1, 2, 2018), (2, 1, 2019),
(1, 3, 2020), (2, 3, 2020), (3, 2, 2021),
(3, 4, 2021), (4, 5, 2022),
(5, 6, 2019), (6, 1, 2023);
-- Companies (the new vertex type for this post)
CREATE TABLE company (
id int PRIMARY KEY,
name text NOT NULL,
industry text NOT NULL
);
INSERT INTO company VALUES
(10, 'Acme', 'manufacturing'),
(20, 'Globex', 'finance'),
(30, 'Initech', 'software');
-- "Works at" edges (the new edge type for this post)
CREATE TABLE works_at (
pid int NOT NULL REFERENCES person(id),
cid int NOT NULL REFERENCES company(id),
role text NOT NULL,
since int NOT NULL,
PRIMARY KEY (pid, cid)
);
Key takeaways
Memory gives an AI agent continuity, but memory alone does not enable useful action. An enterprise agent must also determine what needs to be done, select the right systems and tools, execute each step safely, inspect the results, and revise its approach when reality doesn’t match its assumptions.
That’s three capabilities: planning, tool use, and reflection.
Planning translates a business goal into a sequence of executable steps. Tool use connects probabilistic model reasoning to deterministic systems — databases, APIs, workflow engines, code execution. Reflection lets the agent evaluate its own output, catch incomplete or unsafe results, and decide whether to retry, revise, or escalate.
Together, these move an agent past question-answering and into real business process participation. This installment uses PostgreSQL throughout to show how enterprise agents can query operational data, validate generated SQL, preserve execution state, and leave an auditable trail behind every action.
In Part 1, we covered why the model is not the system, and why memory is
[...]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.