AWS compute comparison

AWS Lambda vs EC2

Two fundamentally different ways to run code on AWS. Lambda is serverless — event-driven, pay-per-invocation, zero maintenance overhead, but with hard limits on runtime and state. EC2 is a full virtual machine — always on, fully customisable, but you manage it and pay for uptime whether the instance is idle or busy.

TL;DR

  • AWS Lambda — serverless functions, event-triggered, pay per 100 ms of execution, 15-minute maximum timeout, stateless, subject to cold starts. Ideal for event-driven workloads, APIs with variable traffic, and scheduled jobs.
  • EC2 — virtual machine with persistent processes, full OS access, any runtime, any duration. You manage patching and scaling. Best for steady workloads, long-running servers, stateful applications.
  • Also consider AWS Fargate (serverless containers, no 15-minute ceiling) as a middle ground for containerised workloads.

Side-by-side comparison

AspectAWS LambdaEC2
Compute modelServerless — AWS manages all underlying serversVirtual machine — you provision, configure, and patch
Pricing modelPer invocation + per 100 ms of execution timePer hour (On-Demand) or with Reserved/Spot discounts
Idle costZero — you pay only when code is executingFull price regardless of traffic
Cold startYes — 10 ms to 1 000 ms+ depending on runtime and package sizeNone — your process is always running
Execution timeoutMaximum 15 minutes per invocationUnlimited
StateStateless — no reliable persistence across invocationsFull disk, memory, and process state
ScalingAutomatic — concurrency scales to thousands in secondsManual or via Auto Scaling Groups (minutes to add instances)
OS / runtime accessManaged runtimes only; custom runtimes via Lambda LayersFull root access — install any software, custom kernels, GPUs
Maintenance overheadNear zero — AWS handles patches, OS updates, capacityHigh — you manage AMIs, patching, monitoring agents
Best forAPIs, event processing, scheduled jobs, webhooksLong-running servers, stateful apps, BYOL workloads, GPU

What is AWS Lambda?

AWS Lambda is a serverless compute service introduced in 2014. You upload a function — a self-contained unit of code — and define what triggers it: an HTTP request via API Gateway, an object uploaded to S3, a message arriving in SQS, a schedule (EventBridge), or dozens of other AWS event sources.

When a trigger fires, AWS spins up an execution environment (or reuses a warm one), runs your function, and tears it down. You are billed for the number of invocations and the duration in 100 ms increments. At zero traffic you pay nothing.

The tradeoff is constraints. Lambda functions are stateless: you cannot rely on data persisting between invocations unless you store it externally in DynamoDB, S3, or RDS. Execution time is capped at 15 minutes. And when no warm environment exists, you suffer a cold start — the latency of initialising a fresh container, downloading your code, and starting the runtime.

Cold start in plain English

Imagine a restaurant kitchen where all the chefs go home when there are no orders. The moment a customer arrives, you must call the chefs back, have them put on their uniforms, and heat the oven — before cooking a single dish. That waiting time is the cold start. A warm instance is a kitchen with a chef already standing by.

What is Amazon EC2?

Amazon Elastic Compute Cloud (EC2), launched in 2006, is AWS's original compute service. You choose an instance type — a combination of vCPUs, RAM, storage, and network throughput — and launch a virtual machine running your choice of operating system. The instance runs continuously until you stop or terminate it.

Common instance families include:

  • t3 / t4g — burstable general purpose; cheap, suitable for low-to-moderate workloads
  • m6i / m7g — balanced CPU/memory; the default choice for web servers and APIs
  • c7g / c6i — compute-optimised; for CPU-intensive workloads
  • r6i / r7g — memory-optimised; for in-memory databases or large caches
  • p4d / g5 — GPU instances; for machine learning training and inference

Unlike Lambda, EC2 supports persistent processes: a web server, a database, a long-running background worker, or any process that must maintain state in memory or on disk across many requests. You also get full SSH access, which makes debugging significantly easier than in a serverless environment.

EC2 demands maintenance overhead: you are responsible for OS patching, AMI updates, security group rules, monitoring agents, and capacity planning. Auto Scaling Groups help automate horizontal scaling, but the setup is far more involved than Lambda's automatic concurrency.

How engineers talk about Lambda vs EC2

