Workload triage
Which parts of the system are genuinely event-driven, which are steady-state, and what each costs in both shapes at your real volumes.
Serverless is excellent for spiky, event-shaped work and expensive for steady high-throughput traffic. We will tell you which one you have before writing any of it.
Serverless on AWS means running code without managing servers: Lambda for the code, API Gateway for HTTP, EventBridge and SQS for messages between services, Step Functions for work that outlives a Lambda timeout. You are billed for execution rather than for uptime.
A queue consumer that runs eight hours a day is a great Lambda. The same code running flat out around the clock costs more than the container it replaced, and you gave up a debugger to get there. The arithmetic takes an afternoon and it saves arguments later.
Which parts of the system are genuinely event-driven, which are steady-state, and what each costs in both shapes at your real volumes.
EventBridge or SQS between services, with dead letter queues and replay, so a bad afternoon is recoverable instead of lost.
Multi-step jobs that outlive a Lambda timeout, with the state machine visible rather than buried in retry logic.
Provisioned concurrency where latency is a user-facing promise, reserved concurrency where a runaway function could otherwise drain the account limit.
If the only way to test is to deploy, your team will stop testing. Pipelines and local harnesses come with the build.
Triage first. Some of what you have should not be a Lambda, and we will say which.
Which workloads suit Lambda and which do not. Steady high-throughput work is usually cheaper on containers, and the maths goes in writing.
EventBridge and queues between components, so a slow consumer degrades instead of taking the producer down with it.
Anything past a few minutes, or anything needing retries and compensation, becomes a state machine rather than a chain of functions calling functions.
Reserved and provisioned concurrency where latency matters, set from measurements, with the monthly cost of that choice stated.
A development loop that runs on a laptop, and infrastructure as code so an environment gets rebuilt rather than repaired.
The same code can be right in either place. What decides it is how many hours a day the work is actually running.
| Dimension | Lambda | Containers on ECS or EKS |
|---|---|---|
| Billing | Per millisecond of execution | Per second the task runs, idle included |
| Spiky traffic | Scales to zero between the spikes | You pay for the floor you keep warm |
| Steady high traffic | Costs more once utilisation stays high | Cheaper once a task is busy most of the hour |
| Cold start | Tens to hundreds of milliseconds, removed by provisioned concurrency at a price | None once the task is running |
| Maximum run time | 15 minutes per invocation | No limit |
| Local debugging | A test harness, or deploy to find out | Run the same image on a laptop |
| What you still operate | Nothing below the function | Cluster or Fargate, plus image patching |
If none of these sound like you, say so on the call and we will tell you honestly whether this is the right piece of work to start with.
No. Below roughly steady, continuous utilisation it usually wins on price and always wins on operational effort. Above that a right-sized container is cheaper. We run the numbers on your traffic and put them in writing.
Almost every system we run does. API on containers, event processing on Lambda, is a common and sensible split.
Fifteen minutes per invocation. Work that takes longer belongs in Step Functions, which orchestrates several short functions and keeps the state visible, or in a container task with no time limit.
Provisioned concurrency on the functions where latency is a promise to a user, and nothing on the rest, because it costs money whether the function runs or not. Trimming the deployment package and avoiding heavy initialisation gets most of the win for free.
It lands in a dead letter queue rather than disappearing. Every consumer we build has one, plus a replay path, so a bad afternoon is something you reprocess rather than something you explain to a customer.
With a local harness and contract tests, so the loop does not require a deploy. If the only way to check a change is to push it, testing quietly stops happening, and that shows up later as incidents.
If traffic is spiky or low, yes. If it is steady and high, a container behind a load balancer is usually cheaper and easier to debug. We run the numbers against your actual request volume and put them in writing before anything is built.
Containers on EKS or ECS, microservices where they earn their keep, and enough observability to debug the system at three in the morning.
Terraform, deployment pipelines and environments that rebuild from code. Deploys a new hire can run in their first week without supervision.
A two-week read of your AWS account against the six pillars. You get a ranked list of what to fix, what it costs, and what happens if you leave it.
Thirty minutes with an engineer, no slide deck. We will tell you what we would change first and what it would cost to have us do it.