Deepen PracticeOrdered learning track

Workload Placement Decision Framework

Learn AWS Containers and Serverless - Part 076

Production workload placement decision framework for AWS compute and integration services: choosing Lambda, ECS, EKS, Fargate, App Runner, Step Functions, EventBridge, SQS, SNS, DynamoDB, S3, and RDS using latency, duration, state, concurrency, cost, operations, reliability, security, and migration criteria.

17 min read3259 words
PrevNext
Lesson 7698 lesson track54–80 Deepen Practice
#aws#architecture#workload-placement#lambda+7 more

Part 076 — Workload Placement Decision Framework

Most compute debates are framed badly.

Bad question:

Should we use Lambda or Kubernetes?

Better question:

What does this workload require from execution, state, latency, scale, failure handling, cost, security, and operations?

Compute placement is a decision framework, not a religion.

This part gives a practical framework for choosing between:

  • Lambda;
  • ECS/Fargate;
  • ECS on EC2;
  • EKS;
  • App Runner;
  • Step Functions;
  • AWS Batch;
  • SQS/EventBridge/SNS;
  • DynamoDB/S3/RDS as state/data plane;
  • hybrid combinations.

The goal is not to produce one answer.

The goal is to make trade-offs explicit.


1. Placement Starts With Workload Shape

Before picking a service, describe the workload.

workload:
  name: invoice-generation
  trigger: API command
  duration: 2-8 minutes
  traffic: bursty during end-of-month
  payload: references S3 documents
  state: job status and output
  dependencies:
    - billing database
    - PDF rendering library
    - S3
  reliability:
    - no duplicate invoices
    - retryable processing
    - DLQ and redrive
  latency:
    - API should return within 1 second
    - job output within 10 minutes
  security:
    - tenant isolated
    - confidential documents
  cost:
    - cost per invoice matters
  operations:
    - on-call needs status and redrive

This description already suggests:

API Lambda -> SQS -> ECS/Fargate worker or Step Functions -> S3/DynamoDB

Not because of preference.

Because duration, payload, state, and reliability suggest it.


2. The Ten Placement Dimensions

Evaluate every workload on ten dimensions.

1. Duration

  • milliseconds/seconds;
  • minutes;
  • hours;
  • always-on.

2. Latency

  • user-facing p99;
  • async completion time;
  • cold start tolerance;
  • queue delay tolerance.

3. Traffic Shape

  • spiky;
  • steady;
  • predictable schedule;
  • burst after event;
  • high sustained throughput.

4. State

  • stateless;
  • small durable state;
  • session/connection state;
  • workflow state;
  • large object state.

5. Concurrency

  • high parallelism;
  • ordered per aggregate;
  • downstream-limited;
  • connection-limited.

6. Dependencies

  • AWS APIs;
  • VPC resources;
  • database;
  • external API;
  • native binaries;
  • GPU/large CPU.

7. Failure Semantics

  • retry-safe;
  • idempotent;
  • compensation needed;
  • poison records;
  • redrive/replay;
  • audit critical.

8. Operations

  • debugging needs;
  • deployment model;
  • runtime control;
  • team skill;
  • observability.

9. Cost

  • idle cost;
  • per-request cost;
  • steady utilization;
  • logs/egress/downstream;
  • unit economics.

10. Security/Compliance

  • data classification;
  • network isolation;
  • audit;
  • encryption;
  • runtime control;
  • tenant isolation.

3. Compute Options at a Glance

ServiceBest FitAvoid When
Lambdashort event-driven tasks, bursty APIs/workerslong-running, connection-heavy, custom daemon/runtime control
ECS Fargatecontainer workloads without EC2 managementultra-tiny sporadic tasks where Lambda simpler
ECS on EC2high utilization/cost control, custom capacityteam does not want host/capacity management
EKSKubernetes ecosystem, controllers, platform standardsimple AWS-native event handlers
App Runnersimple containerized web apps/APIscomplex networking/orchestration/custom platform needs
Step Functionsdurable workflow/orchestrationpure compute-heavy task without workflow state
AWS Batchbatch/HPC/large compute jobslow-latency request/response
SQSdurable backlog/backpressuresynchronous request requiring immediate result
EventBridgeevent routing/fanoutqueue/backpressure or strict ordering
SNSpush pub/sub notificationscomplex event governance/replay
DynamoDBkey-value/document state/idempotencyad hoc relational querying/joins
S3object bytes/fileslow-latency mutable record state

