The Claim Check Pattern
Message brokers have size limits. Kafka defaults to 1 MB per message. SQS caps messages at 256 KB. RabbitMQ, NATS, and Azure Service Bus all draw a line somewhere. Cross it, and the broker rejects your message.
What to Try First
When you hit the limit, the first instinct is to work around it:
- Increase the broker limit. This workaround uses extra memory on the broker. It slows down replication. It also reduces throughput for other messages.
- Split the message. You need to manage three tasks. First, ordering. Second, reassembly. Third, handling partial failure. The formal version of this is Split[1] and Aggregate[2]. Complexity compounds fast.
- Compress the payload. This buys time but is not a permanent solution. Compression ratios depend on data shape. Payloads are getting bigger. We will reach the limit again in the future.
The problem isn't the size of the payload. It's the assumption that the payload has to travel through the broker at all.
The Pattern
The Claim Check pattern[3] works like a coat check at a venue. You hand over your coat, the large payload, and get a ticket. A small, lightweight token. When you need the coat back, you present the ticket.
This is common enough that cloud providers and frameworks ship dedicated solutions for it. AWS built the SQS Extended Client Library[4]. Azure has claim check support baked into Service Bus[5] [6]. Kafka ecosystems lean on Tiered Storage[7]. NServiceBus ships it as a DataBus feature[8].
In a messaging system:
- The producer stores the large payload in external storage like S3, Azure Blob Storage, GCS, or a database.
- The producer publishes a small message to the broker containing only a reference to the stored payload: the claim check.
- The consumer receives the reference, fetches the full payload from storage, and processes it.
The broker never touches the large payload. It only carries the ticket.
Try It
Drag the slider to push the message size past the broker limit. Then toggle the Claim Check pattern to see how the flow changes. You can also find this widget as a standalone tool.
- 1Producer sends the 128 KB payload to the broker.
- 2Broker acknowledges receipt.
- 3Consumer polls the broker for new messages.
- 4Broker delivers the full 128 KB payload to the consumer.
- 5Consumer acknowledges processing.
When to Reach for It
- Large payloads. Anything approaching or exceeding the broker's size limit.
- Binary content. Images, videos, documents. These already have a natural reference (a URL or object key). If you pass them by reference, you are already doing claim check.
- Cost-sensitive pipelines. Brokers charge per message and per GB transferred. Smaller messages mean lower bills.
- Decoupled payload lifecycles. The message might be acknowledged in milliseconds, but the payload needs to stick around for auditing, compliance, or reprocessing.
What It Costs
- Storage dependency. The consumer needs access to the storage system. If storage is down, processing stalls even if the broker is healthy.
- Extra latency. One more round-trip to fetch the payload. For latency-sensitive paths, this adds up.
- Cleanup responsibility. Stored payloads don't delete themselves. You need TTL policies, lifecycle rules, or explicit cleanup. Pick one and enforce it.
- Access control. The reference must be usable by the consumer without leaking access to unrelated data. Scoped credentials or pre-signed URLs handle this, but they add operational surface.
The Principle
The Claim Check pattern respects a boundary that most workarounds try to erase. The broker moves messages. Storage holds data. When you stop forcing one system to do another's job, both work better.
Don't raise the limit. Send a ticket.
References
- [1]Sequencer — Enterprise Integration Patterns↩
- [2]Aggregator — Enterprise Integration Patterns↩
- [3]Store in Library — Enterprise Integration Patterns↩
- [4]SQS Extended Client Library — AWS↩
- [5]Claim Check Pattern — Azure Architecture↩
- [6]Claim Check with Azure Service Bus — Serverless360↩
- [7]Tiered Storage — Confluent↩
- [8]DataBus — NServiceBus↩
- [9]Claim Check Pattern — Wikipedia↩
Talk to you later 🐊 alligator.