← Back to list

Message Queues vs. Pub/Sub: Decoding Asynchronous Communication (with SQS & Kafka)

Shashank Mayya in Data Engineer Things · 2025-06-17 19:29 · 25 claps · 9.7 min read paywalled
#kafka #data-engineering #analytics #sql #engineering
Open on Medium ↗
Wiki topics: GRW · Growth & Analytics 💻 · Programming 🔧 · Data Engineering

Message Queues vs. Pub/Sub: Decoding Asynchronous Communication (with SQS & Kafka)

In the ever-evolving landscape of modern software architecture, building resilient, scalable, and decoupled systems is paramount. Asynchronous communication patterns are a cornerstone of achieving these goals. Two of the most common patterns you’ll encounter are Message Queues and Publish/Subscribe (Pub/Sub) systems. While they both involve sending messages between different parts of an application (or different applications altogether), they serve distinct purposes and have different underlying mechanics. Let’s break them down, using Amazon SQS and Apache Kafka as our real-world examples.

What’s the Big Idea? Why Asynchronous?

Before we compare, let’s quickly visualize the “problem” asynchronous communication solves. Imagine a synchronous system:

This synchronous model often leads to several problems:

  • Tight Coupling: Services are directly dependent on each other. ServiceA needs to know the network address of ServiceB and ServiceC. If ServiceB’s interface changes, ServiceA might break.
  • Reduced Resilience & Fault Tolerance: If any downstream service (ServiceB or ServiceC) is slow or fails, the entire request chain can be blocked or fail. A failure in ServiceC (sending an email) could potentially prevent the Client from getting an order confirmation, even if the payment succeeded.
  • Scalability Bottlenecks: The overall throughput of ServiceA is limited by the slowest service in the chain. If ServiceC can only handle 10 requests per second, ServiceA can’t process orders much faster than that, even if it and ServiceB are capable of more.
  • Poor Responsiveness: The Client has to wait for the entire chain of operations to complete before getting a response. This can lead to a poor user experience, especially if some downstream operations are time-consuming but not critical for the initial acknowledgment.

Asynchronous communication patterns, like those provided by Message Queues and Pub/Sub systems, address these problems by introducing an intermediary (the queue or topic). This leads to benefits such as:

  • Decoupling: Services don’t need to know about each other directly. The sender (producer) just sends a message to the intermediary, and the receiver (consumer) just picks it up from there. They can evolve independently.
  • Increased Resilience: If a consumer service goes down, messages can wait in the queue/topic until it’s back up, preventing data loss and allowing the producing service to continue operating.
  • Improved Scalability: You can scale producers and consumers independently based on load. If one part of the system is slow, you can add more consumers for that specific task without affecting other parts.
  • Load Leveling/Buffering: Handle spikes in traffic by queuing requests, allowing downstream services to process them at their own steady pace rather than being overwhelmed.
  • Enhanced Responsiveness: The initial service can respond to the client much faster after simply placing a message on a queue, deferring longer-running tasks to background processors.

Now, let’s explore how Message Queues and Pub/Sub systems specifically implement these asynchronous benefits.

1. Message Queues: The Orderly Line (e.g., Amazon SQS)

Think of a message queue like a single line at a post office. People (messages) arrive and line up. There’s one counter (or multiple identical counters) serving one person at a time from the front of the line.

Key Characteristics of Message Queues:

  • Point-to-Point Communication: A message is sent to a specific queue, and a consumer (or one of a pool of consumers competing for messages) retrieves it from that queue.
  • One Message, One Consumer (Typically): Once a message is successfully processed by a consumer, it’s removed from the queue and generally isn’t available to other consumers. (SQS has “visibility timeouts” to handle processing failures, but the intent is single consumption).
  • Load Balancing/Task Distribution: Multiple instances of a consumer service can pull messages from the same queue, effectively distributing the workload.
  • Ordering (Sometimes): Some queues (like SQS FIFO queues) can guarantee message order. Standard SQS queues offer best-effort ordering.

Example: Amazon SQS (Simple Queue Service)

Amazon SQS is a fully managed message queuing service.

  • Producers: Applications send messages to an SQS queue.
  • SQS Queue: Stores these messages reliably.
  • Consumers: Applications poll the SQS queue, retrieve messages, process them, and then delete them from the queue.

Architecture Diagram: SQS Standard Queue

How SQS Standard Queues Work (Simplified):

  1. An application (Producer) wants to offload a task, say, “process new order.” It creates a message containing order details and sends it to an SQS queue named NewOrdersQueue.
  2. One or more worker services (Consumers) are polling NewOrdersQueue.
  3. One of these consumers, say OrderProcessor_Instance1, retrieves a message. SQS makes this message “invisible” for a configured “visibility timeout.”
  4. OrderProcessor_Instance1 processes the order.
  5. If successful, it tells SQS to delete the message.
  6. If it fails or crashes, after the visibility timeout, the message becomes visible again for another consumer to pick up. (This helps ensure messages aren’t lost if a consumer dies mid-process).

