You open your RabbitMQ management console on a Monday morning. 247 queues are listed. Some are called orders, others team3-prod-notifs, others test_queue_final_v2. Which one is in production? Which one can you safely delete? Nobody knows.
Without naming conventions, a shared broker becomes a minefield. This article proposes a reusable template, adapted to the constraints of RabbitMQ, Kafka and AWS SQS, so that every queue name is self-documenting.
In this article, message queue refers to the generic concept: a RabbitMQ queue, a Kafka topic or an SQS queue. The naming convention applies to all of these objects, even though their mechanics differ.
Why standardize naming
In an enterprise context, the message broker is often a shared resource across domains. Multiple applications—sometimes multiple teams—publish and consume messages on the same cluster.
Without an explicit convention, each team invents its own format. The result?
- Grafana dashboards are unreadable: impossible to filter by team or domain
- An incident at 2 AM on
queue_notif_3doesn’t tell you who owns it - Test queues pile up and never get cleaned
A structured naming convention, even a lightweight one, solves these problems the same way DNS structures domain names: with readable, hierarchical segments.
- Observability: a structured name integrates directly into dashboards and alerts
- Incident response: the name identifies the team, domain and environment at a glance
- Multi-team governance: every team follows the same format without heavy coordination
- Automation: cleanup scripts, dashboards and alerting can parse queue names
If you’ve ever experienced an incident on a shared broker, you know the first minute is critical. A 99.9% SLA leaves only 43 minutes of downtime per month: every second spent figuring out “whose queue is this?” is a second lost.
Anatomy of a good name
An effective queue name is composed of ordered segments, separated by a delimiter. Each segment carries a specific piece of information.
Environment
The first segment immediately distinguishes production queues from test queues.
Typical values: prod, staging, uat, dev, e2e.
If your broker is shared across environments (which is common in development), the absence of an environment prefix is the number one cause of messages sent to the wrong place. This segment is not optional.
Owner
The name of the entity responsible for the queue: the one to contact when something goes wrong. Two common approaches:
- By team:
team-payments,team-logistics. Advantage: clear ownership for incident response, stable even as applications evolve. - By application:
billing-service,shipping-api. Advantage: direct traceability in logs and metrics, more precise when multiple applications coexist within the same team.
The key is to pick one model and stick with it. Avoid unstable names: a person (jean-bob-queue), a temporary project or a sprint name.
Domain
The business domain the queue belongs to: booking, invoicing, notification, inventory.
This segment lets you visually group queues by business context in the broker console.
Entity
The business entity concerned by the messages: order, shipment, payment, user.
This segment, often overlooked, distinguishes queues within the same domain. Without it, prod.team-payments.invoicing.events.v1 doesn’t tell you which events are flowing through.
The domain represents the functional scope (invoicing), the entity represents the specific business object (invoice, credit-note). If your domain contains only one entity, you can merge both segments.
Pattern
The usage pattern of the queue:
events: business events (publish/subscribe)commands: commands destined for a specific consumerretry: messages waiting for a new attemptdlq: dead letter queue, the cemetery of failed messagesbuffer: buffer queue to absorb load
Version
The message contract version: v1, v2.
Queues carry messages that follow a specific data structure. It’s an API. If a breaking change occurs (field removed, format changed), the version must change.
If you use a schema registry (Confluent, AWS Glue), the version in the queue name designates the major version of the contract. Compatible evolutions (adding optional fields) don’t require a new queue.
The complete template
<environment>.<owner>.<domain>.<entity>.<pattern>.<version>
Concrete examples:
| Queue name | Meaning |
|---|---|
prod.team-payments.invoicing.invoice.events.v1 | Invoice events in production, payments team |
staging.team-logistics.shipping.shipment.commands.v1 | Shipping commands in staging |
prod.team-payments.invoicing.invoice.dlq.v1 | Dead letter queue for invoice events |
prod.team-marketing.notification.email.buffer.v2 | Email notification buffer queue, v2 |
dev.team-platform.monitoring.alert.events.v1 | Alerting events in development |
Adapting the convention to your broker
The template above is a generic model. Each broker imposes its own constraints: separator, maximum length, allowed characters. Here’s how to adapt it.
RabbitMQ
RabbitMQ uses . as the natural separator in routing keys, making the template directly compatible. The limit is 255 bytes (UTF-8 encoded) for a queue name. In practice, with pure ASCII names (letters, digits, ., -), one character equals one byte, so the limit is effectively 255 characters.
RabbitMQ routing keys support the wildcards * (one segment) and # (zero or more segments). Your naming convention must be consistent with your routing rules: prod.team-payments.invoicing.* should match all invoicing queues for the payments team in production.
Kafka
Kafka accepts both . and - as separators. The limit is 249 characters for a topic name. Note: consumer groups also need a naming convention.
Suggestion for consumer groups: <application>.<topic-name> lets you immediately identify which application consumes which topic.
The consumer group name appears in lag metrics. A structured name (app-billing.prod.team-payments.invoicing.invoice.events.v1) makes it easier to alert on consumption lag.
AWS SQS
SQS uses - as a separator (. is allowed but unconventional). The limit is 80 characters, which forces brevity.
For FIFO queues, the .fifo suffix is mandatory and counts toward the 80-character limit.
With SQS, prefer consistent abbreviations: prd instead of prod, pay instead of payments. Document these abbreviations in your ADR or team wiki.
Comparison table
| Broker | Separator | Max length | Specifics |
|---|---|---|---|
| RabbitMQ | . | 255 bytes | Wildcards * # on routing keys |
| Kafka | . or - | 249 chars | Consumer group needs naming too |
| AWS SQS | - | 80 chars | FIFO = .fifo mandatory |
Common pitfalls
Even with a template, certain mistakes keep coming back.
- Unstable owner name: avoid names of people, temporary projects or sprints. Whether you choose a team or application name, it must be canonical and durable
- Inconsistent casing:
Team-Paymentshere,team_paymentsthere. Pickkebab-caseand stick with it - Transient information in the name:
sprint-42-test-queuemeans nothing in 6 months - No environment prefix: the queue
order-eventsexists in prod and dev? Good luck debugging - Name too long for the broker: test the length before deploying, especially on SQS (80 chars)
Before validating a queue name, ask yourself this question: could a colleague who doesn’t know the project understand this queue at 2 AM, in the middle of an incident? If the answer is no, the name needs rework.
What about automated tests?
When running integration tests, you often need to create queues on the fly. Each execution needs its own queues to avoid collisions between parallel tests.
The solution: add a UID as suffix. Prefer a short, readable UID (execution context + test identifier + timestamp) over a full 36-character UUID.
e2e.team-payments.invoicing.invoice.events.v1.runner-1.test-13.20250127T1112
The problem: these temporary queues accumulate. Without a cleanup mechanism, you can end up with thousands of orphaned queues.
On a real project, we discovered over 12,000 orphaned test queues on a RabbitMQ cluster. The cleanup took a full day. An automatic mechanism would have prevented this debt.
Each broker offers cleanup mechanisms:
- RabbitMQ: the
x-expiresargument automatically deletes a queue after a period of inactivity (e.g. 1 hour) - Kafka: the retention policy (default 7 days) can be reduced for test topics
- AWS SQS: no native TTL on the queue itself, but a cleanup script based on the date in the name works well
- Universal fallback: a cron job that lists queues prefixed with
e2e.and deletes those older than 24h
If you run realistic load tests, the volume of temporary queues can be even higher. Automate cleanup from the start.
Formalize and enforce
A convention that isn’t enforced is a convention that doesn’t exist. Here’s how to make it durable.
ADR over wiki: document the convention in an Architecture Decision Record versioned with the code. A wiki gets lost; an ADR in the Git repository stays visible and maintained.
CI validation: a regex in your CI pipeline can reject non-compliant names before deployment.
^(prod|staging|uat|dev|e2e)\.[a-z0-9-]+\.[a-z0-9-]+\.[a-z0-9-]+\.(events|commands|retry|dlq|buffer)\.(v[0-9]+)$
This regex validates the 6-segment format. Adapt it to your needs: add patterns, allow optional segments, or adjust environment values.
Queue catalog: a YAML or JSON file in your repository that lists all declared queues, with their owner and description. This catalog can feed your dashboards and alerts.
If you use an artifact promotion approach, the queue catalog can follow the same lifecycle as your artifacts: declared in dev, promoted to staging, then to production.
TL;DR
- Structure names with ordered segments:
<env>.<owner>.<domain>.<entity>.<pattern>.<version> - Adapt separator and length to your broker’s constraints (
.for RabbitMQ/Kafka,-for SQS) - Pick a stable owner: team or application, it doesn’t matter, but the name must be canonical and durable
- Always prefix the environment: a shared broker without prefix is an incident waiting to happen
- Automate cleanup for test queues with
x-expires, retention policies or cron jobs - Formalize in an ADR and validate with a CI regex so the convention survives turnover
Naming conventions, broker governance, event-driven architecture: we help tech teams structure their asynchronous messaging. Let’s talk.

