Serverless vs Containers
AWS Lambda vs ECS Fargate: Serverless vs Containers Compared
A practical comparison of AWS Lambda and ECS Fargate to help cloud architects choose the right compute model for their workloads.
AWS Lambda and ECS Fargate are both “serverless” in the sense that you do not manage underlying EC2 instances — but they represent fundamentally different execution models. Lambda is event-driven and ephemeral; Fargate runs containerized workloads continuously. Choosing the wrong one for your workload costs money, creates architectural debt, and generates operational complexity that compounds over time.
This comparison is written for architects and CTOs who need a technically grounded decision, not a marketing summary.
Execution Model Comparison
The core difference is not just technical — it is conceptual. Lambda treats compute as a function: a unit of code that executes in response to an event, runs for up to 15 minutes, and terminates. Fargate treats compute as a service: a container that runs continuously (or for a defined task duration) and handles requests as they arrive.
| Characteristic | AWS Lambda | ECS Fargate |
|---|---|---|
| Execution trigger | Event-driven (API Gateway, SQS, S3, etc.) | Continuous service or on-demand task |
| Max execution duration | 15 minutes | Unlimited |
| Minimum billing unit | 1ms (100ms increments for some runtimes) | Per-second (after 1-minute minimum) |
| Package format | ZIP or container image (up to 10 GB) | Container image (any size) |
| Max memory | 10,240 MB (10 GB) | 120 GB (on larger task sizes) |
| Max vCPU | 6 vCPU | 16 vCPU per task |
| Persistent connections | Not reliably supported | Fully supported |
| State between invocations | Ephemeral (no guarantees) | In-container memory persists |
Cold Starts
Lambda cold starts are one of the most misunderstood aspects of serverless architecture. A cold start occurs when Lambda needs to provision a new execution environment — downloading your code, initializing the runtime, and running your initialization code before handling the actual request.
Typical Lambda cold start durations:
| Runtime | Typical Cold Start | With Large Dependencies |
|---|---|---|
| Node.js 20 | 100–300ms | 300ms–1s |
| Python 3.12 | 100–400ms | 400ms–1.5s |
| Java 21 (with SnapStart) | 1–3s (without SnapStart) / ~200ms (with) | Varies |
| Go 1.x | 50–150ms | 150–400ms |
| Container image (any) | 1–4s | 2–10s |
Cold starts only affect a fraction of requests under normal operation — Lambda reuses warm execution environments. However, at low traffic volumes, concurrency spikes, or after deployments, cold starts become frequent. Lambda Provisioned Concurrency eliminates cold starts but adds ~$0.015/GB-hour of reserved capacity cost.
Fargate has a different characteristic: container task startup takes 30–60 seconds for a new task, but once running, requests are handled by the already-warm container with no cold start equivalent. Fargate is not suitable for workloads that need sub-second spin-up from zero.
Timeout Limits
The 15-minute Lambda timeout is a hard architectural constraint, not a configurable limit.
| Scenario | Lambda | Fargate |
|---|---|---|
| API request (< 30s) | Ideal | Suitable |
| Data transformation (< 15 min) | Ideal | Suitable |
| Long ETL job (30 min – 24 hr) | Not possible | Ideal |
| Video transcoding | Not possible (unless chunked) | Ideal |
| ML inference | Possible if model loads fast | Better for large models |
| Batch processing job | Possible with Step Functions | Simpler native support |
When a Lambda function approaches the 15-minute limit, teams typically reach for one of three patterns: chunking work across multiple invocations via SQS, orchestrating multi-step pipelines via Step Functions, or migrating the entire workload to Fargate. All three options add complexity. If your workload routinely approaches 15 minutes, Fargate is the cleaner architectural choice from day one.
Cost Comparison
Lambda and Fargate use entirely different pricing models, making direct comparison require realistic traffic assumptions.
Lambda pricing (us-east-1):
- Requests: $0.20 per 1 million requests
- Compute: $0.0000166667 per GB-second (after 400,000 GB-seconds free tier)
Fargate pricing (us-east-1):
- vCPU: $0.04048 per vCPU-hour
- Memory: $0.004445 per GB-hour
Estimated monthly cost comparison — simple API backend (512 MB memory, 200ms avg duration):
| Traffic | Lambda Cost | Fargate Cost (0.25 vCPU / 0.5 GB) |
|---|---|---|
| 1M requests/month | ~$1.50 | ~$7–14 (always-on task) |
| 5M requests/month | ~$7 | ~$7–14 (same always-on task) |
| 10M requests/month | ~$14 | ~$7–14 (one task handles this) |
| 50M requests/month | ~$70 | ~$14–28 (two tasks) |
| 100M requests/month | ~$140 | ~$28–56 (scaled tasks) |
At low traffic, Lambda wins decisively on cost because you pay nothing when there are no requests. At 5–10 million requests per month the crossover point is reached, and Fargate’s always-on cost becomes competitive. At 50 million+ requests per month, Fargate at appropriate task sizing is typically cheaper.
Stateless vs Stateful Workloads
Lambda’s execution environment is effectively stateless between invocations. While Lambda does reuse warm execution environments (and you can cache data in memory), this behavior is not guaranteed. You cannot maintain a persistent database connection pool, hold WebSocket connections, or rely on in-memory state across invocations in a predictable way.
Fargate containers are stateful within their lifecycle. A running Fargate task can maintain database connection pools (reducing per-request latency significantly), hold WebSocket connections, run background threads, and cache data in memory reliably.
For workloads requiring persistent TCP connections to databases or caches, Fargate with RDS Proxy provides better connection management than Lambda, which tends to exhaust database connections at scale without RDS Proxy in front of it.
Decision Framework
Choose Lambda when:
- Workload is genuinely event-driven with irregular traffic
- Execution time is reliably under 5 minutes
- Traffic is low-to-medium (under 5 million requests per month) or highly spiky
- You want zero infrastructure management and automatic scaling to zero
- Cost optimization at low traffic is the priority
- Functions integrate directly with AWS event sources (S3, SQS, DynamoDB Streams, EventBridge)
Choose Fargate when:
- Tasks run longer than 15 minutes or need to run continuously
- Workload requires more than 10 GB memory or 6 vCPU
- Application maintains state, persistent connections, or in-memory caches
- Traffic is sustained and predictable (lower per-unit cost at scale)
- You have an existing containerized application to migrate
- Background workers, queues, or WebSocket servers are involved
Use both when:
- Event processing triggers long-running Fargate tasks (Lambda as orchestrator)
- API gateway routes lightweight endpoints to Lambda and heavy endpoints to Fargate
- Step Functions workflows combine Lambda for transformation with Fargate for intensive processing
Migration Path
Moving from Lambda to Fargate is typically straightforward if your Lambda functions are already container-packaged. The main work involves adding a web server layer (Express, Gin, FastAPI) to handle the persistent request model, configuring an ECS task definition, and setting up an ALB instead of API Gateway.
Moving from Fargate to Lambda requires decomposing long-running tasks, eliminating persistent state dependencies, and ensuring the execution model fits within the 15-minute constraint.
If you are starting a new workload and are uncertain about traffic patterns, Lambda is lower risk — you can always migrate to Fargate once traffic warrants it.
Choosing between Lambda and Fargate involves trade-offs across cost, operational complexity, and architectural fit. Contact our team to discuss which compute model best fits your specific workload requirements and traffic patterns.
Frequently Asked Questions
When should I use Lambda vs Fargate?
Use Lambda for short-lived, event-driven workloads — API backends, data transformation, scheduled jobs, and anything under 15 minutes. Use Fargate for long-running processes, containerized workloads that need more than 10 GB memory, tasks with stateful in-memory processing, or services that require a persistent TCP connection. If you are running a standard web application with predictable traffic, Fargate often delivers more predictable performance and lower cost at medium-to-high traffic volumes.
Is Fargate more expensive than Lambda?
It depends on traffic patterns. At low traffic (under ~1 million requests per month), Lambda is almost always cheaper because you only pay when code runs. At higher traffic — particularly sustained traffic — Fargate can be cheaper because you are paying for reserved capacity rather than per-invocation overhead. At 10 million requests per month for a typical API, costs are often comparable, but Fargate pricing becomes more predictable. Always model your actual traffic pattern before deciding.
Does Fargate have cold starts?
Fargate does not have cold starts in the traditional sense. ECS Fargate tasks take 30-60 seconds to start a new task from scratch, but this is typically only relevant when scaling out from zero. For running services, Fargate keeps tasks alive continuously. Lambda cold starts affect the first invocation on a new execution environment — typically 200ms-2s depending on runtime and package size. Lambda Provisioned Concurrency eliminates cold starts at additional cost.
Can you use both Lambda and Fargate together?
Yes, and this is a common architecture pattern. A typical hybrid architecture uses Lambda for event-driven triggers, fan-out processing, and lightweight API endpoints, while Fargate runs the core long-running services, batch processors, and stateful workloads. AWS Step Functions can orchestrate both Lambda functions and ECS Fargate tasks in the same workflow. Using both services for what they do best produces more resilient and cost-effective systems than forcing one model on all workloads.
What is the maximum execution time for Lambda?
AWS Lambda has a hard maximum execution time of 15 minutes (900 seconds) per invocation. This cannot be extended. If your workload needs to run longer than 15 minutes, it must be broken into smaller steps using Step Functions, SQS, or EventBridge — or migrated to Fargate, which supports tasks of any duration. This timeout cliff is one of the most common architectural constraints that pushes teams from Lambda toward Fargate.
Need Help Choosing the Right Cloud Platform?
Our AWS-certified architects help you evaluate cloud platforms based on your specific requirements, workloads, and business goals.
