Cheat SheetsRabbitMQAdvanced Queue Types

Advanced Queue Types — Cheat Sheet

RabbitMQ · 5 topics. Download the PDF or the Instagram carousel and share it.

Cheat Sheet · AiCanCode.org
Advanced Queue Types
RabbitMQ5 topicsQuick revision reference
1

Priority Queues

Declare x-max-priority on a queue to enable priority levels (0–255); higher-priority messages are delivered first, allowing urgent tasks to skip ahead of normal work.

  • x-max-priority works only on classic queues — quorum queues do not support priority.
  • Keep x-max-priority ≤ 10; each priority level allocates an internal sub-queue even when empty.
  • Priority only matters under backlog — if consumers keep up, messages are still delivered FIFO.
  • Set consumer prefetch=1 when using priority queues to prevent high-priority messages being blocked behind pre-fetched low-priority ones.
  • For more than ~3 priority tiers, separate queues per tier with dedicated consumers is more predictable.
  • Monitor queue depth per-queue (not per-priority); there is no per-priority depth metric in RabbitMQ management.
Java — Spring AMQP priority queue declaration and publish
@Configuration
public class PriorityQueueConfig {

    // Declare priority queue with max 10 priority levels (0–10)
    // Keep x-max-priority small (≤10) — each level needs its own internal queue
    @Bean
    public Queue orderPriorityQueue() {
        return QueueBuilder.durable("orders.priority")
            .withArgument("x-max-priority", 10)
            .build();
    }
}

// Publisher: set priority per message
@Service
public class OrderPublisher {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void publish(OrderEvent event, int priority) {
        rabbitTemplate.convertAndSend(
            "orders.exchange", "order.priority", event,
            message -> {
                message.getMessageProperties().setPriority(priority);
                return message;
            }
        );
    }

    public void publishUrgent(OrderEvent event) {
        publish(event, 10);   // highest priority — jumps the queue
    }

    public void publishNormal(OrderEvent event) {
        publish(event, 5);    // medium
    }

    public void publishBulk(OrderEvent event) {
        publish(event, 1);    // lowest priority
    }
}
2

Quorum Queues

Quorum queues use the Raft consensus algorithm for data safety with leader election; they offer stronger durability guarantees than classic mirrored queues in clustered setups.

  • Quorum queues use Raft consensus — a write is acknowledged only when a majority of nodes persist it, preventing data loss.
  • Quorum queues replace deprecated classic mirrored queues; they eliminate split-brain scenarios on network partitions.
  • Always durable by design — non-durable quorum queues are not supported.
  • x-delivery-limit on a quorum queue automatically dead-letters messages that are nacked and requeued too many times — built-in poison message protection.
  • Trade-off: quorum queues have higher write latency (Raft round-trip) and more memory usage than non-replicated classic queues.
  • For production clusters, default to quorum queues for any queue that holds data you cannot afford to lose.
Java + Shell — Declaring Quorum Queues
// Low-level AMQP client
Channel channel = connection.createChannel();

Map<String, Object> args = new HashMap<>();
args.put("x-queue-type", "quorum");
args.put("x-quorum-initial-group-size", 3);  // default: use 3 nodes

// Quorum queues are always durable=true — non-durable is not supported
channel.queueDeclare("orders-quorum", true, false, false, args);

// Spring AMQP
@Bean
public Queue ordersQuorumQueue() {
    return QueueBuilder.durable("orders-quorum")
        .quorum()               // sets x-queue-type=quorum
        .quorumInitialGroupSize(3)
        .build();
}

# OR via rabbitmq.conf — make quorum the default policy
# Match all queues with a policy:
rabbitmqctl set_policy quorum-queues ".*" \
    '{"queue-mode":"default","x-queue-type":"quorum"}' \
    --apply-to queues
3

Lazy Queues

Lazy queues write messages to disk immediately, reducing memory usage for deep queues; ideal when consumers are slow and a large backlog must be held without crashing the broker.

  • Lazy queues write messages to disk immediately, keeping RAM free for other operations.
  • Default queues keep messages in RAM and page to disk only under memory pressure.
  • The memory watermark (default 40% RAM) triggers producer blocking — lazy queues help avoid it.
  • In RabbitMQ 3.12+, classic queues are lazy by default.
  • Apply laziness via x-queue-mode=lazy declaration argument or a policy (no restart needed).
  • For new HA deployments, prefer quorum queues; use lazy classic queues for large backlog scenarios.
