AWS Jul 6, 2026 · 7 min read

Lambda or Fargate: how I decide which to use

Yohangel Ramos

Yohangel Ramos

Tech Lead · Senior Fullstack Developer

"Lambda or Fargate?" is one of those questions people ask expecting a winner, and there isn't one. Both run code without you managing servers, but they solve differently shaped problems. After building plenty of services on ECS Fargate and plenty of functions on Lambda, I stopped choosing by fashion and started looking at three things about the workload: how traffic arrives, how long each unit of work lasts, and how much state the process needs to hold. Almost always the decision falls out on its own.

It isn't serverless versus containers

The first misunderstanding is treating it as serverless versus containers. Fargate is also serverless: you define a task, AWS runs it, and you never touch an EC2 instance. The real difference is the execution model. Lambda is ephemeral and event-invoked: a request arrives, an environment spins up, your handler runs, it responds, and it shuts down. Fargate is a long-lived process: your container starts once, sits listening, and serves requests until you scale it or kill it.

That difference colors everything. In Lambda you don't control the lifecycle: there's no "startup" of yours where you open a connection pool and calmly reuse it, because the environment can be recycled at any moment. In Fargate you do have a stable process with its startup, its warm memory, and its connection pool alive between requests. Choosing is, at bottom, choosing how much control you want over that lifecycle.

The shape of traffic rules

The first thing I look at is how the work arrives. If traffic is intermittent, bursty, or unpredictable —a webhook that fires now and then, a cron that processes on schedule, an endpoint with odd spikes— Lambda fits naturally. It scales from zero to many parallel invocations without you configuring anything, and when there's no traffic you pay nothing. That "zero to a thousand without warning" is exactly where Fargate struggles: holding capacity for the spike means paying for containers sitting idle, and reactive scaling is slower than a Lambda cold start.

If traffic is sustained and constant, the math flips. A service under steady load all day, on Lambda, is a continuous drip of invocations billed by the millisecond that ends up expensive next to a handful of Fargate containers at full tilt. There a long-lived process squeezes more out of each CPU: it doesn't repeat the startup cost on every request and keeps warm the resources Lambda would rebuild over and over.

💡 Lambda charges per invocation and duration: it shines when traffic is sometimes zero. Fargate charges per running container: it shines when traffic is almost never zero. Before deciding, draw a day's traffic curve.

Duration and limits: the 15-minute clock

The second axis is how long each unit of work lasts. Lambda has a hard cap of fifteen minutes per invocation. For an API or event processing that's plenty, but any job that might run over —a long migration, video processing, a job that walks a large dataset— doesn't fit, and slicing it to fit is complexity that doesn't always pay off. Fargate has no such clock: a task can run for minutes or hours, which makes it the natural home for long batch work or processes that simply have to stay alive.

There's also the cold start. When Lambda spins up a fresh environment, the first invocation pays the cost of initializing the runtime. For latency-tolerant loads it doesn't matter; for an endpoint sensitive to tail latency, that occasional cold hit shows. It's mitigated —provisioned concurrency, lightweight runtimes— but it's a real factor. Fargate has no per-request cold start: you pay startup once when you scale a new task, not on every invocation.

State, connections, and dependencies

The third axis is how much state and which dependencies the process needs. The classic case is the database. A connection pool lives on reusing connections between requests, and that fits a long-lived process like Fargate. In Lambda, each concurrent environment opens its own, and under a spike you can exhaust PostgreSQL's connections without noticing; the fix is an intermediate connection proxy, one more piece in the diagram. It's not impossible to run Lambda against a relational database, but it's friction Fargate doesn't have.

// In Fargate this initializes ONCE at container start
// and the pool is reused on every request.
import { Pool } from 'pg';

const pool = new Pool({ max: 10 }); // lives between requests

export async function handler(req: Request) {
  const client = await pool.connect(); // reuses, doesn't reopen
  try {
    return await query(client, req);
  } finally {
    client.release();
  }
}

That same pattern in Lambda is treacherous: the pool survives while the environment is reused, but it multiplies per concurrent environment, and that's where the database blows up under load.

My rule, and why I mix the two

In the end my criterion is simple. I start on Lambda when the work is short, event-triggered, with irregular traffic and little state: webhooks, async tasks, glue between AWS services. I move to Fargate when the work is sustained, long-running, or needs live connections and lifecycle control: APIs under constant load, queue workers processing nonstop, long batch.

And I don't pick one for the whole system. In the same product an HTTP service on Fargate with a stable Postgres connection coexists with Lambda functions for incoming webhooks and async jobs. I chose to mix rather than force a single model because each workload has its shape, and fighting the tool to do something it isn't built for always costs you: in Lambda with proxies and slicing, in Fargate with idle capacity waiting for a spike that never comes. Like almost everything in AWS, there's no best tool, there's the best tool for the shape of your problem.

Yohangel Ramos

Written by Yohangel Ramos

Senior Fullstack Developer and Tech Lead. I build with React, Next.js, Nest.js and AWS — and I write about what I learn along the way.

Let's talk →

Keep reading

IA

AI-built startups in 2026: the real numbers behind the hype

IA

How to survive as a programmer in the AI era (without turning cynical or naive)