What Is Pub/Sub (Publish/Subscribe)?
Pub/sub is one of the two core messaging patterns in distributed systems. It lets a service broadcast information without knowing who — if anyone — is listening. This page covers what the publish/subscribe pattern is, how it works, how it differs from a message queue, and how to implement it on Valkey and Redis from Java.
What is the pub/sub pattern?
Pub/sub (short for "publish/subscribe") is a software messaging pattern for asynchronous communication between decoupled components. Instead of calling each other directly, senders publish messages to a named destination and any interested receiver subscribes to it.
There are four concepts to know:
- Message: A serialized, discrete unit of communication exchanged between parties.
- Publisher: An application or service responsible for sending messages.
- Subscriber: An application or service that receives messages from one or more publishers.
- Topic: A named channel that carries messages about a particular subject.
The defining idea is that neither the sender nor the recipients need to be aware of each other's existence, so both can be developed, deployed, and scaled independently. Publishers don't know who is subscribed. Subscribers don't know who is publishing. The only shared contract is the topic name and the message format.
How pub/sub works
The flow is short:
- A subscriber registers interest in a topic.
- A publisher sends a message to that topic. It does not address any specific recipient and does not wait for a response.
- The messaging system delivers a copy of the message to every current subscriber of that topic.
- Each subscriber processes its own copy independently.
This is a fan-out model: one message in, many copies out. Adding a fifth subscriber to a topic does not require any change to the publisher, which is what makes pub/sub the usual choice for broadcasting state changes across a system.
Pub/sub vs. message queue
Pub/sub and message queues are often mentioned together, but they solve opposite problems.
A message queue implements point-to-point delivery. A message goes onto the queue and is delivered to exactly one consumer. When several consumers read from the same queue they act as competing workers, and the system load-balances messages between them. This is the right model for distributing work — background jobs, image processing, outbound email — where each unit of work should be performed once.
Pub/sub implements one-to-many delivery. Every subscriber to a topic gets its own copy of every message. This is the right model for broadcasting facts — notifying billing, analytics, and search indexing that an order was placed — where each recipient does something different with the same information.
A useful rule of thumb: if adding a second consumer should halve the work each one does, you want a queue. If adding a second consumer should duplicate the message so both can react, you want pub/sub. Most real systems use both, which is why a full message broker supports queues and topics side by side.
Pub/sub vs. observer pattern
The pub/sub pattern is frequently compared with the observer pattern, another messaging style from software design.
In the observer pattern, a single object known as the "subject" (or "observable") maintains a list of its dependents, the "observers". When the subject changes state, every dependent observer is updated automatically.
The two differ in coupling and in cardinality. The observer pattern is one-to-many and the participants know each other directly: the subject holds references to its observers. Pub/sub is many-to-many and the participants are anonymous to one another: publishers can send to multiple topics, subscribers can receive from multiple publishers, and neither holds a reference to the other. The observer pattern also normally runs in a single process, whereas pub/sub is typically used across process and machine boundaries.
Pub/sub delivery guarantees
Not all pub/sub is equally reliable, and this is where implementations differ most. The questions that matter in production are:
- What happens if a subscriber is offline? In a fire-and-forget system the message is simply lost. In a durable system it is retained and delivered when the subscriber reconnects.
- Are messages acknowledged? Without acknowledgments, a subscriber that crashes mid-processing loses the message permanently. With acknowledgments, unconfirmed messages can be redelivered.
- Can messages be replayed? Durable, log-based systems let a new or recovering subscriber read history from a position, ID, or timestamp. Ephemeral systems cannot.
- What happens to messages that keep failing? Mature systems cap redelivery attempts and route exhausted messages to a dead-letter destination instead of retrying forever.
These properties are what separate at-most-once delivery (fast, lossy) from at-least-once delivery (durable, requires idempotent consumers). Choosing between them is an architectural decision, not a configuration detail.
Pub/sub benefits and use cases
The benefits of the pub/sub pattern include:
- Efficiency: Subscribers do not poll for new messages. Messages are pushed as they are published, which matters for real-time applications.
- Scalability: Decoupling publishers from subscribers lets each side scale and change independently, and lets you add new consumers of an existing message stream without touching the producer.
- Simplicity: Integrating many applications point-to-point creates a combinatorial mesh of connections, each a potential failure point. Pub/sub replaces that mesh with connections to a small number of topics.
Typical use cases include real-time notifications and chat, live dashboards and telemetry, cache invalidation across application nodes, fan-out to downstream services, and event-driven architectures, where services publish facts about state changes rather than issuing commands to one another.
Pub/sub in Valkey and Redis
Valkey and Redis are in-memory data structure stores commonly used to implement key-value databases, caches, and message brokers. Both ship with a native publish/subscribe implementation, and the commands are identical across the two.
The PUBLISH command sends a message to a channel:
PUBLISH sports oilers/7:leafs/1
The SUBSCRIBE command registers interest in a channel:
SUBSCRIBE sports
This is genuinely fast and simple, but it is strictly fire-and-forget. Messages are pushed only to subscribers that are connected at the moment of publication. There is no persistence, no acknowledgment, and no replay — if a subscriber is restarting, deploying, or briefly partitioned, the messages published during that window are gone. For loss-tolerant traffic such as cache invalidation or live presence updates, that trade-off is often the right one. For anything where a missed message means a missed order, it is not.
Streams address part of this: they provide a durable, append-only log with consumer groups and acknowledgments, so messages survive restarts and stalled consumers can be reclaimed. Higher-level reliability features — delivery limits, dead-letter destinations, message priority, delayed delivery — are not built in and have to be implemented in application code.
Pub/sub in Java with Redisson
Valkey and Redis speak the RESP wire protocol rather than any single language's API, so Java applications connect through a client library. Redisson maps the pattern onto a familiar Java interface, RTopic, with typed messages and listener callbacks instead of raw commands:
RTopic topic = redisson.getTopic("orders");
topic.addListener(OrderCreated.class, (channel, message) -> {
System.out.println("Order created: " + message.getOrderId());
});
// in another thread, service, or JVM
RTopic topic = redisson.getTopic("orders");
long clientsThatReceivedMessage = topic.publish(new OrderCreated("A-1001"));
RTopic comes with synchronous, asynchronous, reactive, and RxJava interfaces, so you can use whichever programming model fits your application. Redisson also improves availability by automatically resubscribing listeners after a failover, which the raw protocol does not do for you.
For a full walkthrough with configuration and pattern-matching topics, see our guides to pub/sub in Java and Valkey pub/sub in Java.
Reliable pub/sub with Redisson PRO
Where the native pattern falls short, Redisson PRO adds Reliable PubSub: durable publish/subscribe built on a topic → subscription → consumer model, with configurable retention, message replay by position, ID, or timestamp, automatic redelivery of unacknowledged messages, and dead-letter topics. It turns the data store you already run into a broker-grade messaging layer without deploying and operating a separate broker cluster.
Redisson PRO also implements the JMS API (2.0, 3.0, and 3.1), so Java teams can use JmsTemplate, @JmsListener, Spring integration, and JNDI lookups against Valkey or Redis. For the full picture, see the complete guide to Reliable PubSub and the messaging documentation.
Pub/Sub: Frequently Asked Questions
What is the difference between pub/sub and a message queue?
A message queue delivers each message to exactly one consumer, so multiple consumers share the work. Pub/sub delivers a copy of each message to every subscriber, so multiple consumers each react to the same information. Queues distribute work; pub/sub broadcasts facts.
Is Redis pub/sub reliable?
Native Redis and Valkey pub/sub is not reliable in the durability sense. It is fire-and-forget: messages go only to subscribers connected at the moment of publication, with no persistence, acknowledgment, or replay. For guaranteed delivery you need Streams, or a client such as Redisson PRO that provides Reliable PubSub on top of Redis or Valkey.
Does Valkey support pub/sub?
Yes. Valkey is an open-source fork of Redis and supports the same PUBLISH, SUBSCRIBE, and PSUBSCRIBE commands with identical semantics, including the same fire-and-forget delivery model.
What is the difference between pub/sub and Redis Streams?
Pub/sub pushes messages to currently connected subscribers and retains nothing. A Stream is a durable, append-only log: messages are stored, consumers track their position, consumer groups distribute work, and unacknowledged messages can be reclaimed. Use pub/sub when losing a message is acceptable, and Streams when it is not.
Is pub/sub the same as event-driven architecture?
No. Pub/sub is a messaging pattern — a mechanism for delivering a message to many recipients. Event-driven architecture is an architectural style in which services communicate by publishing and reacting to events. Pub/sub is one of the mechanisms commonly used to implement it, but you can use pub/sub without being event-driven, and you can build event-driven systems on queues or logs instead.
What happens if no subscriber is listening to a topic?
In a fire-and-forget system such as native Valkey or Redis pub/sub, the message is discarded and nothing is stored. In a durable system such as Streams or Reliable PubSub, the message is retained according to the configured retention policy and delivered once a consumer appears.