A message queue holds work between producers, which add messages at the tail, and consumers, which read them from the head. This lets the two sides run at different speeds: a burst of requests can wait while workers catch up. Producers can even keep sending while workers are stopped for maintenance. section 14.2
Amazon Simple Queue Service (SQS) provides managed message queues, but an ordinary SQS queue does not guarantee that messages will be consumed in the order sent. An SQS FIFO (first in, first out) queue guarantees message order and has a mechanism to detect duplicate messages. Use that distinction when the order of operations matters; duplicate detection does not remove the need to consider how a worker handles repeated processing. section 14.2 section 14.2.6
A screenshot worker
A Node.js producer sends a URL and unique ID to SQS, then returns the ID to the user. A worker reads the message, captures the page, and uploads a PNG to Amazon S3 under that ID. The user can check S3 for the result without waiting for the screenshot operation. This demonstrates queue-based decoupling, not a FIFO-specific configuration. section 14.2.2
For each message, a worker follows a short cycle:
- Receive it by polling SQS; long polling can wait for work rather than returning immediately from an empty queue. section 14.2.5
- Process it within the visibility timeout. If it is not deleted in time, it can become available again. section 14.2.5
- After successful processing, delete it using its receipt handle to acknowledge completion. section 14.2.5
FIFO ordering has a cost: the stated trade-offs are higher pricing and a limit of 3,000 operations per second. If strict order is unnecessary, consider designing work so that order does not matter. SQS is a queue, not a message broker with features such as routing or priorities. section 14.2.6
Listing 14.8 worker.js: Connecting the parts
async function run() {
while(true) { #1
const message = await receive(); #2
if (message) {
console.log('Processing message', message);
await process(message); #3
await acknowledge(message); #4
}
await new Promise(r => setTimeout(r, 1000)); #5
}
};
run(); #6
The worker loop shows the receive–process–acknowledge cycle shared by the queue example; it does not configure FIFO behavior. section 14.2.5






















