Pub/Sub vs REST API is one of the most common communication decisions in system design. A REST API is usually useful when one service needs an immediate response from another, while Pub/Sub is useful when something has happened and other services can react asynchronously. To understand when each approach makes sense, imagine placing an order on an e-commerce app.
Imagine placing an order on an e-commerce app.
You tap Place Order.
Behind that one button, several things may need to happen.
The payment needs to be authorised.
Inventory may need to be reserved.
A confirmation email needs to be sent.
The warehouse may need to be notified.
Loyalty points may need to be added.
Analytics may need to record the purchase.
A recommendation system may also want to learn from what you bought.
But here is the important system design question:
Should the customer wait until every one of these tasks is complete before seeing “Order Confirmed”?
Usually, no.
Some operations must happen before the system can safely confirm the order.
Other operations can happen a few seconds later.
That difference gives us one of the most important decisions in distributed system design:
Should services communicate synchronously through request-response communication such as a REST API, or asynchronously through messaging patterns such as Publish/Subscribe?
The answer is not simply “REST for small systems and Pub/Sub for large systems.”
The real answer depends on what the caller needs immediately, how much traffic the system handles, what happens during failures, how much temporary inconsistency the business can tolerate, and what the architecture costs to operate.
Let’s build that understanding from the beginning.
Pub/Sub vs REST API: The Short Answer
Use request-response communication such as a REST API when the caller needs an answer before it can continue.
Use Pub/Sub when something has happened and other systems can react to that event independently without making the sender wait.
An easy way to remember it is:
Need an answer now → Request-response
Something happened; others can react later → Pub/Sub
This simple rule gets us surprisingly far.
But a real architecture decision should also consider:
latency, throughput, scalability, reliability, consistency, coupling, and cost.
We will cover all of them.
What Is Synchronous Communication?
Synchronous communication means that one service sends a request to another service and waits for a response.
Think of a phone call.
You call a restaurant and ask:
“Do you have a table available at 8 PM?”
You normally stay on the call until someone answers.
Software can behave in the same way.
Suppose an Order Service wants the Payment Service to authorise ₹2,000.
The interaction might look like this:
Order Service
|
| Authorize ₹2,000
v
Payment Service
|
| Payment Approved
v
Order Service continues
The Order Service cannot safely continue until it receives the answer.
This is a good use case for synchronous request-response communication.
What Is a REST API?
REST is a common architectural style for building APIs over HTTP.
One application or service sends an HTTP request to another service.
For example:
GET /products/123
might ask:
“Give me the details of product 123.”
Another request might be:
POST /payments
meaning:
“Create or process this payment.”
In a typical request-response interaction:
Service A
|
| Request
v
Service B
|
| Response
v
Service A
Service A knows which service it wants to communicate with.
It sends a request.
Then it normally waits for the result.
That directness is one of REST’s strengths.
It also creates dependencies.
When Does Synchronous Communication Become a Problem?
Imagine our Order Service directly calls several systems.
Order Service
|
+--> Payment Service
|
+--> Inventory Service
|
+--> Email Service
|
+--> Loyalty Service
|
+--> Analytics Service
Now the customer’s request depends on several downstream services.
Suppose payment succeeds.
Inventory is available.
The order has been created.
But the Analytics Service is temporarily unavailable.
Should the customer be prevented from buying the product because analytics could not record the transaction?
Probably not.
The analytics update is useful.
But it is not necessary for completing the customer’s purchase.
That tells us something important:
Not every activity triggered by a request belongs inside the synchronous request path.
This is where asynchronous communication becomes useful.
What Is Asynchronous Communication?
In asynchronous communication, a sender sends a message or event without waiting for every downstream receiver to finish processing it.
Think of email instead of a phone call.
You send an email.
You do not have to keep your email application open until the recipient reads it.
The recipient can process the message later.
Software can behave similarly.
After successfully creating an order, the Order Service can announce:
OrderCreated
Other services can react to that event independently.
The Order Service does not need to wait for all of them.
What Is Pub/Sub?
Pub/Sub means Publish/Subscribe.
It is a messaging pattern in which one system publishes a message or event, and other systems subscribe to the events they are interested in.
A simplified architecture could look like this:
Inventory Service
^
|
|
Order Service ---> OrderCreated Topic ---> Email Service
|
|
v
Analytics Service
The Order Service is the publisher.
OrderCreated is the event.
The location to which events are published is commonly called a topic.
Inventory, email and analytics systems are subscribers or consumers.
Between publishers and subscribers there is usually messaging infrastructure such as a broker or managed messaging service.
Google Cloud describes Pub/Sub as an asynchronous messaging system that decouples the services producing messages from the services processing them.
The important architectural idea is decoupling.
What Does Decoupling Mean?
Suppose the Order Service directly calls four systems.
Order Service
|
+--> Inventory
+--> Email
+--> Loyalty
+--> Analytics
Six months later, the business creates a Recommendation Service.
If all communication is direct, the Order Service may need to be changed again:
Order Service
|
+--> Inventory
+--> Email
+--> Loyalty
+--> Analytics
+--> Recommendation
The Order Service keeps learning about more and more downstream systems.
The services become increasingly coupled.
With Pub/Sub, the Recommendation Service can subscribe to the existing OrderCreated event.
Inventory
^
|
|
Email
^
|
Order Service ---> OrderCreated Topic
|
+----> Loyalty
|
+----> Analytics
|
+----> Recommendation
The Order Service may not need to change at all.
It simply continues publishing:
OrderCreated
It does not need to know whether two services or twenty services consume that event.
AWS architecture guidance identifies this separation between publishers and subscribers as one of the major benefits of the publish-subscribe pattern.
This is called loose coupling.
Loose coupling can make systems easier to extend, scale and evolve.
REST and Pub/Sub Are Not Opposites
A common beginner mistake is thinking:
“Should I build the system with REST or Pub/Sub?”
Most real systems use both.
The right question is:
Which operations need synchronous communication, and which operations can happen asynchronously?
Consider checkout again.
The Order Service may need to confirm that payment succeeded.
That can remain synchronous.
Customer
|
v
Order Service
|
| REST Request
v
Payment Service
|
| Payment Approved
v
Order Service
After payment succeeds and the order is safely created, the Order Service can publish an event.
OrderCreated
|
+--> Send email
|
+--> Update analytics
|
+--> Add loyalty points
|
+--> Notify warehouse
|
+--> Update recommendations
Now we have a hybrid architecture.
And that is extremely common.
REST handles the information required immediately.
Pub/Sub distributes work that can happen independently.
REST Is Not Automatically Synchronous
There is an important technical detail here.
REST and synchronous communication are not exactly the same thing.
REST describes an API architectural style.
An HTTP API can accept a request without completing the entire job immediately.
For example, imagine asking a system to generate a large report.
Generating it may take several minutes.
Instead of keeping the connection open, the API might return:
202 Accepted
This means:
“The request has been accepted, but processing has not necessarily finished.”
The system may return something like:
/jobs/847/status
The client can check the job later.
So an HTTP or REST-style API can initiate asynchronous processing too.
The deeper comparison in system design is therefore:
direct request-response communication versus decoupled event-driven messaging.
REST is simply the most familiar example of request-response communication.
The First Decision: Does the Caller Need the Result?
This is the most important question.
Imagine the Order Service asking:
“Was this payment authorised?”
The next step depends on the answer.
If payment fails, the application should probably not tell the customer:
“Order successful.”
So the Payment Service might reasonably remain inside the synchronous flow.
Now think about analytics.
Does the customer need to wait until analytics records the purchase?
No.
What about a confirmation email?
Does the email need to physically arrive before the order can be considered created?
Usually not.
What about recommendation-model updates?
Certainly not.
Those are strong candidates for asynchronous processing.
So ask:
Does the caller need the receiver’s answer before continuing?
If yes, synchronous request-response communication often makes sense.
If no, asynchronous communication deserves consideration.
How Latency Affects REST vs Pub/Sub
Latency means how long something takes to respond.
Suppose checkout performs five operations sequentially.
Payment 300 ms
Inventory 200 ms
Email 400 ms
Analytics 300 ms
Loyalty 300 ms
If everything happens sequentially in the critical request path, those operations could contribute roughly:
1,500 ms
to the total workflow.
Real applications may execute some calls in parallel, so real latency will depend on the implementation.
The point is not the exact number.
The important principle is:
Every unnecessary synchronous dependency has the potential to increase user-facing latency.
Now imagine payment and inventory must finish immediately, while email, analytics and loyalty processing happen asynchronously.
The customer no longer has to wait for those non-critical tasks.
This is an important distinction:
Pub/Sub does not make the email service itself magically faster.
It removes email processing from the work the customer must wait for.
That reduces user-perceived latency and shortens the critical path.
What Is the Critical Path?
The critical path is the sequence of operations that must finish before the user receives the result they are waiting for.
For checkout, the critical path might be:
Validate Order
|
v
Authorize Payment
|
v
Reserve Inventory
|
v
Create Order
|
v
Show Confirmation
Email is not necessarily part of that path.
Analytics is not necessarily part of that path.
Loyalty points may not be part of that path.
Removing unnecessary operations from the critical path is one of the reasons asynchronous architecture can improve responsiveness.
Throughput: A Major Reason to Consider Asynchronous Communication
Latency and throughput are related, but they are not the same thing.
Latency asks: How long does one request take?
Throughput asks: How much work can the system process during a period of time?
Throughput might be measured as:
Requests per second
Transactions per minute
Orders per second
Events per second
Suppose your e-commerce application normally receives:
500 orders per second
During a major sale, traffic suddenly reaches:
5,000 orders per second
Now imagine every order directly triggers five downstream service calls.
Approximately:
5,000 orders/sec
×
5 downstream calls
=
25,000 downstream calls/sec
may suddenly hit your internal services.
Every dependent system now needs to keep up with the producer.
The Email Service needs capacity.
The Analytics Service needs capacity.
The Loyalty Service needs capacity.
The Recommendation Service needs capacity.
And they need that capacity at almost the same moment.
This is where asynchronous messaging becomes especially useful.
How Pub/Sub Helps With High Throughput
A messaging system can sit between producers and consumers.
Traffic Spike
|
v
Publisher
|
v
Message Broker
|
+--> Consumer A
|
+--> Consumer B
|
+--> Consumer C
The publisher can continue producing events.
Consumers process those events according to their capacity.
Suppose events arrive at:
5,000 events per second
but one downstream consumer can currently process only:
3,500 events per second
Instead of forcing the producer to slow down immediately, messaging infrastructure may temporarily hold the unprocessed events.
The consumer can process them later or scale by adding more instances.
This buffering capability can help systems absorb sudden traffic spikes.
It is one of the reasons event-driven architectures are useful for high-volume and high-velocity workloads.
Microsoft’s architecture guidance specifically identifies high-volume, high-velocity workloads and independent scaling of producers and consumers as situations where event-driven architecture can be valuable.
Does Pub/Sub Always Provide Higher Throughput Than REST?
No.
This is important.
A properly designed REST API can handle extremely high throughput.
Companies operate REST services processing enormous volumes of requests.
The advantage of Pub/Sub is not simply:
“Pub/Sub can handle more requests than REST.”
That would be misleading.
The architectural advantage appears when producers and consumers should not be forced to operate at exactly the same rate.
This is especially useful when traffic is bursty, different consumers process work at different speeds, multiple consumers need the same event, or downstream operations can happen later.
A much better system design question is:
Does every downstream service need to process this work immediately at the same rate at which the producer generates it?
If not, asynchronous messaging may give the architecture more flexibility.
What Is Backpressure?
Suppose events enter your system at:
10,000 events per second
but one consumer can process only:
6,000 events per second
The remaining 4,000 events per second do not magically disappear.
They start accumulating.
This growing backlog is related to a problem called backpressure.
Messaging systems help manage that pressure by separating ingestion from processing.
But they do not remove the underlying capacity problem.
The architecture still needs to monitor things such as consumer lag, queue depth, event-processing rate, retry rates and processing latency.
If the backlog keeps growing forever, eventually the system has a problem.
So Pub/Sub does not eliminate capacity planning.
It changes how the system handles temporary differences between incoming traffic and processing capacity.
Scalability Is Not the Same as Throughput
These terms are often confused.
Throughput means:
How much work can the system process?
Scalability means:
How well can the system increase its capacity when demand grows?
Imagine a service can currently process:
2,000 requests per second
That is its current throughput.
Now imagine adding more service instances allows it to process:
4,000
8,000
16,000 requests per second
without redesigning the whole system.
That demonstrates scalability.
Pub/Sub can help scalability because producers and consumers can often scale independently.
Suppose the Analytics Service suddenly requires more processing power.
You may increase the number of analytics consumers without changing the Order Service.
Likewise, the Order Service may receive more traffic without forcing every downstream system to scale in exactly the same way at exactly the same time.
That independent scaling is a major architectural benefit.
Cost: REST Is Often Simpler and Cheaper at Small Scale
Architecture decisions also affect cost.
Imagine Service A occasionally asks Service B for information.
A straightforward architecture could simply be:
Service A --> REST API --> Service B
Now imagine introducing Pub/Sub.
You may need messaging infrastructure, topics, subscriptions, message storage or retention, monitoring, consumer workers, dead-letter handling and additional operational tooling.
You may also pay based on message volume, throughput, data transfer, storage, broker capacity or another pricing model depending on the platform.
For a small workload, this can be unnecessary.
If direct communication solves the problem reliably, introducing an event platform may make the architecture more expensive without producing enough benefit.
This is why simple request-response communication is often economically attractive for simple workflows.
But cloud-service price is only one part of cost.
Infrastructure Cost Is Only One Part of System Cost
A better architecture decision considers total cost.
That includes infrastructure cost.
But it also includes compute cost, engineering cost, operational cost and failure cost.
Consider each one.
Infrastructure Cost
Pub/Sub or another messaging platform introduces infrastructure.
Depending on the technology, you may pay for message publishing, message delivery, throughput, data transfer, retention, storage or dedicated broker capacity.
REST infrastructure also costs money, but a simple synchronous architecture may involve fewer moving parts.
For a small application, fewer moving parts can be cheaper.
Compute Cost
Suppose every downstream service must be ready to handle peak traffic immediately.
If traffic normally runs at 1,000 requests per second but sometimes jumps to 10,000, you may need significant capacity available for those spikes.
Asynchronous messaging can sometimes smooth non-critical work across time.
Instead of forcing every consumer to process the entire spike immediately, some consumers can work through a backlog after traffic falls.
This can improve resource utilisation.
But it depends on the business requirement.
You cannot delay work that genuinely needs an immediate answer just to save compute cost.
Failure Cost
Technical architecture can affect business revenue.
Suppose a synchronous recommendation service becomes unavailable.
If checkout directly depends on it, customers may start seeing failed purchases.
Now the cost of that dependency may include:
lost transactions,
abandoned carts,
support requests,
customer frustration,
and potentially lost revenue.
If recommendations are not required to complete the transaction, placing them behind asynchronous messaging may prevent that non-critical failure from breaking checkout.
Sometimes paying for messaging infrastructure is far cheaper than allowing non-critical dependencies to disrupt revenue-critical flows.
Engineering and Operational Cost
Pub/Sub solves some problems.
But it also creates new responsibilities.
Teams need to understand event schemas.
Retries need to be designed.
Duplicate messages need to be handled.
Failed messages need somewhere to go.
Consumers need monitoring.
Events may arrive out of order.
Tracing one transaction across several asynchronous services becomes more difficult.
Consumer lag needs monitoring.
Eventual consistency needs to be understood by developers and product teams.
All of this requires engineering time.
Engineering time is also cost.
This is why the correct architecture is not always the architecture with the lowest cloud bill.
It is the architecture with the best total cost for the business requirement.
A Simple Cost Rule
For small, straightforward communication:
REST is often simpler and cheaper.
As systems become larger, more distributed and more event-heavy:
Pub/Sub may justify its additional infrastructure and operational cost by improving decoupling, resilience, scalability and workload management.
The key word is justify.
Do not add asynchronous infrastructure simply because large technology companies use it.
Add it because your system has a problem that asynchronous communication actually solves.
How Reliability Changes the Decision
Now imagine the Email Service is unavailable.
With direct synchronous communication:
Order Service ---> Email Service
❌
The Order Service now needs to decide what happens.
Should it retry?
Should it fail the entire order?
Should it continue without sending an email?
If the Email Service is inside the synchronous request path, its failure can affect the customer-facing operation.
Now consider asynchronous messaging:
Order Service
|
v
Message Broker
|
v
Email Consumer
❌
Depending on the messaging technology and its configuration, the event may remain available until the Email Consumer recovers.
The Order Service and Email Service no longer necessarily need to be available at exactly the same moment.
This is another form of decoupling.
Sometimes it is called temporal decoupling.
Does Pub/Sub Automatically Make a System Reliable?
No.
It changes the failure model.
Suppose an Email Consumer receives:
OrderCreated: ORDER-4821
The consumer successfully sends the email.
Then it crashes before acknowledging that the message has been processed.
The messaging platform may deliver that event again.
Now the consumer sees:
OrderCreated: ORDER-4821
for a second time.
Should the customer receive another confirmation email?
Probably not.
This leads to an important concept.
What Is Idempotency?
An operation is idempotent when repeating the same operation does not incorrectly repeat its business effect.
For example, the consumer could record that:
ORDER-4821 confirmation email already sent
If the same event arrives again, it avoids sending another email.
Duplicate delivery is a normal design consideration in many messaging architectures.
AWS guidance specifically warns that duplicate messages can occur depending on the messaging infrastructure and recommends designing consumers to handle duplicates safely.
What Is a Dead-Letter Queue?
Sometimes a message repeatedly fails.
Maybe the data is invalid.
Maybe the consumer has a bug.
Maybe a required field is missing.
Continuously retrying the same broken message may not help.
Messaging architectures commonly use something called a Dead-Letter Queue, or DLQ.
A repeatedly failing message can be moved aside for investigation.
Instead of blocking or disturbing normal processing forever, the system effectively says:
We could not process this event successfully.
Store it separately so it can be investigated.
Dead-letter handling is an important part of production messaging systems.
What Is Eventual Consistency?
Asynchronous architecture can also change how quickly different systems agree about the state of the world.
Suppose an order is confirmed at:
10:00:00
The Order Service already knows:
Order = Confirmed
But the Loyalty Service has not processed the event yet.
For a short time, the customer may see:
Order confirmed
while loyalty points have not appeared.
A few seconds later:
Order confirmed
Loyalty points updated
The systems were temporarily inconsistent.
Eventually they agreed.
This is called eventual consistency.
Microsoft’s event-driven architecture guidance identifies eventual consistency as one of the central trade-offs of asynchronous systems.
Whether it is acceptable depends on the business process.
A two-second delay in loyalty points may be fine.
A two-second uncertainty about whether money has already been withdrawn from an account may not be fine.
So another critical design question is:
Can the business tolerate a period during which different systems have slightly different versions of the state?
Strong Consistency vs Eventual Consistency
Strong consistency means users or services expect the latest agreed state immediately.
Eventual consistency allows different parts of the system to temporarily disagree while updates propagate.
Neither model is automatically better.
The requirement decides.
For example:
Send marketing analytics
can usually tolerate eventual consistency.
Update recommendation model
can usually tolerate eventual consistency.
Add loyalty points
often can too.
But:
Is this seat still available?
Has this payment already been processed?
Does this account have sufficient balance?
may require much tighter consistency depending on the business rules.
Asynchronous architecture is powerful precisely because it allows systems to operate independently.
But independence means they are not always perfectly synchronised at every instant.
Observability Becomes More Important With Pub/Sub
Consider a synchronous chain:
Service A ---> Service B ---> Service C
If Service C fails, tracing the request may be relatively straightforward.
Now imagine:
Order Service
|
v
OrderCreated
|
+--> Inventory
|
+--> Email
|
+--> Loyalty
|
+--> Analytics
Suppose the customer says:
“My order completed, but my loyalty points were never added.”
Where did the failure happen?
Was the event published?
Did the broker receive it?
Was it delivered?
Did the Loyalty Consumer receive it?
Did processing fail?
Was it retried?
Did it enter the dead-letter queue?
This makes observability essential.
Distributed tracing, correlation IDs, structured logging, metrics and consumer-lag monitoring become increasingly important.
Microsoft’s architecture guidance specifically notes that debugging and tracing asynchronous workflows are more difficult because one business transaction can span multiple independent components.
So Pub/Sub reduces coupling between services but increases the importance of operational visibility.
That is another trade-off.
What About Message Ordering?
Imagine these two events:
OrderCreated
and:
OrderCancelled
What happens if a consumer processes OrderCancelled first and OrderCreated afterward?
For some workloads, order matters.
For others, it does not.
Messaging platforms provide different ordering guarantees.
Some guarantee ordering only within particular partitions, keys, topics or configurations.
Some prioritise throughput over strict ordering.
Therefore another system-design question is:
Does the business logic require events to be processed in the exact order in which they occurred?
If yes, ordering needs to be designed intentionally.
Pub/Sub Is Not the Same as a Queue
Beginners often use the terms queue and Pub/Sub interchangeably.
They are related, but they describe different patterns.
A simple queue often looks like:
Producer ---> Queue ---> Worker
The message represents work that needs to be processed.
If several workers consume from the same queue, typically one worker handles a particular message.
Pub/Sub focuses on distributing an event to multiple interested subscribers.
---> Email Subscriber
|
OrderCreated ---+---> Analytics Subscriber
|
---> Loyalty Subscriber
The same event can therefore produce multiple independent reactions.
Modern messaging platforms can combine these ideas.
For example, each subscription may internally use multiple consumer instances to process its workload in parallel.
We will examine queues, Pub/Sub and event streaming separately later in this System Design series.
Commands and Events Sound Different
There is a simple language trick that can help identify the right pattern.
A request or command often sounds like this:
Authorize this payment.
Give me this customer's profile.
Check whether inventory is available.
Calculate this price.
The caller wants another system to do something or return something.
An event sounds different:
PaymentCompleted
CustomerRegistered
OrderCreated
ShipmentDispatched
SubscriptionCancelled
An event describes something that has already happened.
That gives us a useful design question:
Am I asking another service for something, or am I announcing a fact that already happened?
If you are asking for something and need the answer, request-response communication is often natural.
If you are announcing something that happened and several systems may react independently, Pub/Sub becomes attractive.
When Is REST Usually the Better Choice?
REST-style request-response communication is often the better choice when the caller needs an immediate result.
For example:
Get product details.
Check current price.
Authenticate this user.
Check inventory.
Authorize this payment.
It also makes sense when there is one obvious receiver, the interaction is simple, traffic is manageable, strong consistency is important, and introducing messaging would add more operational complexity than business value.
This is important because good system design does not mean choosing the most sophisticated architecture.
Sometimes the simplest architecture is the correct architecture.
Microsoft’s architecture guidance explicitly notes that event-driven architecture may not be justified for straightforward request-response workflows when synchronous communication already meets latency and throughput requirements.
When Is Pub/Sub Usually the Better Choice?
Pub/Sub becomes attractive when the information represents an event that has already happened and multiple independent systems may need to react.
For example:
OrderCreated
PaymentCompleted
CustomerRegistered
ShipmentDispatched
FileUploaded
SubscriptionCancelled
It becomes particularly valuable when downstream work can happen later, several consumers need the same event, traffic is bursty, different consumers operate at different speeds, consumers need to scale independently, or temporary failure of one consumer should not break the producer’s primary operation.
A Complete Checkout Example
Now put everything together.
A customer clicks:
Buy Now
The Order Service first needs an immediate business decision.
Customer
|
v
Order Service
|
v
Payment Service
|
v
Payment Approved
Payment authorisation is synchronous because the Order Service needs the result.
The order is created.
Then:
Order Service
|
v
Publish OrderCreated
|
v
Messaging System
|
+--> Email Consumer
|
+--> Analytics Consumer
|
+--> Loyalty Consumer
|
+--> Warehouse Consumer
|
+--> Recommendation Consumer
Now look at what this design achieves.
The customer does not wait for every downstream process.
The Email Service can fail temporarily without necessarily breaking checkout.
Analytics can process events at a different rate.
Loyalty processing can scale independently.
A Recommendation Service can be added later without requiring the Order Service to directly call it.
Sudden traffic spikes can be buffered.
And the critical business decision—whether payment succeeded—remains synchronous.
This is why good system design frequently combines REST and asynchronous messaging rather than choosing one for everything.
So When Should Communication Become Asynchronous?
Communication should be considered asynchronous when the sender does not require an immediate result from the receiver and delaying downstream processing does not violate the business requirement.
Before making the decision, ask these questions:
Does the caller need the result before it can continue?
Can the work happen a few seconds or minutes later?
Will several systems need the same information?
Can producers and consumers scale independently?
What throughput must the architecture support?
What happens during a sudden traffic spike?
What happens if one consumer is unavailable?
Can the business tolerate eventual consistency?
Could duplicate or out-of-order events cause problems?
How will failed messages be retried?
How will the team trace one transaction across services?
And finally:
Does the benefit of asynchronous messaging justify the infrastructure, engineering and operational cost?
Those questions are more valuable than starting with:
“Should we use Kafka?”
“Should we use RabbitMQ?”
“Should we use Amazon SNS?”
“Should we use Google Cloud Pub/Sub?”
Technology comes later.
First understand the communication requirement.
The Final Mental Model
When you are designing communication between two systems, start with one question:
Does the sender need something back from the receiver right now?
If yes:
Request
|
v
Receiver
|
v
Response
Request-response communication is often a good starting point.
If instead something has already happened and other services merely need to know about it:
Something happened
|
v
Publish Event
|
+--> Subscriber A
|
+--> Subscriber B
|
+--> Subscriber C
Pub/Sub may be a better fit.
Then validate that decision against the major system design dimensions:
Latency: How long should the user wait?
Throughput: How much work must the system process?
Scalability: Can capacity grow as demand grows?
Reliability: What happens when a dependency fails?
Consistency: Can different systems temporarily disagree?
Coupling: How dependent are services on one another?
Cost: Is the additional infrastructure and operational complexity justified?
This is the real decision.
Not REST versus Pub/Sub.
But:
Which communication pattern produces the right trade-offs for this particular piece of the system?
Frequently Asked Questions
What is the main difference between Pub/Sub and REST API communication?
A typical REST-style interaction directly calls another service and expects a response. Pub/Sub allows a publisher to announce an event through messaging infrastructure so interested subscribers can process it independently.
Is Pub/Sub synchronous or asynchronous?
Pub/Sub is generally an asynchronous communication pattern. Publishers send events without waiting for every subscriber to complete processing.
Is REST always synchronous?
No. REST APIs can initiate asynchronous workflows. An HTTP API can, for example, return 202 Accepted after accepting work that will finish later.
When should I use REST instead of Pub/Sub?
Use REST-style request-response communication when the caller requires an immediate answer, there is a clear receiving service, the interaction is simple, or the additional complexity of messaging provides little value.
When should I use Pub/Sub?
Consider Pub/Sub when multiple services need to react to the same event, downstream processing can happen independently, workloads experience traffic spikes, consumers need independent scalability, or one consumer’s failure should not necessarily interrupt the publisher’s primary workflow.
Does Pub/Sub reduce latency?
Pub/Sub can reduce user-perceived latency by moving non-essential work outside the critical request path. It does not make the downstream work itself disappear or automatically execute faster.
Is Pub/Sub better for high throughput?
Pub/Sub can be particularly useful for high-volume or bursty workloads because messaging infrastructure can decouple the rate at which producers generate events from the rate at which consumers process them. REST services can also achieve very high throughput, so throughput alone does not determine the architecture.
What is the difference between throughput and scalability?
Throughput describes how much work a system can process during a period of time. Scalability describes how effectively the system can increase its capacity as demand grows.
Is Pub/Sub more expensive than REST?
For a small, simple system, Pub/Sub can cost more because it introduces messaging infrastructure and additional operational work. At larger scale, those costs may be justified by better decoupling, independent scaling, resilience and workload management.
What is eventual consistency?
Eventual consistency means different parts of a distributed system may temporarily have different versions of the state, but they become consistent after updates have propagated.
What happens if a Pub/Sub consumer fails?
Depending on the messaging platform and configuration, the message can often be retried or retained for later processing. Repeatedly failing messages may also be moved to a dead-letter queue for investigation.
Can REST and Pub/Sub be used together?
Yes. This is extremely common. A system might use synchronous REST communication for payment authorisation and then publish an asynchronous event for email, analytics, loyalty points and other independent processing.
Is Pub/Sub the same as a message queue?
No. A queue generally distributes work to consumers, while Pub/Sub is designed to distribute an event to multiple interested subscribers. Modern messaging platforms can combine characteristics of both patterns.
What is the easiest way to choose between REST and Pub/Sub?
Ask:
Does the sender need the receiver’s answer before continuing?
If yes, start by considering request-response communication.
If no, and the sender is announcing something that happened, consider asynchronous messaging such as Pub/Sub.
Key Takeaway
The purpose of asynchronous communication is not to make an architecture look more advanced.
It is to avoid forcing systems to wait for work that does not need to happen immediately.
Use synchronous request-response communication when the next step depends on the answer.
Use asynchronous Pub/Sub when something has happened and other systems can react independently.
And before making the final architecture decision, evaluate:
latency, throughput, scalability, reliability, consistency, coupling and total cost.
That is what turns:
“REST or Pub/Sub?”
from a technology question into a real system design decision.
Next in the System Design Series
Message Queue vs Pub/Sub vs Event Streaming: What Problem Does Each One Solve?
Sources and Further Reading
This article is based on architecture concepts documented by Google Cloud Pub/Sub, the Microsoft Azure Architecture Center, AWS Prescriptive Guidance on the Publish/Subscribe pattern, and MDN’s HTTP documentation for asynchronous request handling.
Google Cloud — What is Pub/Sub?