Services are not competitors only.

They are building blocks.


4. Duration Decision

Short Work

If work is:

< few seconds to tens of seconds
stateless or small state
event-driven
bursty

Lambda is often strong.

Examples:

  • API adapter;
  • webhook receiver;
  • SQS small message consumer;
  • EventBridge consumer;
  • S3 metadata validator;
  • Step Functions task;
  • DynamoDB stream projection.

Medium Work

If work is:

minutes
variable duration
needs status

Use:

  • Step Functions;
  • SQS job queue;
  • ECS/Fargate worker;
  • Lambda only if within timeout and operationally safe.

Long Work

If work is:

tens of minutes to hours

Use:

  • ECS/Fargate;
  • EKS Job;
  • AWS Batch;
  • Step Functions orchestration;
  • Glue/EMR/etc depending data type.

Do not hide long work inside Lambda.

Always-On Work

If work is:

server process
long-lived connection
Kafka consumer
websocket server
in-memory cache

Use containers or specialized managed service.


5. Latency Decision

User-Facing API

Ask:

  • p95/p99 SLO?
  • cold start tolerance?
  • request duration?
  • auth complexity?
  • downstream latency?
  • provisioned concurrency justified?
  • can work be async?

Options:

ShapePlacement
simple low-latency APILambda + API Gateway with SnapStart/provisioned concurrency if needed
always-on high-throughput APIECS/EKS/App Runner
long commandAPI returns 202 + SQS/Step Functions
file uploadpresigned S3 URL
heavy response generationasync job or container

Async Latency

For async, user does not wait, but business still has latency.

Measure:

  • queue age;
  • async event age;
  • iterator age;
  • workflow duration;
  • job completion time.

Async systems need SLOs too.


6. Traffic Shape Decision

Spiky and Idle Often

Lambda usually fits.

Examples:

  • webhook spikes;
  • scheduled small job;
  • event consumer with low average traffic;
  • dev/internal tool.

Predictable Peaks

Lambda with provisioned concurrency/scheduled scaling may fit.

ECS/Fargate scheduled scaling may also fit.

Steady High Utilization

Containers may be more cost-efficient.

Examples:

  • 24/7 API with high RPS;
  • continuous worker;
  • Kafka consumer;
  • high-volume transformation.

Burst With Downstream Limits

Use SQS regardless of compute.

burst -> queue -> capped consumers

Compute choice comes after backpressure decision.


7. State Decision

Stateless

Lambda or containers both fine.

Choose by duration/traffic/ops.

Durable Item State

DynamoDB/RDS with Lambda/ECS.

Use conditional writes/idempotency.

Workflow State

Step Functions.

Do not encode long workflow state in Lambda memory or container local disk.

Object State

S3.

Pass references, not bytes.

Session/Connection State

Containers, managed sessions, or external store.

Lambda execution environment reuse is not session state.

In-Memory Cache

Containers or external cache.

Lambda /tmp/memory cache is opportunistic only.


8. Concurrency Decision

High Independent Parallelism

Lambda can scale fast, but protect downstream.

Use:

  • reserved concurrency;
  • SQS max concurrency;
  • Step Functions Map max concurrency;
  • DynamoDB capacity/key design.

Ordered Processing

Use:

  • SQS FIFO message groups;
  • Kinesis partition key;
  • DynamoDB optimistic concurrency;
  • Step Functions per aggregate;
  • single consumer per group/partition.

Downstream-Limited

Use queue + cap.

Do not let compute auto-scale beyond dependency.

Connection-Limited

Containers often better because connection pools are stable and countable.

Lambda can work with RDS Proxy/reserved concurrency but needs careful math.