Java + Shell — declaring and enabling lazy queues
// Spring AMQP — declare a lazy queue
@Bean
public Queue lazyOrderQueue() {
    return QueueBuilder.durable("orders.processing")
        .lazy()    // x-queue-mode=lazy
        .build();
}

// Or manually via arguments
@Bean
public Queue lazyQueue() {
    return QueueBuilder.durable("bulk-exports")
        .withArgument("x-queue-mode", "lazy")
        .build();
}

# Apply lazy mode to existing queues via management API or CLI
# (no restart required — takes effect for new messages)
rabbitmqctl set_policy lazy-queues ".*" \
  '{"queue-mode":"lazy"}' \
  --apply-to queues

# RabbitMQ 3.12+ — classic queues are lazy by default
# Explicitly set to default (in-memory) mode:
@Bean
public Queue defaultModeQueue() {
    return QueueBuilder.durable("hot-path")
        .withArgument("x-queue-mode", "default")  // in-memory (legacy fast mode)
        .build();
}
4

RabbitMQ Streams

RabbitMQ Streams (3.9+) provide a persistent, append-only log akin to Kafka topics; multiple consumers can read from any offset without deleting messages on acknowledgement.

  • Streams are append-only logs — acknowledged messages are NOT deleted; retention is by age or total size.
  • Each consumer independently tracks its own offset — replay, fan-out, and concurrent reads all work without interference.
  • The dedicated stream protocol (port 5552) outperforms AMQP for high-throughput stream consumers.
  • Named consumers with autoTrackingStrategy persist offsets server-side — safe for consumer restarts.
  • Streams require the stream_queue feature flag (RabbitMQ 3.9+) and rabbitmq_stream plugin enabled.
  • Use streams for fan-out to many consumers; use classic queues for competing-consumers (work queue) patterns.
Java — declare stream + publish via stream client
<!-- pom.xml -->
<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>stream-client</artifactId>
  <version>0.15.0</version>
</dependency>

// Declare stream via AMQP (standard RabbitTemplate)
@Bean
public Queue orderEventStream() {
    return QueueBuilder.durable("order-events-stream")
        .withArgument("x-queue-type", "stream")
        .withArgument("x-max-length-bytes", 10_000_000_000L) // 10 GB max
        .withArgument("x-max-age", "7D")                     // 7-day retention
        .build();
}

// Publishing via standard AMQP (same as classic queue)
rabbitTemplate.convertAndSend("", "order-events-stream", event);

// OR use dedicated stream Environment for high throughput
Environment env = Environment.builder()
    .host("localhost")
    .port(5552)
    .build();

Producer producer = env.producerBuilder()
    .stream("order-events-stream")
    .build();

producer.send(
    producer.messageBuilder()
        .addData(serialize(event))
        .properties().messageId(UUID.randomUUID().toString())
        .messageBuilder().build(),
    confirmationStatus -> {
        if (!confirmationStatus.isConfirmed()) {
            log.warn("Message not confirmed");
        }
    }
);
5

Delayed Message Exchange

The community delayed-message plugin stores messages and delivers them after a configurable x-delay (ms), enabling scheduled tasks and retry-after-delay patterns.

  • x-delayed-message exchange holds messages internally until x-delay ms elapses, then routes normally
  • Requires the community rabbitmq_delayed_message_exchange plugin — not bundled by default
  • Delayed messages are stored on a single node — NOT replicated; node failure loses pending delays
  • For HA clusters, prefer the TTL+DLX retry pattern which uses standard replicated queues
  • x-delay header value is in milliseconds; maximum useful delay is limited by memory on the node
  • The underlying routing type (x-delayed-type: direct/topic/fanout) is set as a declaration argument
Java — CustomExchange for delayed message plugin
# Install the plugin on the broker
rabbitmq-plugins enable rabbitmq_delayed_message_exchange

# Spring AMQP bean declaration
@Bean
public CustomExchange delayedExchange() {
    Map<String, Object> args = new HashMap<>();
    args.put("x-delayed-type", "direct");   // underlying routing type
    return new CustomExchange(
        "orders.delayed",   // exchange name
        "x-delayed-message",// exchange type
        true,               // durable
        false,              // auto-delete
        args
    );
}

@Bean
public Queue scheduledOrderQueue() {
    return QueueBuilder.durable("orders.scheduled").build();
}

@Bean
public Binding delayedBinding(Queue scheduledOrderQueue, CustomExchange delayedExchange) {
    return BindingBuilder.bind(scheduledOrderQueue)
        .to(delayedExchange).with("order.scheduled").noargs();
}
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/rabbitmq