Skip to main content

Queues

Queue up work in your SST app.


Overview​

Typically most async scenarios should be handled with Events. However if you want more control over processing you can use Queues.

Let's look at it in detail.


Get started​

Start by creating a new SST + Next.js app by running the following command in your terminal. We are using Next.js for this example but you can use your favorite frontend.

npx create-sst@two --template standard/nextjs

Create a queue​

Let's start by adding a queue to our app.

stacks/Default.ts
const queue = new Queue(stack, "queue", {
consumer: "packages/functions/src/consumer.handler",
});
info

A Queue can have only one consumer that can pull the messages from the queue.

Make sure to import the Queue construct.

stacks/Default.ts
- import { StackContext, NextjsSite } from "sst/constructs";
+ import { Queue, StackContext, NextjsSite } from "sst/constructs";

This construct uses the Amazon Simple Queue Service (SQS).


Bind the queue​

After adding the queue, bind your Next.js app to it.

stacks/Default.ts
const site = new NextjsSite(stack, "site", {
path: "packages/web",
+ bind: [queue],
});

This allows us to access the queue in our Next.js app.


Send to the queue​

Now in our Next.js API we'll send a message to the queue.

packages/web/pages/api/hello.ts
const sqs = new SQSClient({});

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const command = new SendMessageCommand({
QueueUrl: Queue.queue.queueUrl,
MessageBody: "Hello from Next.js!",
});
await sqs.send(command);

res.status(200).send("Hello World!");
}

Add the imports​

Import the required packages.

packages/web/pages/api/hello.ts
import { Queue } from "sst/node/queue";
import type { NextApiRequest, NextApiResponse } from "next";
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";

Make sure to install the AWS SDK.

npm install @aws-sdk/client-sqs

Add the queue handler​

Finally, we can create the Lambda function that'll get invoked when things get sent to the queue.

packages/functions/src/consumer.ts
import { SQSEvent } from "aws-lambda";

export async function handler(event: SQSEvent) {
const records: any[] = event.Records;
console.log(`Message processed: "${records[0].body}"`);

return {};
}

Now if you go to the API endpoint in your browser — http://localhost:3000/api/hello, you can go to your terminal and you'll notice that the message in the queue has been processed.


Other options​

Aside from queues you have a couple of other options for handling more complex asynchronous tasks in your app.

KinesisStream​

The KinesisStream construct uses Amazon Kinesis Data Streams.

stacks/Default.ts
import { KinesisStream } from "sst/constructs";

new KinesisStream(stack, "stream", {
consumers: {
consumer1: "packages/functions/src/consumer1.handler",
consumer2: "packages/functions/src/consumer2.handler",
},
});

It's similar to the Queue in that the consumer pulls the messages, but it's designed to allow for multiple consumers. A KinesisStream also keeps a record of historical messages for up to 365 days, and consumers can re-process them. This makes it a good fit for cases where you are dealing with a large number of events.