Technology

Serverless vs Containers for SMB Products: A Decision Framework (AWS Examples)

Serverless vs containers for SMB products: a decision framework on cost model, cold starts, latency, autoscaling, operational overhead and lock-in.

· Oct 27, 2026· 8 min read

Serverless vs containers is the infrastructure question every SMB product faces around its first real growth, and it is usually argued on the wrong grounds — conference talks, vendor pricing pages, what the last team used. The right grounds are the shape of your traffic, what has to run longer than a request, how much latency you can tolerate on the first call of the morning, and who is going to operate the system at two in the morning. This framework walks through those questions with AWS examples — AWS Lambda on one side, ECS on the other, Kubernetes where it genuinely belongs — and ends with the hybrid that most products we ship actually run.

One character rents a bicycle from a public rack while another tunes their own motorbike in a garage

What Each Model Optimizes For

Serverless — functions such as AWS Lambda, plus the managed event sources around them — optimizes for paying only when code runs and for never managing a host. You upload code, define what triggers it, and the platform scales it from zero to many and back. You give up control over the runtime, accept limits on execution time and memory, and take on a different kind of complexity: many small pieces wired by events.

Containers — your application packaged with its dependencies and run on a service such as ECS, or on Kubernetes when you need its scheduling and ecosystem — optimize for a long-running process you control. The runtime is yours, connections and caches persist, anything that runs in a container locally runs the same in production. You pay for the capacity you reserve whether it is busy or not, and someone has to size, patch, and watch it.

Neither is more modern. They are different cost models attached to different operational models.

Question 1: What Shape Is Your Traffic?

The cost model is decided by traffic shape more than by anything else.

  • Spiky and mostly idle — a product used in business hours in one region, batch work that runs nightly, an API that gets bursts from integrations. Paying per invocation is cheap, and idle time costs nothing. Serverless wins.
  • Steady and busy — an API serving requests all day, background workers that never drain, real-time connections. Reserved capacity costs less than per-request pricing once utilisation is high, and the price is predictable. Containers win.
  • Unknown — a new product with no traffic history. Serverless is the safer first bet because the bill follows usage, as long as the architecture keeps the option to move the hot path into a container later.

Model both with your own expected numbers before deciding; the crossover point exists, and it is different for every product.

Question 2: Does Anything Run Longer Than a Request?

Functions are designed around short, stateless work. Long-running processes — a queue consumer that runs all day, a websocket server, a job that takes an hour, anything that benefits from a warm cache or a persistent database connection pool — fit a container far more naturally. Serverless can be bent to these with step functions, streaming, and provisioned concurrency, but every bend adds cost and complexity.

A good test: list your workloads and mark each one as request-shaped or process-shaped. Products with mostly request-shaped work lean serverless; products with a few process-shaped cores lean containers for those cores, whatever the rest does.

Question 3: How Much Latency Can You Tolerate?

Cold starts are the honest cost of scale-to-zero. A function that has not run recently must be initialised before it serves, and the delay depends on the runtime, the package size, and the connections it opens at startup. For an internal report that runs nightly, nobody notices. For the login endpoint at nine in the morning, everybody does.

Ways to manage it: keep packages small and initialisation lazy, use provisioned concurrency on the few latency-sensitive functions and accept its cost, or put the latency-sensitive path in a container that is always warm. Containers have their own version of the problem — scaling out under a spike takes time to start new instances — which is where autoscaling policies with sensible minimums matter.

Question 4: Who Operates This?

Serverless hides servers; it does not hide operations. Operational overhead moves rather than disappears: from patching hosts and sizing instances to managing dozens of functions, their permissions, their event wiring, and their versions. Containers on a managed service such as ECS remove most host management too, while keeping the mental model of "an application that runs", which is easier for a small team to reason about.

The practical question for DevOps for startups is not "which has less work" but "which work does our team already know how to do". A team fluent in packaging and running an application will operate containers well from day one. A team that has built on managed services and events will be productive with functions. Either can learn the other; do not pick the model that requires learning it during the launch.

Observability, Infrastructure as Code, and the Deployment Pipeline

