Containers vs VMs vs Serverless; Kubernetes vs ECS vs Cloud Run vs Lambda for Java
Fast recall
Quick revision
Core answer
Defaulting to K8s everywhere; using Lambda for the wrong workload; ignoring team skill and cost
Discuss SnapStart / GraalVM for Lambda Java, cost curves, cold-start, skill-fit, Cloud Run vs Lambda, EKS vs ECS trade-offs
Interview-ready guide
Interview answer
There are two axes. Compute model: VM, container, serverless. Orchestrator: Kubernetes, ECS, Cloud Run, Lambda. Pick independently based on workload shape, team skill, and cost.
Compute model
- VMs: full OS, slow boot, best for legacy, stateful, kernel features
- Containers: consistent packaging, seconds to start, higher density, default for modern Java
- Serverless: scale-to-zero, event-driven, pay-per-invocation, but cold-start and vendor lock-in
Orchestrators
- Kubernetes: most portable and flexible but steepest ops curve; need real expertise
- ECS / Fargate: AWS-native, simpler than K8s, Fargate removes nodes
- Cloud Run: GCP fully managed, stateless HTTP, scale-to-zero, min-instances for low latency
- Lambda: true FaaS, 100+ AWS triggers, but Java needs SnapStart, Provisioned Concurrency, or GraalVM native
Java-specific on Lambda
- Spring Boot cold start historically 2-10s
- SnapStart: free, restore from snapshot, 10x faster — use always for Java
- Provisioned Concurrency: warm instances, predictable latency, extra cost
- GraalVM native image: sub-100ms cold start, no JIT, larger build complexity
- Prefer Spring Cloud Function, Micronaut, or Quarkus over raw Spring Boot for AOT-friendly frameworks
Cost curve intuition
- Low RPS, bursty: Lambda wins
- Medium steady RPS: containers on Cloud Run or ECS Fargate
- High steady RPS: K8s with reserved + spot, or VMs for extreme scale
- Always simulate with real traffic; surprising inversions around Lambda's flat thresholds
Operational cost (people, not just $)
- Lambda/Cloud Run: near-zero ops
- ECS Fargate/Container Apps: low
- ECS on EC2: moderate
- K8s managed: moderate to high
- Self-managed K8s: very high — rarely worth it
- VMs: moderate baseline ops
Decision heuristics
- Default for modern Java service: container + managed orchestrator (ECS Fargate, Cloud Run, or EKS by cloud and skill)
- Event-driven, bursty, async: Lambda + SnapStart or Cloud Run with Pub/Sub
- Always-warm low-latency API: ECS Fargate or Cloud Run with min-instances, not raw Lambda
- Complex multi-tenant platform: K8s with platform team
- Legacy Java EE that can't containerize: VM, plan to modernize
- Big batch: K8s Jobs, AWS Batch, ECS
Security
- K8s: layered — RBAC, pod security, network policy, image admission, mTLS via mesh
- ECS: task IAM roles, VPC, security groups, Secrets Manager
- Cloud Run/Lambda: IAM per service/function
- Never bake secrets; least privilege everywhere
Observability
- All support Prometheus/OpenTelemetry; wiring effort varies
- Lambda logs expensive at scale — tune log levels and sampling
Portability vs lock-in
- K8s most portable
- ECS/Fargate is AWS; Cloud Run is GCP; Lambda is AWS
- Multi-cloud reality is rare; don't pay complexity tax for imagined portability
- Container image is portable across all
Trade-offs
- Scale-to-zero saves $$ but adds cold-start; middle: min-instances
- Serverless promises zero ops but still needs observability, cost capacity planning, cold-start tuning
- Every abstraction leaks; budget time to learn the reality
Anti-patterns
- K8s as religion for 3-engineer team on 4 services
- Lambda for always-warm latency-critical Java API without SnapStart/native
- VMs for greenfield microservices
- Too many orchestrators — on-call nightmare
- Default to K8s without skills
- Serverless everywhere even for steady high-RPS
- Ignoring data transfer costs, log ingestion
- JVMs without container ergonomics — cgroup-unaware OOM kills
- Huge Docker images slow every deploy — distroless/jlink/native
Senior behaviors
- Operational cost before compute cost
- Model cost with real traffic
- Simplest-that-fits; you can always scale up complexity
- Avoid orchestrator sprawl — one paved path for 80%
- Tune JVM for containers — MaxRAMPercentage, container support flags
- Lambda Java always with SnapStart or native
- SLO-driven platform choice
Interview emphasis
- Start with workload shape: traffic pattern, latency SLO, event-driven
- Both compute and orchestrator axes
- Cold-start realities and mitigations
- Concrete trade-offs; no dogma
- Admit team-skill reality — right choice depends on who operates it
Bottom line
- Containers + managed orchestrator is 2026 default for Java
- Lambda earns its keep in event-driven and bursty, with SnapStart
- K8s is right only with real expertise and ecosystem need
- Pick for user SLO and team operation, not resume
Containers vs VMs vs Serverless; Kubernetes vs ECS vs Cloud Run vs Lambda for Java
Direct Answer
The compute axis (VM / container / serverless) decides what you operate; the orchestrator axis (K8s / ECS / Cloud Run / Lambda) decides how much you operate. VMs give maximum control and legacy compatibility but pay in operations and boot time. Containers win for most modern Java: faster packaging, consistent environments, cheaper density, portability. Serverless wins for event-driven, bursty, low-baseline workloads where you want to pay only for invocations. On orchestration: Kubernetes for maximum portability, complex ecosystems, platform teams with K8s skill; ECS/Fargate for AWS-centric teams who want "serverless containers" without K8s operations; Cloud Run for stateless HTTP workloads with automatic scale-to-zero; Lambda for true function-per-event use cases with cold-start-tolerant or tuned Java (SnapStart, GraalVM native image). For a typical Java backend serving sustained traffic, containers + managed orchestrator (EKS, ECS, or Cloud Run depending on cloud and skill) is the 2026 default. Lambda wins for glue, async processing, and spiky workloads where cold-start cost is acceptable or mitigated. The big mistakes: choosing K8s because it's fashionable when your team lacks the skill; choosing Lambda for a latency-sensitive always-warm service; choosing VMs out of habit for greenfield work.
Common Mistakes & Pitfalls
Defaulting to K8s everywhere; using Lambda for the wrong workload; ignoring team skill and cost
Check your understanding
Answer these without looking back at the article.
- How does Lambda SnapStart actually work, and what limitations does it have for Spring Boot?
- When would you move a service from Cloud Run to GKE?
- How do you size resource requests for a Java container on Kubernetes?
- What cost dimensions do engineers most commonly overlook on AWS?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.