Extracting the workloads that genuinely benefit from serverless, with cold starts and scope modelled before anything moves rather than discovered afterwards.
Serverless is excellent for bursty, event-driven and irregular workloads: image processing, webhook handling, scheduled jobs, traffic that arrives in spikes. It is a poor fit for steady high-throughput services, anything latency-critical enough to be hurt by cold starts, and long-running processes.
Most monoliths contain both kinds. So the useful question is never whether to go serverless; it is which workloads should move and which should stay exactly where they are.
We model scope and latency for each candidate before moving it. Several engagements have concluded that half the shortlist should stay on containers, which is a cheaper outcome than finding out after migration.
Teams that start here often pair it with on-premise to cloud migration, ML model deployment and API integration.
The teams who regret serverless are almost always the ones who moved a steady high-throughput service to it because the whole system was going serverless.
Four ways the promised savings fail to appear.
A latency-sensitive endpoint moves to a function with a heavy runtime, so p99 latency gets substantially worse.
A steadily busy service effort several times more per request as functions than it did on a reserved instance.
Hundreds of concurrent function instances each open a database connection and exhaust the pool under exactly the load they were meant to handle.
Logic spread across dozens of functions with no distributed tracing, so debugging a failed flow means correlating log groups by hand.
Candidate selection, then extraction, then honest measurement.
Every candidate profiled for traffic shape, latency scope and duration, with a scope model for both serverless and container hosting.
Chosen workloads extracted behind an API gateway, with the monolith continuing to serve everything else.
Runtime choice, package trimming and provisioned concurrency where the latency scope requires it, sized against real traffic.
Proxied database connections so concurrency scaling does not exhaust the pool.
End-to-end tracing across functions and the monolith, so a request is followable across the boundary.
Per-workload scope dashboards, with the pre-migration model checked against reality after cutover.
Only what benefits, measured before and after.
Traffic patterns, latency scopes and durations profiled, with a scope comparison per candidate workload.
A written recommendation on what moves and what stays, including the workloads we advise leaving alone.
Workloads moved behind a gateway one at a time, with tracing and rollback at the routing layer.
Latency and scope measured against the pre-migration model, with the difference reported plainly.
Next workload only once the previous one is confirmed better on the numbers that mattered.
Managed services where they earn their scope.
Functions for bursty work, containers for steady throughput, chosen per workload.
Queues and event buses so extracted workloads decouple properly rather than just relocating.
Connection proxying so scaling concurrency does not exhaust the database.
Distributed tracing across the boundary, because correlating logs by hand does not scale.
A media platform ran everything on a Rails monolith on fixed EC2 capacity, sized for the daily peak when publishers uploaded batches of images. For most of the day that capacity sat idle.
Image processing was an ideal candidate: bursty, stateless, tolerant of a hundred milliseconds of cold start. Webhook handling and scheduled reports were too. The main API was not, and the scope model showed it would be roughly three times more expensive as functions.
We moved the three that fitted and left the API on containers. Infrastructure spend dropped by just over half, and peak processing capacity went up rather than down.
We model scope and latency per workload before moving anything, and we routinely recommend leaving half the shortlist where it is.
We move one slice at a time behind a router, with both systems live, so every step is small and every step is reversible.
A working demo and a written note every Friday covering what shipped, what slipped and what it means for the date. No status theatre.
Nothing goes live in one jump. We run in parallel or behind a flag until the numbers say it is safe to switch over.