Whichever model you choose, three practices decide whether it is pleasant to run.

  • Observability — structured logs, traces that follow a request across functions or services, and metrics on latency and errors per endpoint. Serverless systems especially need tracing, because a request may touch many functions and the logs are scattered by default.
  • Infrastructure as code — every function, container definition, queue, and permission defined in code and reviewed like application code. This is what makes a later migration between models a refactor rather than an archaeology project, and it is non-negotiable for either.
  • A deployment pipeline that builds, tests, and deploys the whole system from one place, with previews and one-command rollback. Our guide to setting up CI/CD on your repository covers the minimum; the same pipeline should deploy functions and containers alike.

The reliability practices around these — timeouts, retries, idempotent handlers, dead-letter queues — are identical across both models and are laid out in our API integration checklist.

Vendor Lock-In: Real, but Not Where People Look

Vendor lock-in is the argument most often raised against serverless and most often misunderstood. Function code itself is small and portable; what locks you in is the event wiring, the managed services around the functions, and the permissions model. Containers are portable as artefacts, but a product that leans on a cloud's managed database, queue, and identity services is just as tied to that cloud, in a container or not.

Treat lock-in as a cost to be priced rather than a sin to be avoided. Keep business logic in plain modules behind thin adapters, define infrastructure as code, and accept provider-specific services where they save real operational work. The option to leave should be cheap; exercising it should be rare.

Scalability: Where Kubernetes Belongs

Kubernetes comes up in every serverless vs containers conversation and belongs in very few SMB products. It solves scheduling and scalability problems for many services, many teams, and heterogeneous workloads, and it charges for that in operational load. A managed container service with autoscaling covers a single product with a handful of services comfortably, and functions cover the bursty edges. Adopt Kubernetes when the number of services and teams demands it, not when a hiring post does. The broader cloud patterns — managed services, stateless application tiers, queues for background work — are described in our overview of cloud application development.

The Hybrid Most Products End Up With

In our projects, the answer is rarely either. The pattern that keeps recurring:

  • A container for the core API — always warm, predictable latency, persistent connections, easy to reason about.
  • Functions for the bursty and the event-driven — webhooks, image processing, scheduled jobs, integrations that spike.
  • Managed services for everything that is not the product — database, queue, object storage, identity, email.
  • One pipeline and one infrastructure-as-code repository for all of it.

On Pickles Auction, a real-time bidding product with escrow flows, the bidding path needed the consistent low latency and persistent connections of a long-running service, while the surrounding work — notifications, settlement steps, reporting — was exactly the event-shaped load that functions handle well and cheaply. The split was not ideological; it followed the traffic. When the first real traffic arrives, the hardening sequence in our guide to upgrading an MVP's architecture without a rewrite applies to either side of the split.

Decision Checklist

Work through this with your engineering lead before committing:

  • Traffic shape modelled with real numbers: spiky and idle, steady and busy, or unknown
  • Workloads listed and marked request-shaped or process-shaped
  • Latency-sensitive paths identified, with a cold-start plan or a warm service for each
  • Team's existing operational skills matched to the model, not the other way round
  • Observability designed in: logs, traces, per-endpoint metrics
  • Everything defined as infrastructure as code from the first environment
  • One deployment pipeline for functions and containers alike
  • Provider-specific services adopted deliberately, behind thin adapters
  • Kubernetes reserved for the day the number of services and teams demands it

FAQ

  1. Is serverless cheaper than containers? For spiky, mostly idle workloads, usually yes; for steady, busy ones, usually no. The crossover depends on your utilisation, so model it with your own numbers rather than trusting a rule of thumb.

  2. Can we start serverless and move to containers later? Yes, if business logic sits in plain modules behind thin adapters and infrastructure is defined as code. The move is then a refactor of the hot path, not a rewrite.

  3. Do cold starts make serverless unsuitable for user-facing APIs? Not in general. Keep packages small, initialise lazily, and use provisioned concurrency or a warm container for the few endpoints where the first-request latency matters.

  4. When does an SMB product actually need Kubernetes? When it runs many services owned by several teams, or workloads with very different scheduling needs. A single product with a few services is better served by a managed container service plus functions.

  5. Which is easier for a small team to operate? The one the team already knows. Managed containers keep a familiar mental model; serverless trades host management for event and permission management. Neither is free of operations.

If you are choosing the infrastructure for a new product or your bill and your latency are telling you the current choice was wrong, we can model your traffic, map the workloads, and design the split with you. Talk to IvorySoft and we will start with your numbers, not our preferences.

Scroll to top
Looking to create a perfect solution?