Home/Learn/RabbitMQ/Message Properties

Message Properties

Intermediate
Queues

AMQP properties include delivery-mode (persistent/transient), content-type, correlation-id, reply-to, expiration, headers, and priority — all set by the producer per message.

Overview

Every AMQP message carries a set of well-known properties in its envelope header. The most important are delivery-mode (1=transient, 2=persistent), content-type (e.g. "application/json"), content-encoding, correlation-id (links a response to a request in RPC), reply-to (name of the queue to send the response to), message-id (publisher-assigned unique ID), expiration (per-message TTL in milliseconds as a string), priority (0-9 for priority queues), and user-defined headers (Map<String,Object>). In Spring AMQP, MessageProperties encapsulates all of these, and MessagePostProcessors let you set them per-send without modifying the payload.

Setting Message Properties

Use a MessagePostProcessor in convertAndSend to set properties on each message. For consistent defaults across an application, configure a MessagePropertiesConverter on the RabbitTemplate.

Java — setting MessageProperties via PostProcessor
rabbitTemplate.convertAndSend("orders", "order.created", event, message -> {
    MessageProperties props = message.getMessageProperties();
    props.setDeliveryMode(MessageDeliveryMode.PERSISTENT);   // survive restart
    props.setContentType("application/json");
    props.setMessageId(UUID.randomUUID().toString());
    props.setCorrelationId(requestContext.getTraceId());
    props.setExpiration("60000");                            // 60s per-message TTL
    props.setHeader("source-service", "order-service");
    props.setHeader("schema-version", "2");
    return message;
});

RPC Pattern with correlation-id and reply-to

correlation-id and reply-to are the two properties that power the RPC pattern. The caller sets reply-to to its exclusive reply queue, and correlation-id to a unique request ID. The server echoes the correlation-id in its response so the caller can match it.

Java — correlation-id / reply-to RPC pattern
// Caller side
String correlationId = UUID.randomUUID().toString();
String replyQueueName = "rpc.reply." + correlationId;

rabbitTemplate.convertAndSend("rpc.requests", "", request, msg -> {
    msg.getMessageProperties().setCorrelationId(correlationId);
    msg.getMessageProperties().setReplyTo(replyQueueName);
    return msg;
});

// Server side — echo correlation-id in response
@RabbitListener(queues = "rpc.requests")
public void handleRequest(Message request, Channel channel) throws Exception {
    String replyTo       = request.getMessageProperties().getReplyTo();
    String correlationId = request.getMessageProperties().getCorrelationId();
    // ... process ...
    rabbitTemplate.convertAndSend(replyTo, response, msg -> {
        msg.getMessageProperties().setCorrelationId(correlationId);
        return msg;
    });
}

Reading Properties on Consumer Side

In @RabbitListener methods, inject Message to access the full AMQP envelope including all properties and headers. Use @Header to extract individual header values directly.

Java — reading message properties in @RabbitListener
@RabbitListener(queues = "orders.processing")
public void onOrder(
        OrderEvent event,
        @Header("source-service") String sourceService,
        @Header(AmqpHeaders.CORRELATION_ID) String correlationId,
        @Header(AmqpHeaders.RECEIVED_ROUTING_KEY) String routingKey,
        Message rawMessage) {

    log.info("Source: {}, correlationId: {}, routingKey: {}",
             sourceService, correlationId, routingKey);

    // Full access to all properties
    MessageProperties props = rawMessage.getMessageProperties();
    String messageId = props.getMessageId();
    String contentType = props.getContentType();
}

Key Points to Remember

  • 1delivery-mode=2 (PERSISTENT) is required for messages to survive broker restart
  • 2correlation-id + reply-to together implement the RPC/request-reply pattern
  • 3expiration is per-message TTL in milliseconds as a String (independent of queue x-message-ttl)
  • 4headers is a Map<String,Object> for arbitrary application-level metadata
  • 5priority (0-9) is honoured only if the queue was declared with x-max-priority argument
  • 6Use @Header annotation in @RabbitListener to extract individual properties cleanly

Interview Questions

Sign in to ask Aria
1

What are the two message properties used to implement the RPC pattern?

MediumPivotal
2

What is the difference between per-message expiration and queue x-message-ttl?

MediumZalando
3

How do you set consistent default properties for all messages sent via RabbitTemplate?

MediumInfosys
4

What delivery-mode value makes a message persistent?

EasyTCS
5

How would you pass trace/correlation IDs through RabbitMQ for distributed tracing?

HardNetflix

Ask Aria about Message Properties

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…