SQS FIFO (First-In, First-Out) Queues:

For scenarios where the order of messages is critical (e.g., financial transactions, inventory updates that must happen sequentially for a given item).

Handling Message Failures: Dead-Letter Queues (DLQ)

A common pattern with SQS (and other message queues) is to use a Dead-Letter Queue (DLQ) to handle messages that consistently fail processing.

Use Cases for SQS (and Message Queues in general):

  • Decoupling Microservices: An OrderService sends a message to a queue, and a separate NotificationService picks it up to send an email, without either service needing direct knowledge of the other.
  • Background Task Processing: Offloading image resizing, report generation, or video transcoding. A web server can accept an upload, put a “process image” message on a queue, and immediately respond to the user, while a backend worker processes the image later.
  • Batch Processing: Collecting data and processing it in chunks.
  • Reliable Task Distribution: Ensuring that tasks are eventually processed, even if workers fail temporarily.

SQS Pros:

  • Simple & Managed: Easy to set up and use, AWS handles the infrastructure.
  • Highly Scalable & Reliable: Built for massive scale and durability.
  • Cost-Effective: Pay-as-you-go.
  • Good for Task Offloading: Classic use case.

SQS Cons:

  • Limited to One “Subscriber Type” per Queue: If multiple different kinds of services need the same message, you’d typically need to fan out (e.g., SQS -> SNS -> SQS), or they’d all have to consume from the same queue and filter messages, which isn’t ideal.
  • Standard SQS Ordering is Best-Effort: For strict ordering, you need FIFO queues, which have throughput limitations compared to standard queues.
  • No Built-in Message Replay (for all consumers): Once a message is consumed and deleted, it’s gone.

2. Publish/Subscribe (Pub/Sub) Systems: The Broadcasting Channel (e.g., Apache Kafka)

Think of a Pub/Sub system like a radio station or a newspaper subscription. A broadcaster (publisher) sends out a signal (message) on a specific channel (topic). Anyone tuned into that channel (subscribers) receives the message. The broadcaster doesn’t know or care who is listening, and multiple listeners can receive the same broadcast.

Key Characteristics of Pub/Sub Systems:

  • One-to-Many Communication (Broadcast): A publisher sends a message to a “topic.” Multiple subscribers, interested in that topic, can receive a copy of the message.
  • Decoupled Publishers and Subscribers: Publishers don’t know about subscribers, and subscribers don’t know about publishers. They only know about the topic.
  • Event-Driven: Often used for broadcasting events (e.g., “UserLoggedIn,” “ProductPriceChanged”).
  • Message Persistence & Replay (Often): Many Pub/Sub systems, like Kafka, persist messages for a configurable period, allowing new subscribers to process old messages or existing subscribers to replay messages.

Example: Apache Kafka

Apache Kafka is a distributed streaming platform. It’s more than just Pub/Sub; it’s designed for high-throughput, fault-tolerant, real-time data feeds.

  • Producers: Applications publish records (messages) to Kafka topics.
  • Kafka Cluster (Brokers): A set of servers that store these records in topics. Topics are divided into partitions for scalability and parallelism.
  • Consumers: Applications subscribe to topics and process the records. Consumers are often grouped into “consumer groups.” Each record within a partition is delivered to only one consumer within a consumer group, but multiple consumer groups can subscribe to the same topic and get all the messages.

Architecture Diagram: Kafka Topic, Partitions, and Consumer Groups

How Kafka Works (Simplified):

  1. A Producer (e.g., a web application tracking user clicks) sends a record like {“user_id”: 123, “action”: “click”, “page”: “product_detail”} to a Kafka topic called UserActivity.
  2. The Kafka brokers append this record to a partition within the UserActivity topic. Records within a partition are ordered.
  3. Multiple Consumer Groups can subscribe to UserActivity:
  • RealtimeDashboardConsumerGroup: Might have consumers updating a live dashboard.
  • AnalyticsConsumerGroup: Might have consumers feeding data into a data warehouse for batch analysis.
  • FraudDetectionConsumerGroup: Might have consumers looking for suspicious patterns.
  1. Each consumer group independently tracks its progress (offset) in reading from the topic’s partitions. This means AnalyticsConsumerGroup can be hours behind RealtimeDashboardConsumerGroup without affecting it.

  2. Within RealtimeDashboardConsumerGroup, if there are multiple consumer instances, Kafka distributes the partitions among them. So, ConsumerInstance1 might get Partition 0, and ConsumerInstance2 gets Partition 1. Each instance gets a distinct set of messages from the topic. If a consumer in a group dies, its partitions are reassigned to other consumers in that group.

Use Cases for Kafka (and Pub/Sub in general):

  • Event Sourcing: Using a log of events as the primary source of truth for application state.
  • Real-time Analytics & Stream Processing: Processing massive streams of data for insights, like fraud detection, IoT sensor data analysis, or recommendation engines.
  • Log Aggregation: Collecting logs from many services into a central place for analysis and monitoring.
  • Data Integration & Pipelines: Moving data between different databases, data lakes, and applications.
  • Notifying Multiple Systems: When an order is placed, OrderService publishes an OrderPlaced event. NotificationService, InventoryService, and ShippingService all subscribe and react accordingly.

