15.1
AWS Lambda Basics and Pricing
Functions vs servers, invocation types, triggers, runtimes and container images, and the pricing maths.
22 min Reading + animations
Tip: tap or hover any dotted-underlined term to see what it means.
By the end of this lesson you will be able to
- Say what “serverless” really means (no servers to manage, pay per use, scale to zero) and name the main serverless services on AWS and what each one is for.
- Compare an always-on EC2 instance with a Lambda function: how each runs, scales and is billed, and when each one is the better choice (including the 15-minute limit).
- Describe how a function runs (handler, event, execution environment, cold and warm starts), pick a runtime from the current list, and know when to ship a function as a container image.
- Tell the three invocation types apart (synchronous, asynchronous, event source mapping) and predict who retries a failure and where a failed event ends up (destinations, dead-letter queues, the queue’s own DLQ).
- Give a function the right permissions: the execution role for what it calls, the resource-based policy for who may call it; expose it with a function URL; release it safely with versions and aliases.
- Build the two classic examples (thumbnails on S3 upload, a serverless cron with EventBridge) and calculate a monthly Lambda bill from requests and GB-seconds, then compare it with an EC2 instance.
#What serverless means
For four chapters you have been running things on servers: EC2 instances you size, patch and scale (chapter 4), databases on instances you pick (chapter 7), containers on EC2 or Fargate (chapter 14). Every one of them is billed while it is up, whether it works or waits.
Serverless is a different deal. You hand AWS your code (or your data) and AWS runs it when it is needed. Three things make a service serverless:
- No servers to manage. There are servers, of course, but you never see, size, patch or replace them. Serverless does not mean “no servers”; it means “not your servers”.
- Pay per use. You pay per request, per millisecond of run time, per GB stored, per message. Nothing is billed for idle capacity.
- Scales automatically, down to zero. Ten requests a day or ten thousand a second, the service grows and shrinks on its own; with no traffic, nothing runs and nothing is billed.
The idea started with FaaS (Function as a Service): you upload a function, the platform runs it for each event. AWS Lambda (launched 2014) pioneered it. Today “serverless” covers any fully managed service with those three properties: databases, queues, storage, APIs, workflows.
#The serverless menu on AWS
The exam treats these services as “serverless”. Each one is taught in its own lesson; this table is your map.
| Service | What it does without servers | Where it is taught |
|---|---|---|
| AWS Lambda | Runs your code for each event; pay per request and per millisecond | This lesson, 15.2 (limits, concurrency), 15.3 (networking) |
| Amazon DynamoDB | NoSQL key-value database; on-demand mode bills per request | Lesson 15.4, 15.5 |
| Amazon API Gateway | Managed HTTP, REST and WebSocket APIs in front of Lambda and other backends | Lesson 15.6 |
| Amazon S3 | Object storage, also static websites; pay per GB and request | Chapter 10 |
| Amazon SNS and SQS | Pub/sub topics and message queues | Lessons 13.1–13.4 |
| Amazon Data Firehose (was Kinesis Data Firehose) | Loads streaming data into S3, Redshift, OpenSearch and more | Lesson 13.6 |
| Aurora Serverless v2 | Aurora whose capacity grows and shrinks with load (can pause at 0 capacity) | Lesson 7.3 |
| AWS Step Functions | Workflows (state machines) that chain Lambda and other services | Lesson 15.7 |
| AWS Fargate | Runs containers without EC2 instances | Lesson 14.2 |
| Amazon Cognito | Sign-up and sign-in for app users, and temporary AWS credentials for them | Lesson 15.7 |
| Amazon EventBridge | Event bus and scheduler that routes events to targets such as Lambda | Below, and lesson 19.5 |
A typical serverless web app combines them: static files in S3 (served by CloudFront), users signing in with Cognito, a REST API in API Gateway that calls Lambda functions, and DynamoDB storing the data. Lesson 15.8 builds exactly that.
#Why Lambda: an always-on server vs a function per request
Amazon EC2AWS Lambda
- Virtual servers in the cloud; you pick the instance type.
- Limited by the instance’s CPU and RAM.
- Runs continuously, so it is billed every second it is up, busy or idle.
- Scaling means action: an Auto Scaling group launches or terminates instances, which takes minutes.
- Any run time: a process can run for months.
- You patch the OS, rotate AMIs and place instances in several AZs.
- Functions: no servers to see or manage.
- Limited by time: one invocation runs at most 15 minutes.
- Runs on demand, only when an event arrives; billed per request and per millisecond of run time.
- Scaling is automatic: each concurrent request gets its own execution environment within seconds.
- Up to 10,240 MB of memory per function, CPU in proportion.
- AWS patches the runtime and spreads environments across AZs for you.
An always-on server or a function per request
The product-search API of a Dhaka e-commerce shop, built twice: on EC2 instances in an Auto Scaling group (left) and as a Lambda function (right). Watch what each does at night, in the morning, during a flash sale, and with a job that runs for 40 minutes.
Scenario
No requests: the instance is still billed, Lambda costs nothing.
It is 3 a.m. and nobody is shopping. Instance 1 is running anyway, because a server must be up before the first request arrives. You pay for every hour it runs, busy or idle.
Each execution environment handles one request at a time. Ten simultaneous requests need ten environments; this number is the function’s concurrency. An account starts with 1,000 concurrent executions per Region, shared by all its functions. Scaling, throttling and cold starts get a full lesson: lesson 15.2.
#Benefits of Lambda
- Simple pricing: pay per request and per GB-second of compute, with a monthly free tier of 1 million requests and 400,000 GB-seconds (details below).
- Integrated with the whole AWS platform: dozens of services can invoke a function directly (next sections).
- Many languages: Node.js, Python, Java, .NET, Ruby, and anything else through an OS-only runtime or a container image.
- Monitoring built in: every function sends its logs to CloudWatch Logs and its metrics (invocations, errors, duration, throttles, concurrency) to CloudWatch without any agent; AWS X-Ray adds tracing.
- More resources are one setting away: memory from 128 MB to 10,240 MB. CPU grows with memory: at 1,769 MB a function has the equivalent of one vCPU, and at 10,240 MB up to six vCPUs. A CPU-bound function often finishes so much faster with more memory that it costs the same or less.
The slides add that more RAM also gives more network bandwidth. Today each execution environment gets 625 Mbps; for functions outside a VPC you can request an increase, after which bandwidth scales with memory from 2,048 MB up to about 3,000 Mbps at 10,240 MB.
#How a function runs
A function is your code plus its configuration (runtime, memory, timeout, environment variables, execution role). The entry point is the handler, a function that Lambda calls with two arguments: the event (what happened, as JSON) and the context (request ID, remaining time, memory limit).
import json, os, boto3
s3 = boto3.client("s3") # init code: runs once per environment
TABLE = os.environ["TABLE_NAME"] # configuration from environment variables
def handler(event, context): # runs once per invocation
record = event["Records"][0]["s3"]
key = record["object"]["key"]
print(f"resizing {key}, {context.get_remaining_time_in_millis()} ms left")
return {"status": "ok", "key": key}
When a request arrives and no environment is free, Lambda creates one: it starts a microVM, downloads your code, starts the runtime and runs your init code (everything outside the handler). This is a cold start, typically 100 ms to a second or more depending on the runtime and package size. Then it calls the handler. When the handler returns, the environment stays warm for a while and the next request skips straight to the handler. That is why you create SDK clients and database connections outside the handler: they are reused across warm invocations. Lesson 15.2 covers cold starts, provisioned concurrency and SnapStart.
Anything stored in memory or in /tmp (512 MB by default, up to 10,240 MB) may survive to the next invocation on the same environment, but there is no guarantee: treat each invocation as stateless and keep state in DynamoDB, S3 or a cache.
#Runtimes
The slides list the languages as Node.js, Python, Java, C# / PowerShell, Ruby and a custom runtime. That is still the right shape, but the versions change every year. The managed runtimes supported in October 2026:
| Language | Runtime identifiers (supported) | Notes |
|---|---|---|
| Node.js | nodejs22.x, nodejs24.x | Node.js 26 in preview; Node.js 18 and 20 are deprecated |
| Python | python3.11 to python3.14 | 3.10 deprecation scheduled for 31 October 2026; 3.9 deprecated 15 December 2025 |
| Java | java21, java25; Java 8, 11 and 17 on Amazon Linux 2023 (java17.al2023…) | Java is where SnapStart started (lesson 15.2) |
| .NET (C#, PowerShell) | dotnet8, dotnet10 | PowerShell scripts run on the .NET runtime; “.NET Core” in the slides is the old name |
| Ruby | ruby3.3, ruby3.4, ruby4.0 | |
| OS-only | provided.al2023 | For Go, Rust, C++ or any language: you bring a runtime client that talks to the Lambda Runtime API |
Two corrections to the slides: the managed Go 1.x runtime was retired in January 2024, so Go now runs on the OS-only runtime; and the old Amazon Linux 2 based runtimes (provided.al2, Python 3.10/3.11, Java on Amazon Linux 2) are at or near their end because Amazon Linux 2 itself reached end of life in June 2026. When a runtime is deprecated, AWS stops patching it; after a grace period you can no longer create, then no longer update, functions that use it. Every supported runtime runs on both x86_64 and arm64 (Graviton).
#Container images
Instead of a .zip file (50 MB zipped when uploaded directly, 250 MB unzipped including layers), you can package a function as a container image of up to 10 GB, stored in Amazon ECR (lesson 14.1). This suits big dependencies (machine learning libraries, headless browsers) and teams that already build everything with Docker.
The catch from the slides still holds: the image must implement the Lambda Runtime API, the small HTTP interface through which a function fetches its next event and posts its result. The AWS base images (public.ecr.aws/lambda/python:3.13 and so on) include it; for your own base image you add the open-source runtime interface client. The runtime interface emulator lets you test the image locally. A function is still a function: 15 minutes, one request per environment, invoked by events.
FROM public.ecr.aws/lambda/python:3.13
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py ${LAMBDA_TASK_ROOT}
CMD ["app.handler"]
So when the exam says “run an existing, arbitrary Docker image” (a web server that listens on a port, a long-running worker), the answer is ECS or EKS on Fargate, not Lambda.
#What can invoke a function
The slides’ list of main integrations, with how each one invokes (the next section explains the three types):
| Source | How it invokes | Typical use |
|---|---|---|
| API Gateway | Synchronous | REST or HTTP API backend (lesson 15.6) |
| Application Load Balancer | Synchronous | Lambda as an ALB target (lesson 6.3) |
| Function URL | Synchronous | A simple HTTPS endpoint for one function |
| Cognito | Synchronous | User pool triggers: custom checks at sign-up, after sign-in… |
| CloudFront | Synchronous | Lambda@Edge, taught in lesson 11.3 |
| S3 | Asynchronous | Process uploads (lesson 10.7) |
| SNS | Asynchronous | Fan-out: one message to several functions (lesson 13.4) |
| EventBridge (rules and Scheduler) | Asynchronous | React to AWS events, run on a schedule; “CloudWatch Events” in the slides is its old name |
| CloudWatch Logs | Asynchronous | Subscription filter: process log lines as they arrive |
| SQS | Event source mapping | Work queue with a buffer (lesson 13.1) |
| Kinesis Data Streams | Event source mapping | Ordered stream processing per shard (lesson 13.5) |
| DynamoDB Streams | Event source mapping | React to table changes (lesson 15.5) |
| Data Firehose | Synchronous | Transform records before delivery (lesson 13.6) |
Event source mappings also read Amazon MSK and self-managed Kafka, Amazon MQ and DocumentDB change streams. And any program can call the Invoke API with the SDK or CLI.
#Three ways to invoke a function
Every invocation is one of three types, and the type decides who waits, who retries and where failures go. The exam loves this.
Three ways to invoke a function
The same order-processing function of the Dhaka shop, invoked synchronously by API Gateway, asynchronously by S3, and through an event source mapping that polls an SQS queue. Who waits, who retries, and where do failed events go?
Scenario
The caller waits for the result; errors come straight back to it.
A shopper taps “Place order”. API Gateway calls Invoke with the invocation type RequestResponse and keeps the HTTP connection open: it needs the answer to reply to the phone.
Synchronous (RequestResponse). The caller waits for the result. Payloads up to 6 MB each way (response streaming allows up to 200 MB). Errors go straight back to the caller and Lambda does not retry: the caller (the SDK, the client app) decides. A throttled call gets 429 TooManyRequestsException at once.
Asynchronous (Event). The caller hands the event to Lambda and gets 202 immediately; Lambda keeps the event in an internal queue and invokes the function. The event can be up to 1 MB (raised from 256 KB in 2025). On a function error Lambda retries twice by default (after about 1 minute, then about 2 more), configurable to 0 or 1; throttled events are kept and retried for up to the maximum event age (60 seconds to 6 hours, default 6 hours). What then?
- Destinations: send a record of the invocation to a target on success or on failure. Targets: SQS, SNS, EventBridge, another Lambda function, and (on failure only, since November 2024) an S3 bucket. The record includes the request, the response or error, and the reason. Preferred today.
- Dead-letter queue (DLQ): the older mechanism; an SQS queue or SNS topic set on the function that receives only the failed event, no error details.
- Neither: the event is discarded. Because the internal queue is eventually consistent, an event can also be delivered more than once, so make the code idempotent.
Event source mapping (polling). For SQS, Kinesis, DynamoDB Streams and Kafka, nobody pushes events to Lambda; the Lambda service runs pollers that read the source and invoke the function synchronously with a batch. Failure handling depends on the source:
- SQS: failed messages stay in the queue, reappear after the visibility timeout and are retried; after
maxReceiveCountthe queue’s own redrive DLQ takes them. Return partial batch responses (ReportBatchItemFailures) so one bad message does not make the whole batch retry. Set the visibility timeout to at least six times the function timeout. - Kinesis and DynamoDB Streams: records are processed in order per shard, so a failing batch blocks its shard until it succeeds or the records expire. Limit it with maximum retry attempts, maximum record age and bisect batch on error, and send what is skipped to an on-failure destination (SQS, SNS or S3).
| Synchronous | Asynchronous | Event source mapping | |
|---|---|---|---|
| Who invokes | The caller, and it waits | The caller hands off to Lambda’s queue | Lambda’s own pollers |
| Examples | API Gateway, ALB, function URL, Cognito, SDK | S3, SNS, EventBridge, CloudWatch Logs | SQS, Kinesis, DynamoDB Streams, MSK, MQ |
| Retries | Caller’s job | Lambda: 2 by default, up to 6 hours age | Until success, expiry or the source’s limit |
| Failed events go to | The caller (error response) | On-failure destination or function DLQ | SQS: queue’s DLQ. Streams: on-failure destination |
| Payload | 6 MB request and response | 1 MB | Batches (up to 6 MB total) |
#Permissions: two policies, two directions
Lambda security has two sides, and mixing them up is a classic exam trap.
- Execution role (outbound: what the function may call). An IAM role trusted by
lambda.amazonaws.com. Lambda assumes it for every invocation and gives the temporary credentials to your code; the SDK finds them on its own. Writing logs needs the managed policy AWSLambdaBasicExecutionRole; add statements for S3, DynamoDB and the rest. Event source mappings also use this role to read the queue or stream. - Resource-based policy (inbound: who may invoke the function). A policy on the function itself. AWS services that push events (S3, SNS, EventBridge, API Gateway, CloudWatch Logs) and other accounts need a statement here allowing
lambda:InvokeFunction. The console adds it when you add a trigger; the CLI command isaws lambda add-permission. Limit service principals with a source ARN and source account.
Who may call the function, and what may it call?
The thumbnail function of the Dhaka shop. Inbound permission (who may invoke it) lives in the function’s resource-based policy; outbound permission (what the code may touch) lives in its execution role.
Scenario
What the code may call: assumed by Lambda, used by the SDK.
Execution role: thumbnail-role
| Allow | On |
|---|---|
| logs:CreateLogStream, logs:PutLogEvents | /aws/lambda/thumbnail-example |
| s3:GetObject | uploads-example/* |
| s3:PutObject | thumbs-example/* |
| dynamodb:PutItem | table/photos |
Every function has exactly one execution role, an IAM role that trusts lambda.amazonaws.com. Lambda assumes it and hands its temporary credentials to your code through environment variables; the AWS SDK picks them up. No access keys in code, ever.
The execution role’s trust policy is always the same:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}
Across accounts, both sides must allow, as in lesson 2.2: the caller’s identity policy and the function’s resource-based policy. Inside one account, either one is enough for an IAM user or role.
#Function URLs
A function URL is a dedicated HTTPS endpoint for one function, https://<url-id>.lambda-url.<region>.on.aws, invoked synchronously. It is free (you pay only for the invocations), supports CORS settings and response streaming, and suits webhooks (a payment gateway calling you back), a single-function microservice or a quick internal tool.
- AuthType AWS_IAM: callers must sign requests with SigV4 and be allowed
lambda:InvokeFunctionUrl, pluslambda:InvokeFunctionfor URLs created since October 2025. - AuthType NONE: public; the resource-based policy must still allow public invocation (the console adds it). Your code checks any token itself.
A function URL has no API keys, usage plans, request validation, caching or WAF of its own. For those, use API Gateway (lesson 15.6), or put CloudFront in front of the URL (CloudFront can sign its requests to the URL with origin access control, so only CloudFront can call it).
#Versions and aliases
While you develop, you edit $LATEST. Publishing creates a numbered version (1, 2, 3…): an immutable snapshot of code and configuration with its own ARN (…:function:checkout:7). An alias is a named pointer to a version (…:function:checkout:live) that you can move. Triggers, API Gateway and event source mappings should point at an alias, so a release or a rollback is just moving the alias.
An alias can also split traffic between two versions by weight (90% to version 7, 10% to version 8): a canary. AWS CodeDeploy automates this (canary, linear or all-at-once shifting, rollback on CloudWatch alarms), and AWS SAM sets it up with a few lines. Provisioned concurrency (lesson 15.2) is also configured on an alias or a version, never on $LATEST.
Versions, aliases and a safe rollout
API Gateway calls the checkout function through the alias “live”, never through a number. Publishing creates frozen versions; moving the alias changes what runs.
Scenario
$LATEST is editable; a published version is frozen.
You always edit $LATEST. Publishing takes a snapshot of its code and configuration as version 7, with its own ARN ending in :7. A version can never be changed again, so “version 7” always means the same code.
#Two classic examples
The slides end the Lambda introduction with two small architectures. Both appear in exam questions in many disguises.
1. Thumbnails on upload. An S3 event notification (s3:ObjectCreated:*, filtered to .jpg) invokes the function asynchronously. The function downloads the image, writes a thumbnail to another bucket and the metadata (name, size, creation date, thumbnail key) to a DynamoDB table. No server waits for uploads; the shop pays a few hundred milliseconds per photo.
2. A serverless cron job. An EventBridge schedule (the slides still call it CloudWatch Events) invokes the function every hour, or with a cron expression, to run a task. Today AWS recommends EventBridge Scheduler for new schedules: one-time or recurring, with time zones and flexible windows, and millions of schedules per account.
Two classic Lambda jobs: thumbnails and a cron
A product photo uploaded to S3 becomes a thumbnail plus a metadata item in DynamoDB; an EventBridge schedule runs a report every night. Both run with no server, and both have classic ways to go wrong.
Scenario
S3 event → Lambda → thumbnail bucket + DynamoDB item.
S3 event (shortened)
eventName
ObjectCreated:Put
bucket
uploads-example
key
products/saree-042.jpg
size
4,194,304
A seller uploads saree-042.jpg (4 MB) to uploads-example. The bucket’s event notification for s3:ObjectCreated:* with the suffix .jpg invokes the function asynchronously (lesson 10.7).
#How Lambda is priced
You pay for two things, plus extras only if you use them:
- Requests: 0.20 USD per million invocations (0.0000002 USD each).
- Duration × memory, measured in GB-seconds: the configured memory in GB times the run time in seconds, rounded up to the millisecond. In US East (N. Virginia): 0.0000166667 USD per GB-second on x86 and 0.0000133334 USD on Arm (Graviton), 20% less. Cheaper tiers start above 6 billion GB-seconds a month on x86 and 7.5 billion on Arm. Since August 2025 the init phase of a cold start is billed as duration too.
The free tier, every month, per account and shared by all functions: 1 million requests and 400,000 GB-seconds. 400,000 GB-seconds is 400,000 seconds at 1 GB, 3,200,000 seconds at 128 MB (0.125 GB), or 800,000 seconds at 512 MB.
Extras: ephemeral storage above the free 512 MB, provisioned concurrency (lesson 15.2), data transfer out, and CloudWatch Logs ingestion (often bigger than the Lambda bill for chatty functions). Compute Savings Plans (lesson 4.4) also cover Lambda duration.
#A worked example
The thumbnail function: 3 million invocations a month, 512 MB, 800 ms on average, x86, free tier available.
- Compute: 3,000,000 × 0.5 GB × 0.8 s = 1,200,000 GB-seconds. Minus the free 400,000 = 800,000 billed. 800,000 × 0.0000166667 = 13.33 USD.
- Requests: 3,000,000 − 1,000,000 free = 2,000,000 × 0.20 USD per million = 0.40 USD.
- Total: 13.73 USD a month. On Arm: 800,000 × 0.0000133334 = 10.67, plus 0.40 = 11.07 USD.
A t3.small running all month costs 0.0208 × 730 = 15.18 USD, before its EBS volume, and it would be idle most of the night and overwhelmed during a sale. Now try 50 million invocations: Lambda passes 200 USD a month, while a few instances would do the same work for less. Lambda wins for spiky and low-to-medium traffic; steady, heavy load favours servers.
What does a Lambda function cost per month?
The Dhaka shop’s thumbnail function, or any other. Choose the memory, how long one invocation runs on average, how many invocations a month, the architecture, whether the free tier still applies, and an EC2 instance that would do the same work all month. Then calculate.
Memory
Average duration
Invocations per month
Architecture
Free tier
Compare with EC2 (always on)
Press “Calculate” to see the result.
#What goes wrong
| Symptom | Likely cause | Fix |
|---|---|---|
Task timed out after 900.00 seconds | The job needs more than 15 minutes | Split the work (SQS, Step Functions Map), or use Fargate / AWS Batch |
Task timed out after 3.00 seconds | The default timeout is 3 seconds | Raise the timeout to what the work needs, and check slow downstream calls |
AccessDeniedException inside the function | The execution role lacks the action | Add the permission to the execution role, not the code |
| S3 refuses to save the notification, or the trigger never fires | No resource-based policy statement for s3.amazonaws.com | aws lambda add-permission with source ARN and account |
| Synchronous callers get 429 | No concurrency left in the Region or for the function | Reserved concurrency, quota increase, or a queue in between (lesson 15.2) |
| Failed S3 events disappear | Asynchronous invocation with no destination or DLQ | Add an on-failure destination and alarm on it |
| The same SQS message is processed again and again | The function fails or runs longer than the visibility timeout | Fix the error, raise the visibility timeout, add a redrive DLQ, use partial batch responses |
| A Kinesis shard stops moving | A poison record fails the batch forever | Bisect batch on error, maximum retries, on-failure destination |
| Invocations and cost explode after a deploy | The function writes to the bucket or queue that triggers it | Separate output bucket or prefix; recursive loop detection as a safety net |
OutOfMemory / Runtime exited | Memory too small for the data | Raise memory (also gives more CPU) |
| The first request after a quiet period is slow | Cold start | Lighter package and init code, provisioned concurrency or SnapStart (lesson 15.2) |
#Lambda in system design
Use Lambda as the glue and the event handler of an architecture: an API backend with spiky traffic, processing files as they land in S3, consuming queues and streams, scheduled jobs, reacting to AWS events (an EC2 state change, a GuardDuty finding), and small automation tasks. Its strengths are zero idle cost, scaling in seconds and no operations.
Watch the boundaries: 15 minutes per invocation, 1,000 concurrent executions per Region by default, 6 MB synchronous payloads, a cold start on new environments, and no access to private VPC resources unless you attach the function to a VPC (lesson 15.3). The chapter-14 chooser pointed short, event-driven tasks to Lambda and long-running containers to Fargate; lesson 15.8 puts Lambda, Fargate and EC2 side by side for whole architectures.
#Try it yourself
These commands create the thumbnail function in ap-southeast-1 with the CLI. Use a sandbox account; everything stays within the free tier.
REGION=ap-southeast-1
ACCOUNT=111122223333
# 1. Execution role trusted by Lambda, with the logs policy
aws iam create-role --role-name thumbnail-role \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow",
"Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name thumbnail-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
# 2. Create the function from app.py zipped as function.zip (arm64 is 20% cheaper)
zip function.zip app.py
aws lambda create-function --function-name thumbnail-example \
--runtime python3.13 --architectures arm64 --handler app.handler \
--role arn:aws:iam::$ACCOUNT:role/thumbnail-role \
--memory-size 512 --timeout 30 --zip-file fileb://function.zip \
--environment "Variables={TABLE_NAME=photos}" --region $REGION
# { "FunctionName": "thumbnail-example", "State": "Pending", "Runtime": "python3.13", ... }
# 3. Invoke synchronously and read the result
aws lambda invoke --function-name thumbnail-example --cli-binary-format raw-in-base64-out \
--payload '{"Records":[{"s3":{"object":{"key":"products/saree-042.jpg"}}}]}' out.json
# { "StatusCode": 200, "ExecutedVersion": "$LATEST" }
cat out.json
# {"status": "ok", "key": "products/saree-042.jpg"}
# 4. Invoke asynchronously: Lambda only says it accepted the event
aws lambda invoke --function-name thumbnail-example --invocation-type Event \
--cli-binary-format raw-in-base64-out --payload '{"Records":[]}' out.json
# { "StatusCode": 202 }
# 5. Asynchronous settings: 1 retry, 1 hour max age, failures to an SQS queue
aws lambda put-function-event-invoke-config --function-name thumbnail-example \
--maximum-retry-attempts 1 --maximum-event-age-in-seconds 3600 \
--destination-config '{"OnFailure":{"Destination":"arn:aws:sqs:ap-southeast-1:111122223333:thumb-failures-example"}}'
# 6. Allow the uploads bucket to invoke the function (resource-based policy)
aws lambda add-permission --function-name thumbnail-example --statement-id s3-uploads \
--action lambda:InvokeFunction --principal s3.amazonaws.com \
--source-arn arn:aws:s3:::uploads-example --source-account $ACCOUNT
aws lambda get-policy --function-name thumbnail-example --query Policy --output text
# 7. Publish version 1 and point the alias "live" at it
aws lambda publish-version --function-name thumbnail-example
# { "Version": "1", "FunctionArn": "arn:aws:lambda:ap-southeast-1:111122223333:function:thumbnail-example:1", ... }
aws lambda create-alias --function-name thumbnail-example --name live --function-version 1
# Later: send 10% of traffic to version 2
aws lambda update-alias --function-name thumbnail-example --name live --function-version 1 \
--routing-config '{"AdditionalVersionWeights":{"2":0.1}}'
# 8. A function URL with IAM authentication
aws lambda create-function-url-config --function-name thumbnail-example --auth-type AWS_IAM
# { "FunctionUrl": "https://abcdefghijklmnopqrstuvwxyz123456.lambda-url.ap-southeast-1.on.aws/", "AuthType": "AWS_IAM" }
# 9. A serverless cron: every day at 6 a.m. Dhaka time with EventBridge Scheduler
aws scheduler create-schedule --name nightly-report-example \
--schedule-expression "cron(0 6 * * ? *)" --schedule-expression-timezone Asia/Dhaka \
--flexible-time-window Mode=OFF \
--target '{"Arn":"arn:aws:lambda:ap-southeast-1:111122223333:function:report-example",
"RoleArn":"arn:aws:iam::111122223333:role/scheduler-invoke-example"}'
# 10. Watch the logs, then clean up
aws logs tail /aws/lambda/thumbnail-example --follow
aws lambda delete-function --function-name thumbnail-example
Run step 3 twice and compare the Init Duration line in the log: it appears only on the cold start. Then raise the memory to 1,769 MB with aws lambda update-function-configuration and watch Duration fall for CPU-heavy code. EventBridge Scheduler uses its own IAM role (RoleArn) to invoke the function, so it needs no resource-based policy statement.
#Summary
Key takeaways
- Serverless = no servers to manage, pay per use, automatic scaling down to zero. It started as FaaS with AWS Lambda and now covers DynamoDB, API Gateway, S3, SNS/SQS, Data Firehose, Aurora Serverless, Step Functions, Fargate, Cognito and EventBridge.
- EC2 runs continuously, is limited by CPU and RAM, and scales by adding instances in minutes. Lambda runs per event, is limited by time (15 minutes), scales per request in seconds (1,000 concurrent executions per Region by default), and bills per request and per millisecond.
- Memory 128 MB to 10,240 MB; CPU grows with memory (1,769 MB = 1 vCPU). Logs and metrics go to CloudWatch automatically.
- Runtimes (October 2026): Node.js 22/24, Python 3.11–3.14, Java 8–25, .NET 8/10 (C#, PowerShell), Ruby 3.3–4.0, and the OS-only
provided.al2023for Go, Rust and others. Go 1.x and Amazon Linux 2 runtimes are retired or ending. Container images up to 10 GB must implement the Lambda Runtime API; arbitrary images belong on ECS/Fargate. - Synchronous (API Gateway, ALB, function URL, Cognito): caller waits, caller retries, 6 MB. Asynchronous (S3, SNS, EventBridge): 202, Lambda retries twice, 1 MB, then an on-failure destination or DLQ. Event source mapping (SQS, Kinesis, DynamoDB Streams): Lambda polls and sends batches; SQS failures go to the queue’s DLQ.
- Execution role = what the function may call. Resource-based policy = who may invoke it (S3, SNS, EventBridge, API Gateway, other accounts). Function URL = built-in HTTPS endpoint, AWS_IAM or NONE.
- Versions are immutable snapshots; aliases point to them and can split traffic for canaries and instant rollbacks.
- Classic patterns: S3 upload → Lambda → thumbnail in another bucket + metadata in DynamoDB; EventBridge schedule → Lambda as a serverless cron.
- Price = 0.20 USD per million requests + GB-seconds (x86 0.0000166667, Arm 20% less), rounded to 1 ms; free tier 1 million requests + 400,000 GB-seconds a month. Cheap for spiky work; steady heavy load is cheaper on servers.
Answer on your own first, then read the explanation, even when you got it right.
Self-checkQuestion
Which statement best describes serverless computing?
Self-checkQuestion
What is the maximum time a single Lambda invocation can run?
Self-checkQuestion
A function is configured with 1,769 MB of memory. What is true about its CPU?
Self-checkQuestion
Which two services are commonly called serverless on AWS?
Choose 2
Self-checkQuestion
Which runtime should a team use for a new Lambda function written in Go?
Self-checkQuestion
A team wants to run an existing third-party Docker image that starts a web server on port 8080 and runs for days. Which service fits best?
Self-checkQuestion
What must a container image implement to run as a Lambda function?
Self-checkQuestion
An API Gateway REST API invokes a Lambda function, and the function throws an exception. What happens?
Self-checkQuestion
S3 invokes a function for each new object. A malformed file makes the function fail. With default settings, how many times in total is the function invoked for that event?
Self-checkQuestion
A team must capture every failed asynchronous invocation of a function together with the error message and stack trace, to replay them later. What is the best solution?
Self-checkQuestion
A function processes messages from an SQS queue through an event source mapping. Some messages always fail. Where should the dead-letter queue be configured?
Self-checkQuestion
Which two statements about asynchronous invocation are correct?
Choose 2
Self-checkQuestion
An S3 bucket’s event notification cannot be saved: S3 reports that it cannot validate the destination Lambda function. What is missing?
Self-checkQuestion
A function must read objects from one S3 bucket and write items to a DynamoDB table. Where do these permissions go?
Self-checkQuestion
A partner’s role in account 444455556666 must invoke a function in account 111122223333. The partner’s identity policy already allows lambda:InvokeFunction on the function ARN, but calls are denied. What is the fix?
Self-checkQuestion
A function URL uses auth type AWS_IAM. A browser calls it without signing the request. What does the browser get?
Self-checkQuestion
A startup needs an HTTPS endpoint for a payment gateway’s webhook. It calls one function, needs no API keys, throttling plans or caching, and should cost as little as possible. What should they use?
Self-checkQuestion
Which two features does a Lambda function URL NOT provide on its own?
Choose 2
Self-checkQuestion
The team releases version 8 of the checkout function and errors jump. API Gateway calls the alias live, which pointed to version 7 before the release. What is the fastest safe rollback?
Self-checkQuestion
Which two statements about Lambda versions and aliases are correct?
Choose 2
Self-checkQuestion
A news site must e-mail editors a report every day at 6 a.m. Dhaka time. The job takes 40 seconds. What is the most cost-effective and operationally simple solution?
Self-checkQuestion
A thumbnail function is triggered by ObjectCreated events on the bucket photos-example and writes each thumbnail back to photos-example. Invocations and cost suddenly explode. What is the cause and the best fix?
Self-checkQuestion
A nightly report function triggered by EventBridge now needs 25 minutes and fails every night. What are two valid fixes?
Choose 2
Self-checkQuestion
Using the free tier of 400,000 GB-seconds a month, how many seconds of run time does a 128 MB function get for free?
Self-checkQuestion
A function runs 3 million times a month with 512 MB for 800 ms on average, on x86. The free tier applies (1 million requests, 400,000 GB-seconds). Prices: 0.20 USD per million requests, 0.0000166667 USD per GB-second. What is the monthly bill?
Self-checkQuestion
A function runs 10 million times a month with 128 MB for 200 ms. The account’s free tier is already used up by other functions. Prices as above (x86). What is the monthly bill?
Self-checkQuestion
A team moves a CPU-heavy function from x86_64 to arm64 with no change in duration. By how much does the duration part of the bill fall?
Self-checkQuestion
The slides say Lambda costs 1.00 USD for 600,000 GB-seconds after the free tier. At 0.0000166667 USD per GB-second, what do 600,000 GB-seconds actually cost?
Self-checkQuestion
An API receives a steady 400 requests per second all day, every day, each taking 300 ms at 1,024 MB. Which statement about cost is most accurate?
Self-checkQuestion
Which statement about an event source mapping on a Kinesis data stream is correct?