I'm trying to understand how to configure my Lambda function with SQS. I set the reserved concurrency for my Lambda to 1 and the maximum concurrency for the SQS trigger to 2. I also set the visibility timeout for SQS to 1.5 hours. However, during my tests, I noticed that two tasks are always being pulled at the same time, even though my Lambda can only process one at a time. This leads to tasks getting stuck in the queue, which increases over time. Is there a way to truly achieve a rate of QPS 1 with this setup?
5 Answers
Just a quick note, the minimum supported max concurrency is 2 according to AWS docs. So you might need to consider that in your settings!
I’ve noticed that when a Lambda function exceeds 5 minutes of processing time, it keeps any extra tasks in progress until the visibility timeout. If your tasks generally take around a minute, they don’t stay pending for that long. Is this what’s happening in your case? I feel like it might just be a timing illusion you’re having.
It seems your Lambda might be timing out after 5 minutes. Keep in mind that Lambda has a fixed timeout limit, and if your SQS visibility timeout is set to 1.5 hours, the messages won't be processed until then. One suggestion is to keep the visibility timeout around 6 minutes and ensure your Lambda finishes its work quickly. If it's taking too long, it might not be the best fit for Lambda at all.
Are you sure you aren't sending both tasks to the same Lambda run? Normally, SQS sends multiple messages as a batch, so if two tasks are in the queue, your Lambda can handle them one after the other within the same invocation. You could actually increase the SQS max concurrency beyond two and let your Lambda manage multiple items sequentially.
It sounds like you're facing a visibility timeout issue. Your timeout is too long, which isn't directly your problem but could complicate things. To limit your Lambda concurrency to 1 properly, you should use a FIFO queue and keep all messages in the same message group. This way, you won't run into the issue of multiple pollers trying to pick them up at the same time.
Exactly! By using a FIFO queue, you can streamline your process. Plus, you won't need to mess with reserved concurrency anymore and can set a reasonable SQS visibility timeout that fits your function's duration.