A Common Database Feature Turns Out to Be Much Faster Than People Thought

A company called DBOS has shown that a built-in messaging feature in PostgreSQL — a popular open-source database — can handle 60,000 writes per second on a single server, with responses in about a thousandth of a second. The results, published July 24, 2026 in a post titled "Postgres LISTEN/NOTIFY Actually Scales," challenge a widely shared belief that the feature breaks down under heavy use. DBOS
That belief came from an earlier post by a company called recall.ai, which argued that the feature — called LISTEN/NOTIFY — "does not scale." In PostgreSQL, LISTEN/NOTIFY lets different parts of a database system send messages to each other, similar to how a group chat works: you listen on a channel, and when someone sends a message to that channel, you receive it. The earlier post led many developers to conclude that this built-in messaging system was not suitable for applications that need to process a large volume of events quickly.
DBOS's results push back on that conclusion, but with an important catch. They did not find that LISTEN/NOTIFY works well without any effort. They found that the performance problem has a specific cause and, with the right design, can be avoided.
The problem comes down to how PostgreSQL keeps messages in order. When a transaction — a unit of database work — includes a NOTIFY call, PostgreSQL locks the entire system so that no other notification-bearing transaction can proceed at the same time. It holds that lock until the transaction is fully committed and safely saved to disk. This lock exists for a good reason: PostgreSQL promises that messages will arrive in the same order as the transactions that sent them. To guarantee that, the database forces transactions to finish one at a time.
Under heavy use, every transaction that sends a notification has to wait behind this lock. DBOS's first attempt, which used LISTEN/NOTIFY in a straightforward way, could only reach 2,900 writes per second on a single server. Beyond that point, the lock became the main source of delay, and adding more workers did not help because they all had to wait their turn.
DBOS stores each piece of stream data as a new row in a database table. Writers add rows; readers use LISTEN to be notified when new data arrives instead of repeatedly checking the table for changes. The approach itself is not new — it is a familiar pattern for anyone building event-driven systems on PostgreSQL. The innovation is in how DBOS restructured its writes to avoid triggering the global lock on every single notification.
The jump from 2,900 writes per second to 60,000 on the same single server, with response times staying in the millisecond range, is the headline result. The 20x improvement comes from reducing how often and how long the lock causes delays during the commit process. DBOS has not published every detail of how the optimization works.
For teams building real-time systems on PostgreSQL, this finding changes a common decision. The usual advice when an application needs to handle more than a few thousand events per second has been to stop using LISTEN/NOTIFY and switch to a separate messaging system such as Redis, Kafka, or NATS. DBOS's results suggest that the limitation is not built into LISTEN/NOTIFY itself but stems from the specific way it is typically used.
The broader question is whether DBOS's approach works for everyone. The distinction between "LISTEN/NOTIFY does not scale" and "LISTEN/NOTIFY as commonly used does not scale" is not academic — it determines whether engineers add new infrastructure or first examine their own approach. The 60,000 figure was achieved on a specific workload with a specific design, and readers should treat it as proof that it is possible, not as a guarantee for every situation.
Still, proof that something is possible carries real value. It shifts the burden of proof. The next time someone reaches for a separate messaging system because "LISTEN/NOTIFY doesn't scale," the follow-up question is now better informed: at what speed, under what conditions, and have you actually checked where the slowdown occurs?


