Lambda vs ECS: choosing a compute model
Lambda and ECS solve overlapping problems with very different operational shapes. The comparison below is the starting point; the sections after it deal with the case that comes up most often in practice — an existing application being moved to AWS.
| Aspect | AWS Lambda | Amazon ECS |
|---|---|---|
| Model | Serverless, event-driven functions | Containers, orchestrated as long-running services or tasks |
| Execution limit | 15 minutes per synchronous invocation | No time limit |
| Scaling | Automatic, per function | Automatic, via service auto scaling and capacity providers |
| Cost model | Per request and per GB-second of execution | For the Fargate or EC2 capacity consumed |
| State | Stateless between invocations | Stateful or stateless |
| Cold starts | Yes; mitigated with provisioned concurrency | Minimal once tasks are running |
| Deployment | Function versions and aliases, coordinated per function | Standard container image and task-definition rollout |
| Testing | Cloud-dependent; integration testing spans functions | Conventional container testing |
| Code sharing | Layers, or duplication across functions | Native, inside the image |
| Resource limits | Up to 10,240 MB memory; 512 MB-10,240 MB of /tmp | Bounded by the Fargate task size or the EC2 instance |
| Networking | VPC attachment supported | Native VPC networking per task |
| Maintenance | Low per function, higher across a large estate of them | Moderate; you own the image and its base |
| Best for | Event processing, glue, discrete short tasks | Long-running services, complex applications, existing codebases |
When a monolith should go to ECS rather than Lambda
Section titled “When a monolith should go to ECS rather than Lambda”Migrating an existing monolithic application to Lambda means decomposing it first. That is a rewrite dressed as a migration, and it is rarely what the project was funded to do. ECS lets the application move largely intact and be decomposed later, on its own schedule.
The specific obstacles when the requirement is “keep as much existing code as possible”:
- Converting a monolith into functions requires substantial refactoring before anything runs.
- A synchronous invocation is capped at 15 minutes, which not every component will fit inside.
- Cold starts add latency the current application does not have and has not been designed around.
- A large application split across many functions needs deliberate coordination that the monolith got for free from being one process.
The coordination cost of many functions
Section titled “The coordination cost of many functions”Decomposition is worth paying for when it buys independent scaling and independent deployment. It is not free, and the costs land in four places.
Inter-function communication. Functions that need to call each other require an explicit API contract, a transport, retry semantics and a failure story. Inside a container these are method calls.
Shared code. Common libraries must be packaged as Lambda layers or duplicated across deployment packages, and then kept in step. Inside an image they are just dependencies.
State. Anything that was in-process state becomes a round trip to DynamoDB, ElastiCache or Step Functions, with the consistency and idempotency questions that implies.
Deployment. Interdependent functions must be versioned, rolled out and rolled back together. Canary and blue/green strategies that are a single ECS service-update setting become a coordination exercise across many functions, and API Gateway stage versions have to line up with the function versions behind them.
Testing
Section titled “Testing”Container images run the same way on a developer machine, in CI and in the cluster, so established testing practice carries over. Lambda’s execution environment does not exist locally in the same form: local emulators approximate it, each cross-function interaction needs mocking, end-to-end tests must orchestrate several invocations, and tracing a failure across function boundaries is harder than following a stack trace inside one process. None of this makes Lambda the wrong choice — it makes it a choice with a testing budget attached, which should be spent deliberately rather than discovered late.