Larkspur Queue: limits and behavior
Larkspur Queue is a managed message queue for passing work between services. Producers send messages to a queue, and consumers receive them, process them, and delete them when they are done. This page describes the limits that apply to every queue and how the service behaves at those limits. Limits are the same in every region unless a section says otherwise.
Queue types
There are two queue types. Standard queues deliver each message at least once and make a best effort to keep messages in the order they were sent. Ordered queues deliver each message exactly once, in the order it was sent within a message group, at a lower throughput.
The queue type is chosen when the queue is created and cannot be changed later. To move from one type to the other, create a new queue, point producers at it, and drain the old queue before deleting it.
Throughput
Throughput limits apply per queue. Requests above the limit are rejected with error 429 and can be retried after the delay given in the Retry-After header.
| Queue type | Send rate | Receive rate |
|---|---|---|
| Standard | 3,000 messages per second | 3,000 messages per second |
| Ordered | 300 messages per second | 300 messages per second |
Batching counts each message in a batch toward the limit, so a batch of ten messages uses ten units of the send rate. Throughput limits can be raised for standard queues by request; ordered queue limits are fixed.
Message size
The maximum message size is 256 KB, including attributes. Larger messages are rejected unless the queue has large-message offload enabled, in which case messages up to 2 GB are stored in object storage and the queue holds a pointer to them. Offloaded messages are billed for storage at the object storage rate.
Messages are rejected with error 413 when any of the following is true:
- the body exceeds 256 KB and offload is disabled
- the message has more than 10 attributes
- an attribute name is longer than 256 characters
Attribute values count toward the message size. Attribute names and values must be valid UTF-8; binary data must be encoded before it is sent.
Retention
Messages are retained for 4 days by default. The retention period can be set from 60 seconds to 14 days. A message that is still in the queue when its retention period ends is deleted, even if it has never been received.
Changing the retention period applies to messages already in the queue as well as new ones. Shortening it can therefore delete messages immediately.
Visibility timeout
When a consumer receives a message, the message stays in the queue but is hidden from other consumers for the visibility timeout, 30 seconds by default and at most 12 hours. If the consumer does not delete the message before the visibility timeout expires, the message becomes visible again and may be delivered to another consumer.
A consumer that needs more time can extend the timeout for a message it has received. The total time a message can stay hidden, counting every extension, is still limited to 12 hours.
SDK calls
The SDK wraps the HTTP API. The calls below are the ones most often asked about.
send(body, attributes=None, delay_seconds=0)- Sends one message. With a delay, the message becomes visible to consumers only after delay_seconds, at most 900 seconds.
receive(max_messages=1, wait_seconds=20)- Returns up to max_messages messages, at most 10 per call. If wait_seconds is 0, the call returns immediately even when the queue is empty; otherwise it waits up to wait_seconds for a message to arrive.
delete(receipt)- Deletes a received message using the receipt from the receive call. A receipt is valid only until the message's visibility timeout expires.
Dead-letter queues
A queue can name a dead-letter queue and a maximum receive count. When a message has been received more times than the maximum receive count without being deleted, it is moved to the dead-letter queue instead of becoming visible again. The dead-letter queue must be of the same type and in the same region as the source queue.
Moving a message to a dead-letter queue does not reset its retention period, so a message that was already close to the end of its retention period can expire soon after it arrives in the dead-letter queue.
Message groups
Ordered queues keep order within a message group, not across the whole queue. Each message carries a group ID, and messages with the same group ID are delivered one at a time in the order they were sent. Messages in different groups can be delivered in parallel, so spreading work across many groups raises the throughput a consumer fleet can reach.
While a message from a group is hidden by its visibility timeout, no other message from that group is delivered. A consumer that fails to delete a message therefore blocks its group until the timeout expires or the message is moved to the dead-letter queue.
Standard queues ignore group IDs. Sending a group ID to a standard queue is allowed and has no effect, which makes it possible to share producer code between the two queue types.
Long polling
A receive call with a wait time above zero is a long poll. The service holds the request open until a message arrives or the wait time ends, whichever comes first, which reduces the number of empty receives when a queue is quiet. The longest wait time is 20 seconds.
Long polls count toward the receive rate only when they return. A consumer that keeps several long polls open at once can receive messages as soon as they arrive, at the cost of more open connections.
Encryption
All messages are encrypted at rest with keys managed by Larkspur. Customers who need to control the keys can attach their own key from the key service; the queue then uses that key for every new message, and messages already in the queue keep the key they were written with.
If a customer key is disabled or deleted, messages encrypted with it can no longer be received. They stay in the queue until their retention period ends and are then deleted. Re-enabling the key makes them readable again.
Messages are always encrypted in transit. Requests over plain HTTP are rejected.
Access control
Access to a queue is granted with policies attached to the queue or to the caller's role. A request is allowed only if a policy allows it and no policy denies it. The actions that can be granted are:
- queue:Send, to send messages
- queue:Receive, to receive messages and change their visibility timeout
- queue:Delete, to delete received messages
- queue:Admin, to change the queue's settings or delete the queue
Policies that grant access to another account must name that account explicitly. Wildcard principals are rejected for queues that hold encrypted messages with a customer key.
Monitoring
Every queue publishes metrics once a minute. The most useful ones for capacity planning are the number of visible messages, the age of the oldest message, and the number of messages moved to the dead-letter queue. Alarms can be set on any of them.
Metrics are kept for 15 months. After that, only daily aggregates remain.
Error codes
| Code | Meaning | What to do |
|---|---|---|
| 400 | The request is malformed | Fix the request; retrying will not help |
| 403 | No policy allows the action | Grant the action to the caller |
| 404 | The queue does not exist in this region | Check the queue name and the endpoint |
| 413 | The message is too large | Reduce the size or enable offload |
| 429 | The throughput limit was exceeded | Retry after the Retry-After delay |
| 503 | The service is temporarily unavailable | Retry with exponential backoff |
Regions
Queues are regional. A queue and its messages stay in the region where the queue was created, and requests must be sent to that region's endpoint. Cross-region forwarding is not available; services in other regions must call the queue's regional endpoint directly.
New regions are announced on the status page. Existing queues are not moved when a region is added.
Billing
Each send, receive, delete, or timeout change counts as one request. Requests are billed per million, and the first million requests each month are free. Payload size is billed in 64 KB chunks, so a 100 KB message counts as two requests. Empty receives, where no message was returned, are billed like any other receive.
Data transfer within a region is free. Transfer to the internet is billed at the standard network rate.
Frequently asked questions
Can I see how many messages are in a queue?
Yes. The queue's metrics report the approximate number of visible messages, the number of hidden messages, and the age of the oldest message. The counts are approximate because messages are spread across several servers.
Can a queue be renamed?
No. Queue names are fixed when the queue is created. Create a new queue with the new name and move producers and consumers to it.
What happens to messages when a queue is deleted?
Deleting a queue deletes every message in it, visible or hidden, and the deletion cannot be undone. A queue with the same name can be created again after 60 seconds; it starts empty and does not inherit the old queue's policies, dead-letter settings, or customer key.
Is there a limit on the number of queues?
An account can create up to 1,000 queues per region. The limit can be raised by request.