advanced 2 min answer

Prime Video's video-quality monitoring team moved from a serverless step-function pipeline back to a single long-running service and reported a large cost reduction. What actually changed, and which generalisation from this would be wrong?

prime-videoserverlessmonolithcost-per-requestdecomposition
Show the full answer Hide the answer

What actually changed

The original design decomposed frame-by-frame video analysis into functions per step, coordinated by a workflow orchestrator, with intermediate video frames passed between steps through object storage.

Two costs dominated, and neither was compute:

  • Orchestration cost per state transition. The workflow engine is billed per transition. When the unit of work is a frame, and the pipeline has several steps, the number of transitions scales with frames analysed rather than with streams analysed — which is the wrong scaling axis for the price of coordination.
  • Data transfer between steps. Frames were written to object storage by one function and read by the next. The intermediate data was larger than the useful output, and it crossed a network boundary at every step.

The rewrite put the steps in one process, so frames moved between them in memory and the orchestration disappeared entirely. The reported reduction was roughly 90% for that component.

The architectural principle underneath

Decomposition boundaries should follow the data, not the verbs. The steps were separated because they were conceptually distinct activities, not because they had different scaling, failure, or deployment needs. When components must exchange large state at high frequency, a boundary between them is a network hop and a serialisation cost per exchange — and the "clean" separation is paid for on every frame forever.

The right question is not "are these different responsibilities?" but "if I put a network between these two things, what crosses it, how often, and how big is it?"

The wrong generalisation

  • "Serverless does not scale." It scaled fine. It cost too much for this shape of workload: high-frequency, large-payload, tightly-coupled steps.
  • "Microservices were a mistake." This is one component inside Amazon, an organisation running an enormous number of services. A single team reversing one internal decomposition is not a verdict on the style.
  • "Monoliths are cheaper." They were cheaper here because the steps shared data at high frequency. Where steps have genuinely different scaling profiles or failure isolation needs, the separation pays for itself.

The honest reading is narrower and more useful: function-per-step decomposition is wrong when the steps are chatty and the payloads are large, and the cost shows up per request rather than per deployment.

What should have caught it earlier

A cost-per-request model built before the design was committed, not after it ran in production. The transition count per stream and the bytes crossing each boundary were both calculable from the design document.