Skip to main content
In this guide you’ll build a simple serverless pipeline that processes user-uploaded videos using S3, SNS, SQS, and Lambda. The pattern decouples upload events from processing, enabling reliable, scalable, and asynchronous media workflows. High-level flow:
  • A user uploads a raw video to an S3 bucket (e.g., MP4).
  • S3 publishes an event to an SNS topic (for example, video-uploaded).
  • SNS fans out the notification to two SQS queues:
    • video-processing queue — for transcoding to a streaming format (HLS) and storing output in the processed-videos bucket.
    • thumbnail-processing queue — for extracting still frames and storing them in the thumbnails bucket.
  • Two Lambda functions poll the queues, read the original object from S3, perform work, then write results back to their respective S3 buckets.
A simplified AWS video-processing architecture diagram showing a user uploading raw videos to an S3 bucket, which publishes a "New Video Topic" and pushes messages to queues. Lambda functions consume the queues to generate thumbnails and processed videos, storing the outputs in separate S3 buckets.

Prerequisites

You should create three S3 buckets in advance (names below are examples; use your preferred naming): These buckets are standard; we will add the event notification and permissions as part of the setup. S3 buckets in the console (example):
A screenshot of the AWS S3 Management Console showing a list of five S3 buckets and their regions/access settings. A green notification at the top says the "thumbnails-kodekloud" bucket was successfully created.

Mapping: service responsibilities

1) Create an SNS topic

In the AWS Console: Amazon SNS → Topics → Create topic.
  • Name: video-uploaded (or your preferred name)
  • Type: Standard — ordering is not required for this demo
  • Leave encryption and other settings at defaults for the demo
You can keep the default access policy while creating the topic; we’ll update the SNS topic policy later to allow S3 to publish events. SNS topic created (example):
A screenshot of the AWS Amazon SNS console showing a "video-uploaded" topic with a green banner confirming the topic was created. The page shows the topic details (name, ARN, owner), action buttons (Edit, Delete, Publish message) and sections for subscriptions and policies.

2) Create two SQS queues and subscribe them to SNS

Create two SQS Standard queues:
  • video-processing
  • thumbnail-processing
Keep default settings for visibility timeout, delivery delay, and retention for the demo. Optionally enable encryption. When creating each queue, subscribe it to the SNS topic:
  • Subscription protocol: Amazon SQS
  • Select the video-uploaded SNS topic
Note: When an SQS queue is subscribed to an SNS topic, the queue must allow the topic to send messages via a queue policy. The AWS Console usually creates that queue policy automatically when subscribing via the console. If you subscribe via CLI/SDK, ensure the queue policy permits the SNS topic to send messages. SQS create queue example UI:
A screenshot of the AWS SQS “Create queue” page showing a queue named "video-processing" and its configuration settings. Visible options include visibility timeout (30 seconds), message retention period (4 days), and maximum message size (256 KB).
After subscribing both queues, publishing a test message to the SNS topic should create messages in both queues (messages remain until a consumer processes them):
A screenshot of the AWS SQS Queues page showing two queues named "thumbnail-processing" and "video-processing." Both are Standard queues with 2 messages available and 0 messages in flight.

3) Create Lambda functions that process SQS messages

We will create two Lambda functions:
  • video-processing — downloads the original object from S3, transcodes to HLS (e.g., with ffmpeg), uploads the HLS outputs to processed-videos-kodekloud.
  • thumbnail-processing — downloads the original object, extracts thumbnails, and uploads them to thumbnails-kodekloud.
In the Console: Lambda → Create function → Author from scratch
Example runtime: Node.js 18.x
Create an IAM role for the functions (e.g., LambdaSQS-S3) with the following permissions for the demo:
  • S3 read/write as required (for demo you can use AmazonS3FullAccess, but scope down to least privilege in production)
  • CloudWatch Logs (Lambda managed policy handles logging)
Important: You do not need to grant SQS permissions to the Lambda execution role for invocation; the Lambda service handles polling. However, ensure the SQS queue policy allows SNS to send messages to the queue. Create function (example Node.js runtime):
Screenshot of the AWS Lambda "Create function" console showing the "Author from scratch" option with a function name field filled as "myFunctionName", runtime set to Node.js 18.x, and architecture x86_64. The page also shows options for using a blueprint or a container image and sections for permissions and advanced settings.
Add SQS as a trigger for each Lambda:
  • Choose the appropriate queue per function (video-processing ↔ queue, thumbnail-processing ↔ queue)
  • Batch size: how many messages delivered per invocation (demo uses 1; production may batch)
  • Batch window: how long to wait to collect messages for a batch (0s for immediate invocation)
Minimal Lambda handler to inspect the incoming event (useful for debugging):
How the SQS-triggered Lambda event looks:
  • event.Records — array of SQS messages (length equals number of messages in batch)
  • event.Records[n].body — contains the SNS notification as a JSON string
    • Parse this string to get the SNS envelope, then parse Message to get the original payload (often JSON)
Use this pattern to parse SQS+SNS messages (Node.js):
SQS delivers the SNS notification as the record body. That means your Lambda typically does two parses: first parse the SQS record body to get the SNS envelope, then parse Message to get your original payload.
A production-style video-processing Lambda will:
  • Parse the message to obtain the bucket and key
  • GetObject from S3
  • Run ffmpeg (or use a media processing service) to convert to HLS
  • Upload M3U8 and TS segment files back to the processed bucket
