You can't read a pg_dump file the way you read a table. To see what is inside, you normally restore it into a PostgreSQL server first.
pg_restore and grep can list the tables without a restore, and even print a table's rows as raw text. They can't filter, sort or join them.
The free PostgreSQL Dump Viewer opens a pg_dump without a server. It replays the dump into a real PostgreSQL inside your browser tab and shows the tables, rows and foreign keys. You can run read-only SQL on it, and the file is never uploaded.
Before restoring a dump, you often need one small answer: is this the right backup, which schemas does it contain, are the rows you need actually there? Starting a server, restoring, waiting and then running one query is sensible for a real recovery. It is too much ceremony for a received backup or a pre-restore check.
Restoring a database puts it back into service; inspecting a dump answers a question about a file.
For inspection, the first things I want are usually the database tree, a table preview, the declared foreign keys, and read-only SQL. If I find what I need, I might export that result as CSV or JSON. If I do not, I have learned that before setting up a server and committing to a restore.
That is why we built the PostgreSQL Dump Viewer. It replays the dump into a real PostgreSQL running inside the browser tab. The file never leaves your computer, and the temporary database is gone when you close the tab.
The result is deliberately narrow: browse schemas and tables, inspect relationships, run read-only PostgreSQL SQL, and export a result. It is not a production restore service.
| PostgreSQL Dump Viewer | Restore into a PostgreSQL se |
|---|
I’m happy to share that I was a guest on the Rails Business podcast and the episode is now live. Here’s a recap of the topics we discussed.
We spent most of the time discussing engineering work last year related to scaling the database workload for peak traffic at Aura where we use Ruby on Rails and PostgreSQL.
I’m presenting this information in two places this fall, Rails at Scale Summit in Austin, TX, and the Postgres Summit in NYC.
Besides the podcast, you can get more details in these posts:
If you’re not able to make those events or prefer to listen to a discussion of the content, then the podcast will have a lot of the same information.
Besides the work at Aura, we also checked in on my book High Performance PostgreSQL for Rails, which has now been available in print for two years. Ryan asked about what’s next for the book, and it’s a difficult question to answer.
With the availability and quality of AI tooling for software engineers, I don’t see developers buying books as much. With fewer prospective readers, the ROI is less attractive for authors and publishers to commit to the resource-intensive process of creating a book.
I’m grateful to have had the opportunity to write a book before the rise of the AI tools. I’m still getting positive feedback from my book which is very fulfilling.
Recently I met Madison Sites who’s a reader, and they shared feedback that they’re reading the book as part of the WNB.rb book club. Madison said the book has been helpful for building vocabulary and familiarity with database concepts and implementation details, and that’s helped with database work and better comprehension for conference talks about similar topics. I appreciated hearing about that!
We segued into how we
[...]
With PGConf.dev 2027 now on the horizon, I found myself thinking back to PGConf.dev 2026 and all the moments that stayed with me.
What started with two accepted talk submissions for the Community Day at PGConf.dev 2026 turned into four days filled with community discussions, anniversary celebrations, hallway conversations, poster sessions, unconference discussions, and countless opportunities to meet the people behind PostgreSQL.
Some moments made me think. Some made me laugh. Others reminded me why I enjoy contributing to this community so much.
Between my first PGConf.dev, my recent transition to Microsoft, two accepted talks, a community coin I didn’t expect, and a brief moment of wondering whether I belonged, this conference turned out to be far more memorable than I anticipated.
Some moments stayed with me...
PGConf.dev 2026 took place in Vancouver, Canada. I decided to arrive a few days early, for several reasons:
I have attended many PostgreSQL conferences in Europe over the years, and one thing I always enjoy is seeing how every event develops its own personality.
PGConf.dev immediately felt different.
PGConf.dev (2024–2026), formerly known as PGCon (2007–2023), it is a conference for people who actively build PostgreSQL. And when I say build PostgreSQL, I do not only mean writing code.
PGConf.dev brings together: PostgreSQL committers and code contributors, Documentation writers, Infrastructure maintainers, Meetup organizers, Community o
[...]October's hacking workshop will cover my talk, pg_plan_advice: Plan Stability and User Planner Control for PostgreSQL?. If you're interesting in joining us, please sign up using this form and I will send you an invite to one of the sessions.
Read more »
A recent question on the community channels described a difficult situation: a standby had been promoted with archive_mode=off, and restarting the new primary was something the team wanted to avoid. Could they enable archiving on a downstream standby and take a pgBackRest backup from there instead?
Their attempt failed with archive_mode must be enabled, even with archive-mode-check=n. Removing the checks from pgBackRest’s source code allowed their proof of concept to succeed, but was that enough to trust the approach?
My recommendation was to return to a supported configuration, either through a restart or a controlled switchover. But I wanted to take a closer look and see whether archive-mode-check=n might allow the standby-based approach.
So, in this post, we’ll try to reproduce the situation, examine what pgBackRest checks, and see why a successful backup and restore don’t tell the whole recovery story.
archive_mode matters
The test environment consists of three VMs running AlmaLinux 10 and PostgreSQL 18: pg1, pg2, pg3. We’ll set up cascading replication: pg1 → pg2 → pg3.
pg1)
Let’s first set up pgBackRest on the primary (pg1):
/etc/pgbackrest.conf:
[global]
repo1-path=/shared
repo1-retention-full=4
log-level-console=info
log-level-file=detail
compress-type=zst
start-fast=y
[demo]
pg1-path=/var/lib/pgsql/18/data
The configuration here is relatively simple: we will store WAL archives and backups on a /shared drive accessible from all hosts involved.
postgresql.conf:
archive_mode = on
archive_command = 'pgbackrest --stanza=demo archive-push %p'
Remember, changing archive_mode requires a PostgreSQL restart, while changing archive_command only requires a reload.
$ pgbackrest --stanza=demo stanza-create
$ pgbackrest --stanza=demo check
$ pgbackrest --stanzaIt’s been a month since I published the first part of this research, and interest from the Postgres community has been higher than I expected. Most vendors I contacted were shy to respond, so the Databricks team’s blog post Collaboration makes us all stronger was one of the first examples of a vendor publicly sharing their side of the story.
In the past four weeks, I spoke with managers of managed Postgres services, security engineers, and red teamers who look for new threats in the services they offer. Here’s what I learned from those conversations:
My initial plan was actually write about PostgreSQL core vulnerabilities but the coordinated work with the vendors takes longer than I expected. As the time flies and given that I only have a 40-minute talk at PGCONF.EU, there’s simply no way I’ll be able to cover everything I gathered in a single session. So I want to share all the things I wont be able to cover at the talk here as a blog post.
In this article you will see the vulnerabilities I have found on PostgreSQL vendors’ security hardening extensions and the broader threat model discussion.
A few months ago, when I first logged in to a managed Postgres provider’s instance, I noticed I didn’t have superuser rights. Still, I could update all the data and set up features that usually require superuser rights. But I wasnt the superuser. This made me wonder how and why they set it up this way.
The answer is pretty simple. When a new PostgreSQL backend starts, custom security extensions step in and check queries to decide if the user
[...]A long time ago I ran a write-heavy system on a hub and a handful of workers. Each worker took a share of the application traffic and wrote events locally. The hub owned the reference data (customers, plans, prices), pushed it down to the workers, and pulled every worker’s events back up to compute the invoices. The plumbing was Londiste and PgQ: triggers on every table, a queue per node, a ticker, and a Python daemon per hop. It worked, and it was a lot of moving parts to explain to anyone new.
Postgres 10 shipped logical replication in 2017, and 19 is the tenth release that has it. Every release since Postgres 10 has taken a piece of that plumbing and made it a line of SQL.
This is the first article in a series about Postgres logical replication use-cases, and about how the feature set has evolved over the past ten years and ten releases. The question is the application developer’s one, not the DBA’s: which architectures can I deploy with Postgres core alone today, what does each release change about that, and where do I still need something else? I built three architectures for real, across three posts:
A fourth post, covering what is left out of this series in less detail — geo-replication, BDR-style multi-active setups, plain CDC and triggers — is also planned.
If I could give one piece of advice to the past me, starting to contribute to open source projects, it’d be to value other developers' time more. It took me a while to appreciate the “economy” behind this, and adjust how I work to increase my chance of getting patches done. Hopefully some new contributors could learn from my mistakes.
On the server this article was written against, pg_stat_statements_info.dealloc reads 20, and that counter is all the database has left to say about forty rows an agent deleted. The forty entries were there while the DELETE statements ran, one per table, counted and timed like anything else. Then the same agent read the schema twice over, 12 800 statements that changed not one row, and the reading needed room.
The eviction is documented behaviour rather than a defect. The view is sized once, at 5 000 entries by default, and once more distinct statements arrive than that the documentation says "information about the least-executed statements is discarded". Run once, a statement is the least-executed thing in the database.
Ordinary application traffic sits at the far end of the axis that policy implies, since an application issues a small set of statements a great many times each. An agent writing its SQL fresh on every turn does the reverse, and the rewriting adds a second cost on top, because a question asked in two shapes occupies two entries and each of those two has been called once.
-- comment and a public. prefix all merged into the baseline, while count(1), a table alias, a swapped predicate order, a subquery and a CTE each took an entry of their own.
queryid on PostgreSQL 18, where 17 kept them apart, and the surviving entry carries the name of whichever schema was queried first.
application_name set to payments-api and one to claude-agent, landed in the same entry, so an agent borrowing the application's login cannot be separated from it after the fact.
track at its default top, a statement inside a PL/pgSQL function or a DO block leaves no entry of its own, and the samRelational databases like Postgres provide many unique features, specifically atomicity, consistency, isolation, and durability (ACID), but providing durability has always been a challenge. Though computers originally used non-volatile magnetic-core memory, the past five decades have been dominated by computer architectures where CPU-accessible memory is volatile, and OS-accessible storage is non-volatile/durable. Postgres uses the write-ahead log (WAL), which is stored on OS-accessible durable storage, to provide durability. (I recently wrote a presentation about WAL, and I have a presentation explaining durability.)
However, using OS-accessible storage for durability adds complexity. What if CPU-accessible memory, where most of the database processing happens, could be made durable in a high-performance and cost-effective way? This has been a goal of memory manufacturers for over twenty years, and it might finally be ending in failure.
Variously called phase change memory (PCM), 3D XPoint, Optane, and non-volatile Compute Express Link (CXL), the technology allows durable CPU-accessible memory to be mixed with volatile DRAM in the same system. This 30-minute video covers the fits and starts of the effort, and its eventual abandonment by Micron and Intel. This 2012 article summarizes frustration with the industry, "Long-derided as a Techno-Ponzi scheme — useful for raising a development budget but never delivering a return — PCM may now finally start earning its way in the world."
On 16 September 2026, the Postgres Meetup for All user group met, organized by Elizabeth Christensen and Ryan Booz. Ryan Booz and Greg Potter delivered a talk.
On 18 September 2026, Claire Giordano and Aaron Wislang hosted and published a new podcast episode “25 years of contributing to Postgres with Peter Eisentraut” from the Talking Postgres series.
On September 19 2026, the Postgres Bangalore (PGBLR) user group met, organized by:
Speakers:
Community Blog Posts:
I did it! The most important thing I anticipated after leaving DRW was having more time for important work, and one of the top items on my to-do list was the pg_acm update.
I already knew about two dozen bugs I needed to fix; several new functions people asked about. In addition, I had several conceptual changes in mind. Do you know how disturbing it is when you know you need to do something, and you can’t focus on that “something” because other things, less important but more urgent, keep popping up?
Finally, a rainy Saturday came! I promised myself not to look for a break in the rain, and not to even think about going biking, until I am done. Full disclosure: I am not done with the most boring and most important part: documentation! However, I figured I should at least publish the code and let people criticize it! And bug me about documentation!
My goal is to finish the documentation update before PG Conf.EU, where I am going to give a talk about pg_acm. Can you imagine how excited I am about this opportunity?! That’s why I want to be ready beforehand. I hope that some non-artificial intelligence will discover some bugs and ask some intelligent questions.
Please check it out: pg_acm
I used AI tools to size an OLTP workload on an EC2 system, with DBT-5, a TPC-E-like fair-use implementation. I provided a systematic and mechanical plan for running a series of tests to determine what the appropriate scale factor is on a system.
I pre-configured the database with some settings that are known to be needed to be changed, such as shared_buffers and max_wal_size but more on this at a later time when we characterize the system behavior further to be able to tune some of these settings better. Remember, this is an iterative process when trying to figure it out for any workload.
I decided to use Claude Fable 5.1 for this exercise and fed in the following instructions:
The following chart illustrates the sum of all the testing from starting at a 5000 customer database, up to a 97,000 customer database:
We need to zoom in a little bit to see that the best result for this system is at 32,000 customers with 24 users: It's worth mentioning that during this exercise, Claude also ran some smoke tests at various times to make sure everything was working. There were some minor fixes, but a significant improvement was to actually spend the time to allow multiple Trade Results and Market Feed transactions to be handled concurrently. It's been pointed out at lea[...]The future of Postgres is bright. So bright in fact, that I spent almost a dozen posts expounding on the upcoming features it would bring, with veritable stars in my eyes. Unfortunately, while I was out counting my chickens, it would seem some of these exciting new features failed to hatch.How, and perhaps more importantly why that happened, deserves some investigation.
Postgres events in Scotland now have a permanent address: postgres.scot
It is a deliberately small page. Right now it points at the PostgreSQL Edinburgh User Group (PostgresEDI) on cloomba, where you will find RSVPs, a calendar subscription and an RSS feed, and it will carry other Scottish Postgres events as they come along. The point is to have one address worth bookmarking and sharing, rather than whichever platform we happen to be on this year.
If you are running something Postgres-related in Scotland and want it listed, email info (at) postgres.scot.
postgres.scot is a volunteer website, not affiliated with or endorsed by the PostgreSQL project or the PostgreSQL Community Association.
Thursday, August 13th, Paterson's Land at the University of Edinburgh, two talks, pizza and refreshments sponsored by pgEdge, and the rest of the evening at the Tolbooth Tavern, one of the few pubs nearby that was not hosting an Edinburgh Fringe show that night.
Torsten Förtsch
Torsten Förtsch on replaying the stream of changes into the target database
Torsten started from a move to Aurora and the question of what "your data" actually means once the database is somebody else's service. His answer was to rebuild point-in-time recovery at the logical level: a pg_dump for the base copy, a stream of changes captured with wal2json in place of archived WAL segments, and replay into a database you control, on whatever operating system and Postgres version you like.
He took us through both halves of that. Capture and replay turned out to be 35 lines of jq translating the JSON change stream into SQL statements, with some care over how those statements are written so they find the right row quickly. The harder half is the initial copy: working out which position in the stream a dump corresponds to, so that replay starts in exactly the right place. He finished with where he wants to take it, incl
Two client connections, opened one after the other through PgBouncer transaction mode, asked the same database whose rows they were allowed to see, and the second one got the first one's answer. It had set nothing, it had never met the first caller, and the rows it read belonged to that caller's tenant. Any runbook that keeps a tenant key in a session variable sits one pooler away from this, and since 28 July the MCP protocol carries no session of its own, so a tool call from an agent arrives in this shape by default.
The setup is the one most multi-tenant guides teach. A row level security policy reads current_setting('app.tenant', true), each request or tool call opens with SET app.tenant, and on a connection nobody else is using the rows that come back belong to whoever asked for them. Through the pooler, the first call still behaves as written.
SET app.tenant = 'a';
SET
SELECT current_setting('app.tenant') AS tenant;
tenant
--------
a
(1 row)
SELECT tenant, body FROM docs;
tenant | body
--------+----------------
a | alpha invoice
a | alpha contract
(2 rows)
A second client connection, opened after the first one had closed and setting nothing of its own, then asks the database who it is working for and what it may read.
SELECT current_setting('app.tenant', true) AS inherited_tenant;
inherited_tenant
------------------
a <-- set by the caller before it
(1 row)
SELECT tenant, body FROM docs;
tenant | body
--------+----------------
a | alpha invoice
a | alpha contract
(2 rows)
Both callers ran on one backend, as did the two after them that switched the tenant to b and inherited it. When caller A's implicit transaction ended, PgBouncer released that backend and handed it over without sending anything in between that would have cleared app.tenant. Two changes made that shape the ordinary one. On 28 July 2026 the MCP specification took the session out of the protocol, its announcement stating that "Each request now travels on its
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.