Compute and containers
Choosing between EC2, Lambda, ECS, EKS, Fargate and Elastic Beanstalk, plus ECS network modes, Lambda concurrency and VPC access, and edge compute.
Exam tasks: 2.5 (select compute for performance and scale), 4.3 (choose new architectures: serverless, containers)
The decision: how much of the platform do you want to manage (servers, clusters, runtimes), and what does the workload need that only a lower level gives you (long runtimes, GPUs, special kernels, Kubernetes APIs)?
Choosing a platform
Side by side
| EC2 | Lambda | ECS or EKS on Fargate | ECS or EKS on EC2 | Elastic Beanstalk | |
|---|---|---|---|---|---|
| You manage | OS, patching, scaling | Code only | Task or pod definitions | Cluster nodes too | App code, some config |
| Max run time | Unlimited | 15 minutes | Unlimited | Unlimited | Unlimited |
| Scale to zero | No (ASG can hit 0) | Yes | Yes (0 tasks) | Tasks yes, nodes via scaling | No |
| GPUs | Yes | No | No | Yes | Yes, via instance type |
| Pricing | Per instance-second | Per request + GB-second | Per vCPU and GB-second | Per instance | Underlying resources |
| Best when | Legacy apps, licensing, full control | Spiky, event-driven work | Containers without servers | Dense packing, special hardware | Lift a web app with little change |
Exam signal
"Least operational overhead" plus containers means Fargate. "Must use existing Kubernetes manifests and Helm charts" means EKS. "Runs for hours" or "needs a GPU" rules out Lambda (and Fargate for GPUs).
Legacy: use Amazon ECS Express Mode instead
AWS App Runner stopped accepting new customers on April 30, 2026. It still runs for existing users, but new designs that want "container image in, HTTPS URL out" use ECS Express Mode, which provisions the ALB, scaling and domain for an ECS service from an image and two IAM roles.
ECS in depth
Network modes
| Mode | How it works | Use it when | Limits |
|---|---|---|---|
| awsvpc | Each task gets its own ENI and private IP | You want per-task security groups and VPC flow logs per task. Required on Fargate | ENIs per instance limit density; turn on ENI trunking |
| bridge | Docker's virtual bridge on the host; container ports map to host ports | EC2 launch type, many tasks per host with dynamic host ports behind an ALB | Security groups apply to the host, not the task |
| host | Containers share the host's network directly | Maximum network performance | Two tasks can't use the same port on one host |
| none | No external networking | Batch jobs that need no network | No connectivity at all |
Per-task security groups
Only awsvpc gives each task its own security group. In bridge or host mode, every task on an instance shares the instance's security groups, so you can't isolate one service's traffic from another on the same host.
IAM roles
- Task execution role: used by the ECS agent to pull images from ECR, write logs to CloudWatch and fetch secrets from Secrets Manager or Parameter Store for the task definition.
- Task role: used by your application code to call AWS APIs (read S3, write DynamoDB). Give each task definition its own least-privilege role.
- Container instance role (EC2 launch type only): lets the agent register the instance with the cluster. Don't give application permissions here, because every task on the host could use them.
On EKS, the equivalent of a task role is EKS Pod Identity or IAM roles for service accounts (IRSA).
Capacity
- Capacity providers attach Auto Scaling groups or Fargate and Fargate Spot to a cluster, with weights and a base, so a service can run a baseline on Fargate and burst onto Fargate Spot.
- Fargate Spot suits interruption-tolerant tasks and gives a two-minute warning before reclaiming capacity.
- EKS Auto Mode and Karpenter manage EKS worker nodes for you when Fargate's limits (no GPUs, no DaemonSets) rule it out.
Lambda in depth
Concurrency
| Unreserved | Reserved concurrency | Provisioned concurrency | |
|---|---|---|---|
| What it does | Shares the account pool | Guarantees and caps a function's concurrency | Keeps environments initialized and ready |
| Cold starts | Yes | Yes | No, up to the provisioned amount |
| Extra cost | No | No | Yes, while provisioned |
| Use it for | Most functions | Protect a downstream DB, or stop one function starving others | Latency-sensitive APIs, predictable peaks |
- Set reserved concurrency to 0 to throttle a function completely, for example during an incident.
- Schedule provisioned concurrency with Application Auto Scaling for known peaks such as business hours.
- SnapStart (Java, Python, .NET) cuts cold starts by restoring a snapshot of an initialized environment, at lower cost than provisioned concurrency.
- Throttled synchronous calls get a 429. Asynchronous events are retried, then go to a DLQ or an on-failure destination.
Lambda hammering a database
Scaling to thousands of concurrent functions can exhaust a relational database's connections. Use RDS Proxy to pool connections, and reserved concurrency to cap the function, rather than a bigger database instance.
Lambda in a VPC
- Attach a function to a VPC only when it must reach private resources such as RDS, ElastiCache or internal APIs.
- Lambda creates shared Hyperplane ENIs per subnet and security group combination when you configure the function, so cold starts no longer pay for ENI creation.
- A VPC-attached function has no public IP, even in a public subnet. For internet access, put it in private subnets with a route to a NAT gateway. For AWS services, use VPC endpoints and skip NAT charges.
- Use at least two subnets in different AZs.
Edge compute
| CloudFront Functions | Lambda@Edge | |
|---|---|---|
| Runtime | JavaScript | Node.js, Python |
| Triggers | Viewer request, viewer response | Viewer and origin request and response |
| Execution time | Under a millisecond | Up to 5 s (viewer), 30 s (origin) |
| Network calls and body access | No | Yes |
| Scale and cost | Millions of requests per second, lowest cost | Lower scale, higher cost |
| Runs at | Every edge location | Regional edge caches |
| Typical uses | Header rewrites, URL redirects, cache-key normalization, JWT validation, A/B cookies | Auth that calls a service, dynamic origin selection, image resizing, body inspection |
- Lambda@Edge functions are created in us-east-1 and replicated globally. Versions only, no
$LATEST. - CloudFront Functions can read small config from CloudFront KeyValueStore without redeploying.
Exam signal
Anything that only touches headers, cookies or the URL at high volume is CloudFront Functions. Anything that needs an origin-side trigger, network access, the body, or more than a millisecond of work is Lambda@Edge.
Scenarios
awsvpc gives every task its own ENI, so a security group can identify the payments tasks specifically. Host ports in bridge mode are dynamic and shared on the instance's security group, so they can't reliably isolate one service. Host mode has the same shared-security-group problem. One service per instance works but wastes capacity and adds operational overhead.
Provisioned concurrency keeps environments initialized for the peak, removing cold starts. Reserved concurrency on the batch function caps how much of the Regional pool it can take. More memory speeds up execution but doesn't eliminate cold starts or throttling. A VPC adds nothing here. A longer timeout doesn't affect cold starts or concurrency.
Both tasks only read and write headers and URLs, which CloudFront Functions handles at edge locations with sub-millisecond runtime and the lowest per-request cost. Lambda@Edge works but costs more and adds latency. API Gateway or an ALB-backed Lambda would add a hop in front of or behind the cache without any benefit.
Further reading
Purpose-built databases
Choosing between RDS, Aurora, DynamoDB, DocumentDB, Neptune, Keyspaces, Timestream, MemoryDB, Redshift and OpenSearch, and the DynamoDB and Aurora features the exam tests.
Analytics patterns
Building an S3 data lake with Glue, Athena and Lake Formation, and choosing between Athena, Redshift, EMR and OpenSearch, with Firehose ingestion, QuickSight dashboards and AppSync as a GraphQL layer.