- Workload pattern
-
Understanding the operational pattern of your application is the most important
factor in selecting serverless services. Different workload patterns demand different
service combinations. Serverless data processing largely falls within the following
patterns:
Asynchronous processing: File
processing, image manipulation, batch transformations, and webhooks. These workloads
process events that don't require an immediate response and benefit from queues for
buffering and fan-out for parallel processing.
Synchronous request/response: Web APIs,
mobile backends, and microservices. These workloads need low-latency compute that
responds to individual HTTP requests and scales with concurrent traffic.
Streaming: IoT telemetry, click-stream
analysis, real-time analytics, and transaction processing. These workloads ingest
high-velocity, continuous data that must be processed in near-real
time.
Orchestration: Multi-step approval
flows, ETL pipelines, and saga patterns. These workloads coordinate tasks with
branching logic, error handling, and state management.
Each pattern uses a different combination of serverless services. For detailed
examples and recommended service combinations for each pattern, see the Choose
section.
- Execution duration and concurrency
-
Serverless compute services differ significantly in how long they allow a single
execution to run and how they handle concurrency. Unlike traditional servers, Lambda
event functions do not run constantly. When a function is triggered by an event, this is
called an invocation. Lambda event functions are limited to 15 minutes in duration, but on
average, across all AWS customers, most invocations last for less than a second.
Short-lived, event-driven invocations are best
served by Lambda, which supports execution durations up to 15 minutes and scales
automatically per-request to thousands of concurrent invocations. The Lambda service
runs instances of your function only when needed and scales automatically from zero
requests per day to thousands per second. You pay only for the compute time that is
actually used, so there is no charge when your code is not running. The
per-millisecond billing of Lambda can reduce cost for short-duration workloads.
There are many types of invocation events that can trigger short-lived functions.
Some examples include an HTTP request from API Gateway, a schedule managed by an
EventBridge rule, a message from an IoT device, or a notification that a file was
uploaded to an Amazon S3 bucket.
Stateful, interactive sessions, such as AI coding
sandboxes, interactive notebooks, and multi-tenant CI environments, need isolated
environments that retain state across user interactions. Lambda MicroVMs are a different
compute form factor from Event Functions: they use a Dockerfile-based programming
model, allocate one environment per session (not per request), and bill on a baseline
plus burst model rather than per-millisecond. MicroVMs provide VM-level isolation with
full OS capabilities, snapshot-based rapid startup, up to 8-hour lifetimes, and
suspend/resume to reduce idle costs.
Long-running or steady-state processes, such as
batch jobs, persistent WebSocket connections, or services that require more than 15
minutes of continuous processing, are better served by Fargate, which
can run indefinitely. For details on how Fargate and Lambda scale differently,
see the Scaling model and latency tab. Fargate provides consistent resource allocation for workloads
that exceed the timeout or compute limits of Lambda. Additionally, Lambda durable functions enable
multi-step, long-running executions that persist state across multiple invocations.
Each individual invocation still respects the 15-minute limit. Durable functions
automatically checkpoint progress and resume where they left off, so total workflow
durations can far exceed 15 minutes without requiring Fargate or external
orchestration.
Consider both the average and maximum execution time of your workloads. A Lambda
function that occasionally exceeds 15 minutes fails unpredictably and requires
architectural redesign. Your application architecture and needs determine how to
invoke a function. For example, batch-processing patterns have
different requirements than on-demand data processing. Fargate suits a
microservice that primarily handles batch data processing. Lambda is simpler
to deploy and maintain for on-demand processing.
- Cost model and predictability
-
One of the key advantages of serverless development is that you pay only for the
resources you consume. Serverless technologies are pay-as-you-go, which means you can
scale up and down as your application needs change without paying for idle capacity.
However, different AWS serverless services use different pricing models that favor
different usage patterns.
Pay-per-use pricing (Lambda, Step Functions Express,
EventBridge) charges based on actual invocations and duration, with no cost when idle.
For Lambda, you are charged based on the number of requests for your functions and the
duration it takes for your code to run. There is no charge when your code is not
running. This model suits unpredictable or spiky workloads where traffic can
drop to zero, and for early-stage applications where demand is uncertain.
Capacity-based pricing (Fargate, Amazon Aurora Serverless,
DynamoDB provisioned mode) charges for reserved compute or throughput capacity. While
this might incur costs during low-traffic periods, it becomes more cost-effective at
sustained, predictable scale where per-request pricing would exceed the equivalent
reserved capacity. For example, DynamoDB provisioned mode lets you adjust your tables'
throughput capacity as needed, which can be more economical for workloads with
consistent traffic patterns.
Hybrid pricing (DynamoDB on-demand, API Gateway)
offers per-request pricing that scales linearly without upfront commitment. This
provides cost predictability without the need to forecast capacity, but can become
expensive at very high throughput compared to provisioned alternatives.
Baseline plus burst pricing (Lambda MicroVMs)
charges for configured baseline resources while the MicroVM is running, with the
ability to burst to 4x baseline during peak activity. Suspended MicroVMs reduce cost
while preserving state. This model suits interactive workloads with variable activity
and idle periods.
Model your expected traffic patterns across daily, weekly, and seasonal cycles.
Workloads with high peak-to-average ratios favor per-use pricing. Steady-state
workloads might benefit from capacity-based pricing. You can also use a combination:
for example, Lambda with pay-per-use for variable compute alongside DynamoDB provisioned
mode for predictable data access patterns.
- Operational complexity
-
Traditional web application frameworks bundle routing, data access, connection
pools, and integrations into a single codebase that you deploy and maintain as one unit.
Setting up, configuring, and maintaining the frameworks, runtime environments, and
infrastructure slows down your delivery of features and bug fixes. As applications grow
and rely on more external systems, this complexity increases ramp-up time for new
developers, makes tracking down the source of bugs more challenging, and delays the
delivery of new features.
Serverless services exist on a spectrum of operational responsibility that reduces
or eliminates this overhead. Instead of managing everything in one package, you compose
loosely connected services where each one does one thing well with as few dependencies
as possible.
Minimal management: Lambda, API Gateway, DynamoDB,
Amazon SQS, Amazon SNS, EventBridge, and Step Functions require no server provisioning, patching, or
capacity planning. You don't need to set up connection pools, configure runtime
environments, or manage scaling infrastructure. You can focus entirely on
writing or generating code that solves business problems.
Container management: Fargate requires
building and maintaining container images, configuring task definitions, and managing
deployment pipelines. You don't manage the underlying infrastructure, but you own the
container lifecycle. This model suits teams that need custom runtimes or have existing
containerized workloads they want to run without managing clusters.
Infrastructure as code complexity: AWS Serverless Application Model
minimizes IaC complexity for serverless-only architectures with shorthand syntax and
local testing. AWS Cloud Development Kit (AWS CDK) and Terraform provide more power for complex applications at
the cost of steeper learning curves and more code to maintain.
Consider your team's existing skills, the number of services to manage, and your
organization's operational standards. If your teams are spending more time maintaining
infrastructure than building features, moving toward the minimal management end of the
spectrum can free up resources for higher-value work.
- Scaling model and latency
-
How a service scales directly impacts your application's responsiveness under
load. In serverless architectures, scaling happens automatically, but different
services use different mechanisms that affect latency and throughput.
Per-request scaling (Lambda) creates a new execution
environment for each concurrent request. Lambda invokes your function in an execution
environment, which provides a secure and isolated runtime environment that manages
the processes and resources required to run the function. This provides near-instant
response to traffic spikes, scaling from zero to thousands of concurrent executions
in seconds.
However, per-request scaling introduces cold starts, which are initialization
delays that occur when Lambda creates a new execution environment. The largest
contributor to cold start time is the time that Lambda spends initializing the function,
which includes loading the function's code, starting the runtime, and initializing
the function code. For Java, Python, and .NET workloads, Lambda SnapStart can improve startup performance
by up to 10x at no extra cost by taking a snapshot of the initialized execution
environment and caching it for low-latency access. For other runtimes, you can
mitigate cold starts with Provisioned Concurrency at additional cost.
Task-level scaling (Fargate)
adds or removes container instances based on metrics such as CPU utilization, memory
usage, or request count. Scaling adds new tasks in seconds to minutes
and avoids cold starts for requests handled by existing tasks. Once a task is running,
it stays warm for its entire lifetime, providing consistent latency for all requests
it handles.
Throughput-based scaling (DynamoDB, Kinesis) adjusts
read/write capacity or shard count based on demand. DynamoDB on-demand mode scales
instantly to accommodate your workload's traffic patterns. Provisioned mode requires
auto-scaling configuration but provides predictable throughput at lower per-request
costs. With serverless architecture and DynamoDB, connection pools are not necessary to
rapidly connect and scale the database. Instead, you adjust your tables' throughput
capacity as needed.
For strict latency requirements (sub-100ms P99), evaluate cold-start behavior
carefully. Lambda with Provisioned Concurrency or SnapStart, or Fargate with pre-warmed
tasks, provides predictable latency for API workloads. For data processing workloads
where latency is less critical, standard Lambda scaling is typically sufficient.
- Integration and composability
-
Serverless architectures are composed from multiple services that communicate
through events. An event represents a change in state, or an update. For example, an
item placed in a shopping cart, a file uploaded to a storage system, or an order
becoming ready to ship. The depth of native integration between services affects how
quickly you can build and how much custom code you need to write.
Deep native integration: Lambda integrates with over
200 AWS services as event sources. Some services can trigger Lambda functions
directly. For example, when an image is added to an Amazon S3 bucket, Lambda can be
triggered to resize it. Some services cannot invoke Lambda directly, but you can use
an event source mapping, which is a polling mechanism that reads from an event source
and invokes a Lambda function. You can use event source mappings to process items from
a stream or queue in: DynamoDB Streams, Amazon Kinesis, Amazon MQ, Amazon MSK,
self-managed Apache Kafka, and Amazon SQS.
Event routing flexibility: EventBridge provides
content-based routing with filtering rules, allowing a single event bus to route
events to different targets based on event content. Amazon SNS provides topic-based fan-out
to deliver messages to multiple subscribers simultaneously. Amazon SQS provides
point-to-point buffering where consumers actively poll messages from the queue. Common
combinations include routing EventBridge or Amazon SNS events to an Amazon SQS queue as a buffer
for downstream consumers, pulling events from a stream or queue with EventBridge Pipes,
and routing events to Kinesis for analytics.
API integration patterns: API Gateway offers two
integration approaches. Proxy integrations directly pass all request information to a
Lambda function for processing, which is simpler to configure. Non-proxy (custom)
integrations can transform data before it reaches your function and before output
returns to clients, which is useful for legacy code migration or keeping function code
focused on business logic. REST API provides the broadest feature set including
caching, request validation, and WAF. HTTP API provides the lowest latency and cost.
AWS AppSync provides real-time subscriptions and GraphQL. Lambda function URLs provide the
simplest single-function HTTPS endpoint without requiring API Gateway. For
bidirectional communication where the server needs to push data to clients, API
Gateway WebSocket APIs provide persistent connections suited for chat, real-time
dashboards, and multiplayer games.
Due to the loose coupling between components of an event-driven system, your
compute functions are not aware of other activities in the architecture. You can scale
components independently, one service can fail without impacting other services, and
events can be flexibly routed, buffered, and provide a log for audit.
- Portability and standards
-
Your choice of serverless services affects how portable your architecture is
across environments. Serverless applications usually comprise several AWS services,
integrated with custom code run in Lambda functions. While Lambda can be integrated with
most AWS services, you should consider the trade-off between deep platform
integration and the ability to run workloads in other environments.
AWS native services (Lambda, Step Functions, EventBridge,
DynamoDB) provide the deepest integration and lowest operational overhead. You can use
any of these services through the AWS SDK without needing to install applications
or configure servers. Becoming proficient with using these services through code in your
Lambda functions is an important step to producing well-designed serverless applications.
However, these services create coupling to AWS-specific APIs and event formats,
meaning migrating to another cloud requires significant refactoring.
Standards-based services (Fargate with Docker
containers, Amazon MQ with AMQP, Amazon MSK with Apache Kafka) run on open protocols
or open-source technologies. If you need a custom runtime that is not provided by
AWS, you can create and deploy a custom container image on Fargate. Amazon MSK
provides Apache Kafka compatibility for teams with existing Kafka expertise. These
options make workload portability more feasible at the cost of higher operational
complexity and less tight integration with other AWS services.
Deployment frameworks: AWS Serverless Application Model and AWS Cloud Development Kit (AWS CDK)
generate CloudFormation templates and are AWS-only. AWS Serverless Application Model extends CloudFormation with shorthand
syntax focused on speeding up serverless development, offering optimized definitions
for API Gateway, Lambda, and Step Functions resources, plus local Lambda testing through the SAM CLI.
Terraform provides multi-cloud infrastructure definition using a single workflow across
providers but with less serverless-specific tooling and limited local Lambda testing
capabilities.
Containers and standards-based messaging can improve portability for multi-cloud requirements.
Native serverless services offer close integration with other AWS services,
which can simplify development when your workload runs primarily on AWS.