Example Node.js handler using AWS SDK + ffmpeg (simplified):
For production workloads, watch Lambda /tmp disk limits, execution timeout, and memory. Consider using a media service (Elastic Transcoder, MediaConvert, or ECS/Fargate) for large or long-running transcodes. Also scope IAM permissions to least privilege.
After deploying video-processing, you should see the function updated successfully:
A screenshot of the AWS Lambda console showing a function named "video-processing" with an SQS trigger and a green banner indicating the function was successfully updated. The page displays function details (ARN, last modified) and tabs for Code, Test, Monitor, Configuration, etc.
Create thumbnail-processing using a similar approach (you can reuse the same IAM role if permissions match). The thumbnail function should extract frames (e.g., with ffmpeg) and upload them to thumbnails-kodekloud. Lambda functions list example:
Screenshot of the AWS Lambda Functions page showing two functions: "video-processing" and "thumbnail-processing." Both are Zip package type running Node.js 18.x and were last modified about 20 and 18 minutes ago.

4) Configure S3 to publish events to the SNS topic

Configure the raw-videos-kodekloud bucket to send object-created events to the SNS topic: S3 → Buckets → open raw-videos-kodekloud → Properties → Event notifications → Create event notification:
  • Name: video-uploaded
  • Event types: All object create events (s3:ObjectCreated:*)
  • Destination: SNS topic → select video-uploaded
A screenshot of the Amazon S3 console showing the "Create event notification" page for a bucket, with the event name set to "video-uploaded" and filters Prefix "images/" and Suffix ".jpg". The lower part shows selectable object creation event types for the notification.
You must grant the S3 service permission to publish to the SNS topic. Add an SNS topic policy that allows the s3.amazonaws.com principal to call SNS:Publish when requests originate from your bucket. See the Amazon S3 event notifications documentation for details:
A screenshot of the AWS documentation page for Amazon Simple Storage Service (S3) Event Notifications. It shows a list of supported S3 event types and destinations (SNS, SQS, Lambda, EventBridge) with the left navigation menu and informational note/warning boxes.
Example SNS topic policy (replace ARNs/account IDs with your values):
To apply:
  • Open the SNS topic → Edit → Access policy → add the statement to the policy’s Statement array and save.
  • Return to the S3 event notification and save it. If saving fails, check the topic policy for invalid JSON, wrong ARNs, or account IDs.
S3 event destination selection (example):
A screenshot of the AWS S3 console showing the "Destination" section for configuring event notifications, with radio options for Lambda function, SNS topic, and SQS queue. The page also shows an Intelligent-Tiering option and an informational box about granting S3 permissions to publish to destinations.
Create and save the event notification:
A screenshot of the Amazon S3 console on the "Create event notification" page. It shows general configuration fields with event name "video-uploaded", prefix "images/", suffix ".jpg", and object creation event options.
After saving, you should see confirmation that the event was created for the bucket:
Screenshot of the AWS S3 console showing the Properties page for the bucket "raw-videos-kodekloud" with bucket overview and versioning settings. A green banner at the top notes a successful creation of the "video-uploaded" event notification.

5) Test the end-to-end flow

Steps to test:
  1. Upload a short video to raw-videos-kodekloud (Console, API, or CLI).
  2. S3 emits an object-created event → SNS receives it → SNS fans out to both SQS queues.
  3. Lambda functions subscribed to the queues pick up messages, process, and upload results.
Upload succeeded example:
Screenshot of the AWS S3 console showing an "Upload succeeded" status for one file (video.mp4, 38.2 MB) uploaded to the bucket s3://raw-videos-kodekloud. The summary shows 1 file succeeded and 0 failed.
Expected outputs:
  • video-processing should create HLS outputs (M3U8 + TS segments) in processed-videos-kodekloud:
A screenshot of the Amazon S3 console showing a folder (ee33fc58-...) with the Objects tab open. Three files are listed — output.m3u8, output0.ts, and output1.ts — with their sizes and last-modified timestamps.
  • thumbnail-processing should create thumbnails in thumbnails-kodekloud:
A screenshot of the AWS S3 console showing a folder for thumbnails with three image files created from the video upload, showing the generated thumbnails in the Thumbnails bucket.
Troubleshooting:
  • If you don’t see outputs, check CloudWatch Logs for both Lambda functions to verify message receipt and errors.
  • Verify SNS topic policy and S3 event notifications if S3 cannot publish to SNS.
  • Confirm SQS queue policies allow SNS to deliver messages.

Cleanup

To avoid ongoing charges, delete resources you created for the demo:
  • Delete SQS queues
  • Delete SNS topic
  • Delete Lambda functions
  • Empty & delete S3 buckets
S3 delete bucket confirmation UI (example):
A screenshot of the AWS S3 console showing the "Delete bucket" confirmation page for the bucket named "thumbnails-kodekloud." It includes warnings that deletion cannot be undone and a text field to type the bucket name to confirm.
That wraps up this lesson. You now have a working example of how S3 → SNS → SQS → Lambda can be wired together to process uploaded files asynchronously and at scale.

Watch Video

Practice Lab