KubeMQ
LearnQueuesHow-To Guides

Message Expiration (TTL)

Set time-to-live for queue messages to auto-expire unprocessed items.

How Expiration Works

Messages with expirationSeconds > 0 are automatically discarded if not consumed before the TTL elapses. Expired messages are removed on the next receive operation.

An unconsumed message is silently discarded once its TTL elapses — the next poll never sees it.

Set Message Expiration

expiration.go
msg := kubemq.NewQueueMessage().
    SetChannel("time-sensitive-orders").
    SetBody([]byte(`{"orderId":"ORD-7001","type":"flash-sale"}`)).
    SetExpirationSeconds(300)

result, err := client.SendQueueMessage(ctx, msg)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Sent with 5-minute TTL: id=%s, expiresAt=%d\n",
    result.MessageID, result.ExpiresAt)
expiration.py
result = client.send_queue_message(
    QueueMessage(
        channel="time-sensitive-orders",
        body=b'{"orderId":"ORD-7001","type":"flash-sale"}',
        expiration_in_seconds=300,
    )
)
print(f"Sent with 5-minute TTL: id={result.id}, expiresAt={result.expires_at}")
expiration.ts
const result = await client.sendQueueMessage(
  createQueueMessage({
    channel: 'time-sensitive-orders',
    body: JSON.stringify({ orderId: 'ORD-7001', type: 'flash-sale' }),
    policy: { expirationSeconds: 300 },
  }),
);
console.log(`Sent with 5-minute TTL: id=${result.messageId}, expiresAt=${result.expiresAt}`);
Expiration.java
QueueMessage msg = QueueMessage.builder()
    .channel("time-sensitive-orders")
    .body("{\"orderId\":\"ORD-7001\",\"type\":\"flash-sale\"}".getBytes())
    .expirationSeconds(300)
    .build();

SendQueueMessageResult result = client.sendQueueMessage(msg);
System.out.printf("Sent with 5-minute TTL: id=%s, expiresAt=%d%n",
    result.getMessageId(), result.getExpiresAt());
Expiration.cs
var result = await client.SendQueueMessageAsync(new QueueMessage
{
    Channel = "time-sensitive-orders",
    Body = Encoding.UTF8.GetBytes("{\"orderId\":\"ORD-7001\",\"type\":\"flash-sale\"}"),
    ExpirationSeconds = 300
});
Console.WriteLine($"Sent with 5-minute TTL: id={result.MessageId}, expiresAt={result.ExpiresAt}");
Expiration.kt
val result = client.sendQueueMessage(QueueMessage(
    channel = "time-sensitive-orders",
    body = """{"orderId":"ORD-7001","type":"flash-sale"}""".toByteArray(),
    expirationSeconds = 300
))
println("Sent with 5-minute TTL: id=${result.messageId}, expiresAt=${result.expiresAt}")
expiration.cpp
kubemq::QueueMessage msg;
msg.channel = "time-sensitive-orders";
msg.body = R"({"orderId":"ORD-7001","type":"flash-sale"})";
msg.expirationSeconds = 300;

auto result = client.sendQueueMessage(msg);
std::cout << "Sent with 5-minute TTL: id=" << result.messageId << std::endl;
expiration.rs
let msg = QueueMessageBuilder::new()
    .channel("time-sensitive-orders")
    .body(br#"{"orderId":"ORD-7001","type":"flash-sale"}"#.to_vec())
    .expiration_seconds(300)
    .build();

let result = client.send_queue_message(msg).await?;
println!(
    "Sent with 5-minute TTL: id={}, expiration_at={}",
    result.message_id, result.expiration_at
);
expiration.rb
policy = KubeMQ::Queues::QueueMessagePolicy.new(expiration_seconds: 300)
msg = KubeMQ::Queues::QueueMessage.new(
  channel: 'time-sensitive-orders',
  body: '{"orderId":"ORD-7001","type":"flash-sale"}',
  policy: policy
)

result = client.send_queue_message(msg)
puts "Sent with 5-minute TTL: id=#{result.id}, expiration_at=#{result.expiration_at}"
expiration.exs
msg = KubeMQ.QueueMessage.new(
  channel: "time-sensitive-orders",
  body: ~s({"orderId":"ORD-7001","type":"flash-sale"}),
  policy: KubeMQ.QueuePolicy.new(expiration_seconds: 300)
)

{:ok, result} = KubeMQ.Client.send_queue_message(client, msg)
IO.puts("Sent with 5-minute TTL: id=#{result.message_id}, expiration_at=#{result.expiration_at}")

What Happens to Expired Messages

BehaviorDetail
Expiration checkOccurs during receive operations (not a background timer)
Expired messagesDiscarded silently — not delivered to consumers
No DLQ routingExpired messages are not sent to dead letter queues
Delay interactionIf delay + expiration are both set, expiration starts after the delay ends

Delay + Expiration Interaction

DelayExpirationAvailable AtExpires At
0300sImmediatelyT+300s
60s300sT+60sT+360s
60s0T+60sNever

The maximum expiration is controlled by the server setting MaxExpirationSeconds (default: 43,200 seconds / 12 hours).

Next Steps

Was this page helpful?

On this page