Most integration problems start the same way. One system needs to tell another that something happened, an order was placed, a work order was closed, an invoice was approved, and the obvious approach is to have the first system call the second directly and wait for a reply. That works until the second system is slow, or busy, or down for maintenance, or suddenly hit with ten times the usual traffic. Then the direct call becomes the weakest link, and a problem in one system spreads to every system connected to it. A message queue is the standard, decades-proven answer to that fragility. It puts a buffer between the sender and the receiver so that neither has to be available at the same moment for the work to get done. This article is a plain-language explanation of what that buffer is and why it matters.
Where this fits: a message queue is one specific tool inside the wider discipline of connecting systems. If you want the big picture first, how integration patterns, APIs, events and messaging all fit together, start with the pillar guide, enterprise system integration explained, then come back here for the detail on queuing.
1. What a message queue is
A message queue is a holding area for messages that sits between the system that produces work and the system that consumes it. A message is simply a small package of data, an order identifier, a JSON payload describing an event, a command to do something, along with whatever metadata the receiving system needs. The producer writes that message into the queue and immediately moves on. The message waits there, in order, until a consumer picks it up and processes it. The queue guarantees that the message is stored safely while it waits, so nothing is lost just because the consumer happened to be busy or offline when the message arrived.
The piece of software that runs the queue is usually called a message broker. It accepts messages from producers, keeps them durably, tracks which messages have been delivered and which are still waiting, and hands them out to consumers. You will see names like RabbitMQ, Apache ActiveMQ, Amazon SQS, Azure Service Bus and Apache Kafka in this space, and although they differ in design, they all provide the same core promise: a sender can hand off a message and trust that it will reach a receiver eventually, without the two ever needing to be online together.
The mental model that makes this click is the physical mail sorting office. You post a letter and walk away. You do not stand at the recipient's door waiting for them to be home. The sorting office holds the letter, and the recipient collects it when they are ready. The postal system decouples the act of sending from the act of receiving, and a message queue does exactly the same thing for software.
2. The problem it solves: tight coupling and load spikes
To appreciate why queues exist, look at what happens without them. In a direct, synchronous integration, System A calls System B and blocks, meaning it stops and waits, until System B answers. This creates two distinct and painful kinds of fragility.
The first is tight coupling. System A now depends on System B being available at the exact moment of the call. If System B is down for a deployment, System A's request fails. If System B is slow, System A is slow too, because it is stuck waiting. A single struggling component drags down everything wired to it, and a chain of synchronous calls can collapse together in what engineers call a cascading failure. The systems are so tightly bound that they cannot fail, or even hiccup, independently.
The second problem is load spikes. Real workloads are not smooth. An e-commerce site gets a surge at a sale launch. A facilities system gets a flood of work orders after a storm. A billing run fires thousands of records at midnight. If the receiving system has to process every request the instant it arrives, it must be sized for the worst peak it will ever see, which is expensive and wasteful for the ninety-nine percent of the time when traffic is normal. Push past that peak and the receiver falls over.
A queue dissolves both problems at once. Because the producer only has to reach the queue, not the consumer, System A no longer cares whether System B is up. It writes the message and moves on. And because the queue absorbs bursts, holding messages until the consumer can work through them at a steady pace, the consumer can be sized for the average load rather than the peak. The queue smooths the spikes into a manageable stream. This is the heart of why queuing matters, and it is the same decoupling instinct that runs through good integration architecture generally.
A caution worth stating early: a queue trades immediate certainty for resilience. When you drop a message and move on, you no longer get a synchronous answer that says the work is finished. It says only that the work is accepted. If the consuming system rejects the message later, the producer has already walked away. That is usually the right trade, but it means you have to design for eventual processing, for failures that surface after the fact, and for the possibility that a message is processed more than once. Queuing removes fragility from the connection and adds a modest amount of complexity to the design. Do not adopt it expecting the old synchronous certainty for free.
3. Producers, queues and consumers
The three roles in a queuing system are simple, and once you name them the whole pattern becomes easy to reason about. A producer (also called a publisher or sender) is any system that creates messages and writes them into the queue. A queue is the buffer, managed by the broker, that stores messages in order until they are consumed. A consumer (also called a subscriber or worker) is any system that reads messages from the queue and does the actual processing.
The crucial property is that these three run at their own speeds. The producer can write faster than the consumer can read, and the queue simply grows to hold the backlog. The consumer can be temporarily offline, and messages wait for it. You can even run several consumers reading from the same queue so the work is shared out, which is how queuing lets you scale processing by adding workers rather than rewriting the producer. The diagram below shows the shape of it.
Read the diagram left to right. The producer pushes messages M1, M2, M3, M4 into the queue and does not wait. The queue holds them in the order they arrived. The consumer pulls them off the front, oldest first, and processes each one when it has capacity. If the producer speeds up, the queue lengthens. If the consumer stalls, the messages simply wait. Neither side is blocked by the other, and that independence is the entire point.
4. How queuing works: acknowledgements, retries and dead-letter queues
Holding messages in order is the easy part. The interesting engineering is in making sure a message is processed exactly the right number of times, even when things go wrong. Three mechanisms do most of that work.
The first is the acknowledgement, usually shortened to ack. When a consumer finishes processing a message successfully, it sends an ack back to the broker, and only then does the broker consider the message done and remove it. If the consumer crashes halfway through, no ack is sent, so the broker still holds the message and can hand it to another consumer. This is what stops a message from being silently lost when a worker dies mid-task. The rule of thumb is to acknowledge only after the work is truly complete, not when the message is received, because an early ack turns a crash into a lost message.
The second is the retry. If processing fails, because a downstream service was briefly unavailable, or a record was temporarily locked, the message can be returned to the queue and delivered again later. Most brokers let you configure how many times a message is retried and how long to wait between attempts. Retries handle the large category of failures that are transient, the ones that succeed on the second or third try simply because the temporary problem has cleared.
The third is the dead-letter queue, often written DLQ. Some messages fail every time, no matter how many retries you allow, perhaps because the payload is malformed or references data that no longer exists. If you kept retrying those forever they would clog the queue and starve the healthy messages behind them. Instead, after a set number of failed attempts, the broker moves the message out of the main queue and into a separate dead-letter queue. There it waits for a human or a monitoring process to inspect it, fix the underlying problem, and decide what to do. The dead-letter queue is the safety net that keeps one poisonous message from blocking everything else while still ensuring nothing is thrown away unnoticed.
Together, acks, retries and dead-letter queues deliver the reliability that makes queuing trustworthy for real business processes. Most brokers aim for at-least-once delivery, meaning a message will be delivered until it is acknowledged, with the side effect that it can occasionally be delivered more than once. That is why well-built consumers are designed to be idempotent, able to receive the same message twice and produce the same result without double-charging an invoice or duplicating a work order. Idempotency is the consumer's half of the reliability bargain.
5. Point-to-point versus publish-subscribe
There are two fundamental delivery models in messaging, and knowing which one you need shapes everything about the design.
In the point-to-point model, a message goes onto a queue and is delivered to exactly one consumer. If several consumers are attached to the same queue, they share the load, but any given message is handled by only one of them. This is the classic work-queue pattern: a stream of tasks that each need to be done once, spread across a pool of workers. Processing a batch of uploaded images, sending a queue of emails, or handling incoming orders are all point-to-point, because you want each task done a single time.
In the publish-subscribe model, often shortened to pub/sub, a message is broadcast to every interested subscriber. The producer publishes to a topic rather than a queue, and each subscriber that has registered interest gets its own copy. One event, say an order was placed, can simultaneously notify the billing system, the inventory system and the analytics system, each acting on the same event independently. This is the pattern behind event-driven architecture, where systems react to things that happen rather than being called directly.
The distinction matters because it answers the question of how many consumers should act on each message. If the answer is exactly one, you want a point-to-point queue. If the answer is many, each doing something different, you want publish-subscribe. Many real systems use both: a pub/sub broadcast that fans an event out to several teams, each of which drops the event into its own point-to-point work queue for reliable processing. I go deeper into the broadcast model in the dedicated guide to what publish-subscribe is.
6. The benefits
It is worth setting out plainly what a message queue actually buys you, because the benefits are distinct and each one earns its place. The table below summarises the five that matter most and what each one really means in practice.
| Benefit | What it means |
|---|---|
| Decoupling | The producer and consumer never need to know about each other or run at the same time. Either can be changed, redeployed or taken offline without breaking the other. |
| Buffering & load-leveling | The queue absorbs bursts of traffic and releases them at a steady rate, so the consumer can be sized for average load instead of the worst peak. |
| Asynchrony | The producer hands off a message and continues immediately rather than blocking for a reply, keeping user-facing systems fast and responsive. |
| Reliability | Durable storage, acknowledgements, retries and dead-letter queues mean a message survives a consumer crash and is not lost when something fails. |
| Scaling | Processing capacity grows by adding more consumers to the same queue, with no change to the producer, so throughput scales horizontally on demand. |
Read those five together and a theme emerges: every benefit flows from the same root idea, putting a durable buffer between sender and receiver. Decoupling, buffering, asynchrony, reliability and scaling are not five separate features you bolt on, they are five consequences of the one architectural decision to stop making systems call each other directly.
7. Popular message queue systems
You rarely build a queue from scratch. You choose a broker, and the mainstream options fall into a few families. The point of naming them is not to crown a winner but to show that this is settled, well-supported technology with mature choices for every context.
- RabbitMQ is the classic general-purpose message broker. It implements the AMQP protocol, supports both point-to-point queues and publish-subscribe through exchanges, and is a sensible default for straightforward task queues and service-to-service messaging. Its flexible routing and broad language support make it a common first choice.
- Apache Kafka is a distributed event-streaming platform rather than a traditional queue. It keeps a durable, replayable log of events and excels at very high throughput and at pub/sub scenarios where many consumers read the same stream. If your problem is event streaming, analytics pipelines or a shared event backbone, Kafka is often the right tool. I compare the two directly in RabbitMQ versus Kafka.
- Amazon SQS is a fully managed queue service on AWS. There is no broker to run or patch; you create a queue and use it. It is the low-operational-overhead choice for teams already on AWS who want point-to-point queuing without managing infrastructure.
- Azure Service Bus is Microsoft's managed enterprise messaging service, offering queues and publish-subscribe topics with features like sessions, ordering and dead-lettering. It is the natural fit for organisations building on Azure and integrating Microsoft business platforms.
- Apache ActiveMQ is a long-established open-source broker that implements standard messaging protocols and remains widely used in Java and enterprise Java environments.
The common thread is that these are proven, standards-aware products with large communities behind them. Whichever you pick, you are adopting a pattern the industry has relied on for decades, not an experiment.
8. When to use a queue
A queue is not the answer to every integration, and reaching for one reflexively adds moving parts you may not need. The honest test is whether the work can, or should, happen out of step with the request that triggered it. Reach for a queue when:
- The work is slow or heavy. Generating a report, transcoding a video, running a batch of calculations. Accept the request, queue the job, and let a worker grind through it while the user gets on with their day.
- Traffic is spiky. If load arrives in bursts, a queue levels it out and protects the consumer from being overwhelmed at the peak.
- The producer and consumer should be independent. When you want to deploy, scale or fail either side without disturbing the other, decoupling through a queue is exactly the tool.
- One event needs to reach many systems. Publish-subscribe over a broker lets a single event notify several consumers cleanly instead of hard-wiring point-to-point calls to each.
- You need durability across outages. If a message absolutely must not be lost when the receiver is temporarily down, the queue's durable storage is the safety guarantee.
And be equally clear about when not to. If the caller genuinely needs an immediate answer to continue, checking a stock level before confirming an order, validating a password at login, a synchronous request is the correct pattern, and forcing it through a queue only adds latency and complexity. For a fuller comparison of synchronous request styles against event-driven ones, see API versus webhook. And when you are integrating a specific business platform such as Microsoft Dynamics, the practical mix of direct APIs and queued messaging is covered in Business Central APIs and integrations. Queuing is a precise tool for a precise class of problem: work that can be done independently of the moment it was requested. Used there, it is transformative. Used everywhere, it is overhead.
9. References
The concepts in this article rest on published standards and vendor documentation rather than opinion. For deeper reading, the primary sources are:
- AMQP (Advanced Message Queuing Protocol), standardised by OASIS. AMQP is the open, wire-level protocol that defines how compliant brokers and clients exchange messages, and it is the standard RabbitMQ and many other brokers implement.
- RabbitMQ documentation, published by the RabbitMQ project, covering queues, exchanges, acknowledgements and dead-letter behaviour.
- Apache Kafka documentation, published by the Apache Software Foundation, covering topics, partitions, consumer groups and the event-log model.
- Amazon SQS documentation and Azure Service Bus documentation, published by AWS and Microsoft respectively, covering their managed queuing and pub/sub services.
- Apache ActiveMQ documentation, published by the Apache Software Foundation.
Consult the official documentation for the specific broker you adopt, since the exact semantics of acknowledgements, ordering guarantees and delivery models vary between products.
Final thoughts
A message queue is a small idea with an outsized effect. By placing a durable buffer between the system that produces work and the system that consumes it, you break the fragile assumption that both must be available at the same instant. The producer hands off a message and moves on. The queue holds it safely. The consumer takes it up whenever it is ready, at whatever pace it can sustain, with acknowledgements, retries and dead-letter queues catching the failures along the way. From that single decision flow all the benefits worth having: decoupling, load-leveling, asynchrony, reliability and easy scaling.
The skill is not in running a broker, which the mature products make straightforward, but in knowing where queuing belongs. Use it for work that can happen independently of the moment it was requested, and it will make your architecture calmer, more resilient and easier to scale. Force it onto interactions that genuinely need an immediate answer, and it just adds latency. Queuing is one of the most dependable tools in enterprise integration precisely because its job is so well defined. To see how it sits alongside APIs, events and the other patterns you will reach for, keep the pillar guide, enterprise system integration explained, close at hand.
Designing a messaging or integration layer?
Independent, vendor-neutral advice on where queuing belongs, choosing a broker, decoupling systems, and building integration that survives load spikes and outages. 22+ years across ERP, EAM, CAFM and enterprise integration.
Book a conversationRelated reading: Enterprise system integration explained, API vs webhook, RabbitMQ vs Kafka, What is publish-subscribe, Business Central APIs and integrations.
Muhammad Abbas
CMMS / CAFM Manager & Enterprise Integration Specialist · 22+ years across ERP, EAM, CAFM and enterprise integration.
Work with me