These phrases come up regularly in architecture discussions, pull requests, and incident reviews. Learning them helps you follow technical conversations confidently.

  • "We're seeing cold starts on the Java runtime — let's switch to Node.js or enable Provisioned Concurrency."

    Used when Lambda latency spikes for infrequent requests. Provisioned Concurrency keeps a set number of warm instances ready.

  • "Lambda scales to zero overnight — we pay nothing when there's no traffic."

    Scales to zero is a key selling point of serverless: no idle instances means no idle cost.

  • "The function times out after 15 minutes — we need to break this job into smaller chunks."

    The execution timeout is Lambda's hardest limit. Long jobs must be decomposed into smaller invocations, often via Step Functions or SQS.

  • "This workload is stateless, so Lambda is a good fit — we don't need the instance to remember anything between requests."

    Stateless means each invocation is self-contained. The opposite — stateful — requires external state management or a persistent server.

  • "We're on a t3.medium — 2 vCPUs, 4 GB RAM — it handles our baseline traffic, and the Auto Scaling Group adds more instances during peak hours."

    EC2 instance types follow a naming convention: family letter(s) + generation number + size (nano, micro, small, medium, large, xlarge, 2xlarge…).

  • "We moved the image-resizing pipeline to Lambda. It's event-driven — S3 triggers the function whenever a file is uploaded."

    Event-driven architectures react to events (file upload, queue message, HTTP call) rather than polling. Lambda is purpose-built for this pattern.

  • "The Reserved Instance for this API server saves us 40% compared to On-Demand."

    Reserved Instances commit you to 1 or 3 years in exchange for a significant discount. Contrast with Spot Instances, which are spare capacity sold cheaply but can be interrupted.

  • "Debugging Lambda in production is painful — there's no SSH, so we rely entirely on CloudWatch Logs and X-Ray traces."

    The lack of a persistent process and SSH access is one of Lambda's practical downsides. Structured logging and distributed tracing become essential.

Lambda function skeleton (Node.js)

A Lambda handler receives an event object and a context object. It must complete within the configured timeout.

// handler.mjs — AWS Lambda (Node.js 20)
export const handler = async (event, context) => {
  // event contains trigger-specific data
  // (API Gateway request, S3 event, SQS message, etc.)
  console.log('Request ID:', context.awsRequestId);

  // Lambda is stateless — don't rely on module-level state
  // across invocations. Use DynamoDB, S3, or RDS for persistence.
  const result = await processEvent(event);

  return {
    statusCode: 200,
    body: JSON.stringify(result),
  };
};

EC2 deployment sketch (systemd service)

On EC2 you manage a persistent process. A typical Node.js API is kept alive by systemd and fronted by nginx.

# /etc/systemd/system/myapp.service
[Unit]
Description=My API Server
After=network.target

[Service]
Type=simple
User=deploy
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/node server.mjs
Restart=on-failure
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

Decision guide: Lambda or EC2?

  • Event-driven, spiky, or unpredictable traffic → Lambda
  • API with variable load, responds in under 15 minutes → Lambda
  • Scheduled jobs, background tasks, webhook handlers → Lambda
  • Zero infrastructure management required → Lambda
  • Long-running server process (hours or days) → EC2
  • Application needing local disk or in-memory state → EC2
  • Custom OS, kernel module, GPU, or BYOL licence → EC2
  • SSH access needed for debugging → EC2
  • Steady high-throughput workload where Lambda cost exceeds EC2 → EC2 or Fargate
  • Containerised workload, no 15-minute limit, no server management → Fargate

Frequently asked questions

What is the main difference between AWS Lambda and EC2?

EC2 (Elastic Compute Cloud) is a virtual machine you provision, configure, and pay for by the hour — whether or not it is handling traffic. Lambda is serverless: you deploy a function, and AWS runs it only when triggered by an HTTP request, an event, or a schedule. You pay per invocation and per 100 ms of execution time. Lambda removes all infrastructure management; EC2 gives you full control over the runtime environment.

What is a cold start and why does it matter?

A cold start occurs when Lambda needs to initialise a brand-new execution environment — downloading your deployment package, starting the runtime, and running initialisation code — before it can handle a request. This adds latency ranging from 10–100 ms for Node.js or Python to over a second for Java with a large classpath. Cold starts are most noticeable for infrequently invoked functions. Provisioned Concurrency pre-warms Lambda instances to eliminate cold starts, at an additional cost.

What are the hard limits of AWS Lambda?

Lambda has a maximum execution timeout of 15 minutes per invocation, up to 10 GB of RAM, 512 MB–10 GB of ephemeral /tmp storage, and a deployment package limit of 250 MB (unzipped). These constraints make Lambda unsuitable for long-running batch jobs, workloads requiring persistent local state, or anything demanding GPU access. For those scenarios, EC2, Fargate, or ECS is more appropriate.