Kafka Pros:

  • Extremely High Throughput & Low Latency: Built for handling millions of messages per second.
  • Scalability & Fault Tolerance: Distributed by nature, can scale out and tolerate broker failures.
  • Message Retention & Replayability: Messages are stored on disk and can be re-read. This is powerful for recovery, adding new consumers, or re-processing data.
  • Rich Ecosystem: Connectors, stream processing libraries (Kafka Streams, ksqlDB).
  • True Decoupling for Multiple Interested Parties: The core strength of Pub/Sub.

Kafka Cons:

  • Complexity: More complex to set up, manage, and operate than SQS (though managed services like Amazon MSK or Confluent Cloud reduce this).
  • Steeper Learning Curve: Understanding partitions, consumer groups, offsets, Zookeeper (or KRaft) takes effort.
  • Resource Intensive: Can require significant server resources for large deployments.

Achieving Pub/Sub with SQS using SNS (Simple Notification Service)

While SQS itself is a queue, AWS provides SNS to enable Pub/Sub patterns where SQS queues can be subscribers. This is a common AWS-native pattern for fanning out messages.

This pattern allows different services to react to the same event independently, processed via their own SQS queues for resilience and independent scaling. It’s a great way to get Pub/Sub behavior within the AWS ecosystem without managing a full Kafka cluster if your needs are simpler.

Head-to-Head: Message Queue (SQS) vs. Pub/Sub (Kafka)

[embed]

When to Choose Which?

It’s not about which is “better,” but which is “better for your specific problem.”

Choose a Message Queue (like SQS) when:

  • You need to offload tasks to background workers to improve application responsiveness.
  • You want to reliably distribute tasks among a pool of identical workers.
  • You need simple decoupling between two services for a specific task.
  • Your primary concern is ensuring a task is done once (e.g., processing a payment).
  • Operational simplicity is a high priority.
  • You’re using the SNS+SQS fan-out pattern for simpler Pub/Sub needs within AWS.

Choose a Pub/Sub System (like Kafka) when:

  • You need to broadcast messages/events to multiple, diverse consumer applications.
  • You are dealing with high-volume, real-time event streams (e.g., clickstreams, IoT data, logs).
  • You need the ability to replay messages (e.g., for new services, recovery, or re-analysis).
  • You’re building event-driven architectures where components react to happenings elsewhere.
  • You require strong ordering within a context (partition, often keyed by user ID, order ID, etc.) for multiple subscribers.
  • You need a backbone for data pipelines and stream processing.
  • You require a durable, replayable log of events that can be consumed by different systems at different rates.

3. Hybrid Architectures: The Best of Both Worlds

Often, you’ll find systems using both patterns effectively. It’s not an either/or decision; they can be complementary.

In this hybrid model:

  • SQS is used within the Order Processing domain for decoupling internal tasks (e.g., breaking down order placement into smaller, manageable, and retryable steps). This keeps the internal workings of the Order Service encapsulated and uses SQS for its simplicity in task management.
  • Kafka is used as an inter-domain event bus. When a significant business event occurs (like “OrderCompleted”), it’s published to a Kafka topic. Other independent domains (Notifications, Inventory, Analytics) can then subscribe to these events and react accordingly without being tightly coupled to the Order Service. Kafka’s persistence and replayability are valuable here.

Conclusion

Both Message Queues and Pub/Sub systems are invaluable tools for building robust, scalable modern applications.

  • SQS (and similar queues) shine for direct, reliable task distribution where one message is meant for one processing action, often within a service or closely related services. They are simpler to manage and excellent for work offloading.
  • Kafka (and similar Pub/Sub platforms) excel at broadcasting events to many interested parties, handling massive data streams, enabling powerful event-driven architectures, and serving as a durable log for inter-service communication across an enterprise.

Understanding their core differences, strengths, and ideal use cases — and how they can complement each other, as seen in the SNS+SQS fan-out or hybrid Kafka/SQS architectures — will help you choose the right tool (or combination of tools) for the job. This leads to better-designed, more resilient, and more efficient systems. Happy messaging!


메타데이터
post_id
c7e9c4ab2711
slug
message-queues-vs-pub-sub-decoding-asynchronous-communication-with-sqs-kafka-c7e9c4ab2711
url
https://blog.dataengineerthings.org/message-queues-vs-pub-sub-decoding-asynchronous-communication-with-sqs-kafka-c7e9c4ab2711
canonical_url
https://blog.dataengineerthings.org/message-queues-vs-pub-sub-decoding-asynchronous-communication-with-sqs-kafka-c7e9c4ab2711
author_url
https://medium.com/@smayya
status
ok
fetched_at
2026-07-19 10:09:26