9. Dependency Decision

AWS API Calls Only

Lambda often excellent.

Private VPC Database

Lambda works but consider:

  • VPC config;
  • RDS Proxy;
  • connection limits;
  • reserved concurrency;
  • cold/start networking;
  • query latency.

Containers may be better for connection-heavy workloads.

External API

For short calls:

  • Lambda with timeout/idempotency.

For slow/rate-limited calls:

  • SQS + worker;
  • Step Functions;
  • containers for sustained workflows;
  • circuit breaker.

Native Libraries

Lambda container image may fit.

If library requires long process/OS control or huge artifacts, ECS/EKS/Fargate may fit better.

Kafka

Lambda supports MSK/Kafka event source mappings, but long-lived custom Kafka consumers may fit ECS/EKS better when offset/state/control needs are complex.


10. Failure Semantics Decision

Simple Retry

Lambda async/SQS/EventBridge may be enough.

Need Durable Backlog

SQS.

Need Workflow Compensation

Step Functions.

Need Poison Record Isolation

SQS DLQ, stream failure destination, Step Functions catch/quarantine.

Need Human Approval

Step Functions callback token or external workflow.

Need Replay

EventBridge archive/replay, SQS DLQ redrive, stream retention, S3 manifest, outbox/event log.

Need Exactly-Once Business Side Effect

No AWS compute option magically gives this.

Use:

  • idempotency;
  • conditional writes;
  • external idempotency keys;
  • transactions/outbox;
  • reconciliation.

Placement does not remove correctness design.


11. Operations Decision

Team Skill

Use what team can operate well.

  • If team has no Kubernetes maturity, EKS may be costly operationally.
  • If team has no serverless async experience, Lambda/EventBridge can fail subtly.
  • If team has no workflow discipline, Step Functions can become spaghetti.

Golden paths reduce skill burden.

Debugging Needs

Containers provide:

  • process-level debugging;
  • shell/sidecar/agent patterns;
  • long-running logs;
  • local parity.

Lambda provides:

  • simpler deployment;
  • managed scale;
  • CloudWatch/X-Ray/Powertools;
  • no host management.

Deployment Needs

  • Lambda aliases/canary for functions;
  • ECS rolling/blue-green;
  • EKS deployment strategies;
  • Step Functions versions/aliases;
  • EventBridge rule rollout;
  • AppConfig flags.

Choose based on operational model, not only runtime.


12. Cost Decision

Lambda Cost Good When

  • low average utilization;
  • bursty;
  • short;
  • no idle required;
  • scale-to-zero valuable;
  • ops savings significant.

Container Cost Good When

  • high steady utilization;
  • long-running;
  • connection-heavy;
  • predictable capacity;
  • CPU/memory intensive;
  • team already operates platform well.

Step Functions Cost Good When

  • workflow visibility/reliability saves engineering time;
  • compensation/retry/audit needed;
  • direct integrations remove Lambda glue.

Cost Trap

Comparing only compute cost:

Lambda GB-seconds vs Fargate vCPU-hours

misses:

  • logs;
  • retries;
  • NAT;
  • downstream;
  • operations;
  • incidents;
  • deployment safety;
  • developer time.

Use unit cost per business outcome.


13. Security Decision

Ask:

  • what data classification?
  • public or private endpoint?
  • VPC access required?
  • IAM role granularity?
  • runtime isolation requirements?
  • secrets handling?
  • audit requirements?
  • network egress restrictions?
  • tenant isolation?
  • compliance retention?

Lambda Security Strength

  • small execution role per function;
  • short-lived environments;
  • no host patching;
  • easy narrow integration.

Container Security Strength

  • custom runtime hardening;
  • sidecars/agents;
  • network/service mesh controls;
  • long-running inspection;
  • runtime policies;
  • deeper platform controls.

Both can be secure.

Both can be insecure.

Placement must match security controls and team maturity.


14. Decision Tree

This tree is a simplification, but it forces the right questions.


15. Scoring Matrix

Use a 1–5 score.

