This page states that "Messages in Storage queues are typically first-in-first-out".
One example is given where messages can arrive out of order. Are there other possible causes/scenarios?
Ignoring the visibility-timeout scenario, is it expected that FIFO would be maintained under the following scenarios?
Scenario 1:
High volume, i.e. when there is a very large number of messages in the queue (e.g. would a message from half-way down the queue suddenly appear at the top? How non-deterministic is the ordering?).
Scenario 2:
High throughput, i.e. a large number of readers and writers.
Scenario N:
Are there any other known scenarios where FIFO is not adhered to? (E.g. if a failover occurs within Azure Storage).
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
@cbailiss Thank you for your feedback! We will review and provide an update as appropriate.
@KetanChawda-MSFT
Thanks.
This question is about Azure Storage queues - not Service Bus (I see you have added a Service Bus label).
@cbailiss Thank for confirmation. Added the storage label as well. The labels were added based on the documentation.
@SumanthMarigowda-MSFT can you please help here on storage query.
@cbailiss The fact is more about FIFO _guarantee_ in the event of failures. Both storage and service bus queues add failed messages back to the queue to the end of the queue (as if its a newly added message) but might be out of order since your consumers could have received the next messages before its added back.
_But_ Service Bus _guarantees_ FIFO through the use of message sessions as stated in the documentation.
The scenarios you've mentioned are still FIFO assuming there are no failures causing messages to be re-added to the queue. Also, if you have more than one consumer on the same queue, the messages would be load balanced across them thereby losing the order there to.
If FIFO is strictly required for you use case, service bus + message sessions is the way to go. Note that sessions are locked by the first consumer to connect.
Thank you @PramodValavala-MSFT - that is useful information.
One follow-up question - you say:
Also, if you have more than one consumer on the same queue, the
messages would be load balanced across them thereby losing the
order there to.
To what extent is the order lost when there are multiple consumers? If there is a single consumer on a queue that contains 1000 messages, then a second consumer connects, is it possible that a newly added message would go straight to consumer B whilst consumer A still has a backlog of 1000 messages to consume? (which is not very FIFO at all)
Or is it more that both consumers would work through the 1000 messages consuming messages from the front of the queue, but at the very front it is not exactly FIFO within the first X number of messages where X is a very small percentage of the total messages in the queue?
In the two scenarios above, the first is not really FIFO, but the second is very close to FIFO.
I am asking because my requirement is to have close to FIFO, but I want to ensure there are no scenarios (ignoring failures) where a newly added message could jump to the front of the queue bypassing most of the messages already in the queue.
Put it another way, if in a high throughput scenario, at a point in time a queue only contains say 4 messages, and two consumers are rapidly reading messages, I am OK with these being read slightly out of order, but I am not OK with one consumer picking up a newly added message when there are 1000 older messages waiting to be read.
It feels to me like storage queues have a reasonable guarantee of ordering (ignoring failures), but that for simplicity/efficiency they don't guarantee it down to the level of single specific messages at the very front of the queue. Is my rough understanding correct?
@cbailiss Always from the front unless you are setting Prefetch or using ReceiveBatch.
It feels to me like storage queues have a reasonable guarantee of ordering (ignoring failures), but that for simplicity/efficiency they don't guarantee it down to the level of single specific messages at the very front of the queue. Is my rough understanding correct?
Yes. Service Bus queues are similar too except that they optionally offer Message Sessions to overcome it.
Also, I believe the re-added messages are not necessarily added to the end of the queue contrary to what I said before but ordering is still not guaranteed because the consumers may pick up the next messages before its re-added.
Thank you, that makes sense and is all very useful information.
It might be useful to request some of this information is added into the docs page, to expand on what "typically" means in a bit more detail. "Typically" followed by one example (as the current page is written) is a bit ambiguous.
A statement like the following provides a more clarity:
Storage queues are always read from the front of the queue, except:
a) When failed messages are re-added to the queue (the failed message may appear after messages added more recently)
b) When multiple consumers exist, each using Prefetch or ReceiveBatch (since these read sets of messages from the front of the queue that could be processed at different times/rates by the consumer).
@cbailiss Glad we could help! I believe these details are scattered around the Service Bus docs and this doc is probably assuming key workings are understood.
@axisc Thoughts?
Most helpful comment
@cbailiss The fact is more about FIFO _guarantee_ in the event of failures. Both storage and service bus queues add failed messages back to the queue
to the end of the queue (as if its a newly added message)but might be out of order since your consumers could have received the next messages before its added back._But_ Service Bus _guarantees_ FIFO through the use of message sessions as stated in the documentation.
The scenarios you've mentioned are still FIFO assuming there are no failures causing messages to be re-added to the queue. Also, if you have more than one consumer on the same queue, the messages would be load balanced across them thereby losing the order there to.
If FIFO is strictly required for you use case, service bus + message sessions is the way to go. Note that sessions are locked by the first consumer to connect.