Single-node · In-memory · gRPC

Heads up: I ended up switching to NATS + PostgreSQL. If you need consumer groups, bare NATS won't help — you need JetStream, which requires persistence. tinybroker fills the gap when you want in-memory consumer groups with no persistence overhead. The code works and is free to use; just know why you're reaching for it.

vs PostgreSQL LISTEN/NOTIFY

PostgreSQL’s LISTEN / NOTIFY mechanism lets database sessions send and receive asynchronous notifications. It is often used as a lightweight pub/sub layer when PostgreSQL is already the primary store.

Use PostgreSQL LISTEN/NOTIFY when

  • You are already using PostgreSQL and want minimal infrastructure additions.
  • Notifications are tightly coupled to database events (e.g., notify on row insert via a trigger).
  • Message volume is low and notifications are informational only — a missed notification is recoverable by querying the table.
  • You want transactional notifications: NOTIFY inside a transaction fires only if the transaction commits.

Use tinybroker when

  • You need consumer groups. NOTIFY broadcasts to every LISTENing connection — there is no mechanism to deliver a notification to exactly one recipient from a pool. Implementing balanced delivery on top of LISTEN/NOTIFY requires advisory locks or a coordination table, which turns a simple primitive into a distributed systems problem.
  • You do not want message routing to burden your database. A busy NOTIFY loop (high frequency events, many listeners) adds connections, WAL pressure, and processing overhead to PostgreSQL. A broker exists so that event fan-out is not the database’s problem.
  • You need wildcard topic patterns. LISTEN takes a literal channel name — there is no pattern matching. Subscribing to a dynamic set of channel names requires issuing one LISTEN command per channel, which does not scale for dynamic topic spaces.
  • You need confirmable receipt. NOTIFY delivers at most once. If a listener is not connected at the time of the notification, the event is lost — permanently. tinybroker holds messages in-channel until delivered or the channel is dropped.
  • You want clear separation of concerns. Using your primary database as a message bus couples two different failure domains. A slow query or a long transaction can stall notification delivery; an overloaded notification queue can affect query performance.

Summary

LISTEN/NOTIFY is a useful shortcut for simple database-event broadcasting, but it is a broadcast primitive, not a message broker. Consumer groups, pattern routing, and reliable delivery are not features it was designed to provide, and building them on top requires non-trivial application code that essentially reimplements a broker. At that point, a dedicated broker is cleaner.