DimensionLambdaECS/FargateEKSStep Functions
short bursty event5322
long-running process1552
workflow state2115
low ops overhead5424
custom runtime control2451
steady high utilization cost3552
connection-heavy2551
AWS event integration5334
compensation/retry visibility2225
team skill dependentmediummediumhighmedium

Do not use this as absolute truth.

Use it to have structured conversations.


16. Workload Examples

Example 1 — Payment Capture API

Requirements:

  • synchronous response;
  • strict idempotency;
  • external provider call;
  • p95 latency target;
  • no duplicate charge.

Placement:

API Gateway -> Lambda API
DynamoDB idempotency
external provider with idempotency key
EventBridge event after success

If provider is slow/unreliable:

API -> Step Functions or SQS async command

depending business UX.

Example 2 — Monthly PDF Report Generation

Requirements:

  • large job;
  • minutes;
  • S3 output;
  • user checks status.

Placement:

API Lambda -> SQS/Step Functions -> ECS/Fargate worker -> S3 + DynamoDB status

Example 3 — Search Index Projection

Requirements:

  • eventually consistent;
  • idempotent update;
  • bursty events.

Placement:

EventBridge -> SQS -> Lambda consumer

If volume sustained/high:

EventBridge -> SQS -> ECS worker

Example 4 — Kafka Aggregator

Requirements:

  • long-lived partition consumer;
  • high throughput;
  • stateful processing.

Placement:

EKS/ECS consumer service

with output to:

EventBridge/SQS/DynamoDB/S3

Example 5 — File Upload Ingestion

Requirements:

  • direct upload;
  • validation;
  • processing;
  • output metadata.

Placement:

API Lambda presigned URL
S3 incoming/
S3 -> SQS
Lambda validator
Step Functions/ECS for heavy processing
DynamoDB metadata

17. Placement by Anti-Requirement

Sometimes decision is made by what service should not do.

Do Not Use Lambda If

  • work exceeds Lambda timeout;
  • requires long-lived bidirectional connection;
  • requires stable in-memory session;
  • requires daemon/background thread reliability;
  • requires GPU/custom host;
  • needs heavy sustained CPU for cost;
  • connection pool math is unsafe;
  • debugging/runtime control is central.

Do Not Use EKS If

  • workload is simple event glue;
  • team lacks Kubernetes operations maturity;
  • no need for cluster ecosystem;
  • platform overhead exceeds benefit;
  • AWS-native integration is easier with Lambda/Step Functions.

Do Not Use Step Functions If

  • single short function is enough;
  • workflow state is unnecessary;
  • state transitions would be excessive without value;
  • team uses it as visual programming for simple code;
  • data payloads are huge and not referenced.

Do Not Use EventBridge If

  • you need durable queue/backpressure as primary feature;
  • you need strict ordering;
  • you need immediate request/response;
  • consumers are command handlers with result expectation.

18. Placement and Migration Cost

Initial placement can be wrong. Make migration possible.

Use boundaries:

  • SQS between producers and workers;
  • EventBridge between domains;
  • Step Functions for orchestration;
  • S3 references for large data;
  • API contracts for front door;
  • idempotency keys;
  • schema versions.

These boundaries let you move compute behind them.

Example:

SQS consumer starts as Lambda.
Later becomes ECS worker.
Producer unchanged.

That is good architecture.

Bad architecture:

API directly invokes specific Lambda that contains all workflow and side effects.

Migration is hard.


19. Placement Review Template

Use this in design docs.

workload:
  name:
  owner:
  criticality:
  dataClassification:

trigger:
  type:
  syncOrAsync:
  expectedRate:
  peakRate:

execution:
  expectedDuration:
  maxDuration:
  memoryCpuNeed:
  coldStartTolerance:
  runtimeDependencies:

state:
  durableState:
  objectData:
  workflowState:
  idempotencyKey:

failure:
  retryableFailures:
  permanentFailures:
  dlq:
  redrive:
  compensation:
  duplicateSafety:

capacity:
  downstreamLimits:
  concurrencyCap:
  backlogSlo:
  rateLimit:

security:
  iam:
  secrets:
  network:
  audit:

operations:
  logsMetricsTraces:
  alarms:
  runbook:
  deployment:
  rollback:

cost:
  unitCostMetric:
  expectedMonthlyVolume:
  majorCostDrivers:

decision:
  selectedServices:
  rejectedOptions:
  tradeoffs:

A decision without rejected options is usually not a decision. It is a default.


20. Decision Smells

Smell 1 — “We Always Use Lambda”

Likely ignoring workload diversity.

Smell 2 — “We Always Use EKS”

Likely over-operating simple workloads.

Smell 3 — “This Lambda Just Orchestrates 8 Steps”

Probably Step Functions.

Smell 4 — “This API Might Take 5 Minutes”

Probably async job/workflow.

Smell 5 — “We Need to Slow Down Consumers”

Probably SQS/backpressure.

Smell 6 — “One Event Should Notify Many Consumers”

Probably EventBridge/SNS, often with SQS per consumer.

Smell 7 — “We Need Exactly Once”

Probably misunderstanding. Need idempotency/transactions/reconciliation.

Smell 8 — “We Need to Query by Many Fields in DynamoDB”

Maybe wrong data model or RDS/OpenSearch need.

Smell 9 — “We Need Shell Access to Debug Lambda”

Maybe container service or better observability.

Smell 10 — “Kubernetes Because Resume”

Not an architecture reason.


21. Placement Under Constraints

Constraint: Team Is Small

Prefer:

  • Lambda;
  • Step Functions;
  • SQS/EventBridge;
  • DynamoDB/S3;
  • App Runner for simple container API.

Avoid unless necessary:

  • EKS;
  • custom platforms;
  • EC2 cluster management.

Constraint: High Compliance

Prefer:

  • clear account boundaries;
  • IAM least privilege;
  • KMS;
  • audit logs;
  • Step Functions for audit workflows;
  • S3 Object Lock/versioning where needed;
  • explicit runbooks.

Compute can be Lambda or containers, but auditability matters.

Constraint: Extremely High Throughput

Evaluate:

  • containers for steady compute;
  • Lambda for burst;
  • Kinesis/MSK for streams;
  • DynamoDB key design;
  • SQS batch/concurrency;
  • cost per unit.

Constraint: Legacy Container App

Maybe:

  • ECS/App Runner for first migration;
  • then extract async/serverless side paths;
  • do not rewrite everything to Lambda immediately.

Constraint: Fast Product Experiment

Maybe:

  • Lambda + DynamoDB + API Gateway;
  • AppConfig flags;
  • simple EventBridge/SQS;
  • revisit if workload becomes sustained/heavy.

22. Build-vs-Managed Decision

Sometimes the placement question is not just compute.

Ask whether AWS managed service replaces custom compute.

Examples:

NeedManaged Service Option
workflow orchestrationStep Functions
queue/backpressureSQS
pub/subSNS/EventBridge
schedulerEventBridge Scheduler
file storageS3
key-value stateDynamoDB
API front doorAPI Gateway/ALB/App Runner
searchOpenSearch
batch computeAWS Batch
ETLGlue/EMR depending need

Do not build a scheduler inside ECS if EventBridge Scheduler fits.

Do not build a workflow engine inside Lambda if Step Functions fits.

Do not build a queue in DynamoDB unless SQS does not fit and you understand trade-offs.


23. Placement and Team Topology

Architecture should match team ownership.

Single Team, One Service

Simple stack may be fine.

Multiple Producers/Consumers

EventBridge/SNS/SQS boundaries help.

Platform Team + Product Teams

Golden paths and templates matter.

Data Team Consumers

Event contracts, S3 data lake, streams, and governance matter.

Security/Compliance Stakeholders

Audit trails, account boundaries, KMS, and retention matter.

A compute choice that ignores ownership becomes an operating problem.


24. Placement and Future Change

Ask:

  • if traffic grows 10x, what changes?
  • if duration grows 10x, what changes?
  • if one tenant becomes 80% traffic, what changes?
  • if external API becomes slow, what changes?
  • if workflow adds human approval, what changes?
  • if we need replay, what changes?
  • if we need multi-region, what changes?

Choose boundaries that preserve optionality.

SQS/EventBridge/S3 references/Step Functions often preserve optionality better than direct synchronous coupling.


25. Migration Playbook by Trigger

TriggerLikely Migration
Lambda timeout pressureLambda -> Step Functions/ECS worker
Lambda cost high steady trafficLambda worker/API -> ECS/Fargate/App Runner
container side tasks burstyECS side work -> SQS/Lambda
workflow hidden in codecode chain -> Step Functions
downstream overloaddirect invoke -> SQS buffer
event fanout growingdirect calls -> EventBridge/SNS
file payload through APIAPI payload -> S3 presigned upload
DynamoDB query complexityadd access-pattern index or move read model
queue consumer heavy sustainedLambda consumer -> ECS worker
low-latency Java cold start issueSnapStart/provisioned concurrency or container API

Migration should preserve contracts where possible.


26. Placement Decision Checklist

Workload

  • Duration known.
  • Latency SLO known.
  • Traffic pattern known.
  • State needs classified.
  • Payload size known.
  • Dependencies listed.
  • Ordering requirement known.

Reliability

  • Retry semantics known.
  • Idempotency key defined.
  • DLQ/failure path defined.
  • Backpressure need evaluated.
  • Workflow/compensation need evaluated.
  • Replay/redrive requirement known.

Operations

  • Team skill considered.
  • Deployment strategy known.
  • Observability plan.
  • Runbook owner.
  • Debugging needs considered.
  • Migration path considered.

Security/Cost

  • IAM/network/secrets requirements.
  • Data classification.
  • Unit cost driver identified.
  • Idle vs utilization evaluated.
  • Downstream cost included.

Decision

  • Selected services listed.
  • Rejected alternatives documented.
  • Trade-offs explicit.
  • Review date set.

27. Common Anti-Patterns

Anti-Pattern 1 — Compute First, Workload Later

Team chooses platform before describing workload.

Anti-Pattern 2 — Ignoring Failure Semantics

Placement based on happy path only.

Anti-Pattern 3 — No Migration Boundary

Producer tightly coupled to current compute.

Anti-Pattern 4 — Cost Compared Without Reliability

Cheaper service selected but DLQ/replay/audit missing.

Anti-Pattern 5 — Serverless Used for Stateful Daemon

Wrong execution contract.

Anti-Pattern 6 — Kubernetes Used for Tiny Glue

Operational overhead dominates value.

Anti-Pattern 7 — EventBridge Used Instead of Queue

No consumer backpressure.

Anti-Pattern 8 — SQS Used Instead of Workflow

No visibility into multi-step process.

Anti-Pattern 9 — DynamoDB Used for Arbitrary Queries

Access patterns not modeled.

Anti-Pattern 10 — Step Functions Used for Pure CPU Loop

Wrong tool for compute-heavy tight loop.


28. Final Mental Model

Workload placement is architecture under constraints.

The correct answer is not:

Lambda

or:

EKS

The correct answer is a composition:

front door
execution
queue/event boundary
state store
workflow
object store
observability
failure path
deployment model

A top-tier engineer makes placement decisions by asking:

What contract does this workload need today,
what failure mode must it survive,
what scale/cost might it reach,
and what boundary lets us change compute later?

That is workload placement engineering.


References

  • AWS Lambda Developer Guide: event-driven architectures
  • AWS Lambda Developer Guide: event source mappings
  • AWS Step Functions Developer Guide: integrating services and optimized integrations
  • AWS Step Functions Developer Guide: run ECS/Fargate tasks
  • Amazon EventBridge Scheduler documentation
  • AWS Well-Architected Framework and Serverless Applications Lens
  • Amazon ECS, Amazon EKS, AWS Fargate, AWS App Runner, Amazon SQS, Amazon EventBridge, Amazon SNS, DynamoDB, and S3 documentation
Lesson Recap

You just completed lesson 76 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.