Serverless promises that you only pay for what you use. That is true, and also exactly why bills surprise people: usage is the variable you stopped watching.

This is a working note rather than a definitive guide — the patterns here come from systems I’ve actually shipped and the trade-offs I kept running into along the way.

Make cost a first-class design input

I treat the cost of a request the same way I treat its latency budget — a number I can estimate before I write the code, and one I instrument once it ships. Every async hop, every retry, and every fan-out is a multiplier you can reason about up front.

A serverless bill is just your architecture, itemized.

The reference setup I keep reaching for keeps the hot path on a single table with well-chosen keys, pushes everything non-urgent onto EventBridge, and reserves Lambda concurrency so a traffic spike degrades gracefully instead of compounding.

None of this is glamorous, but it’s the part that decides whether a design holds up once real traffic and real deadlines arrive.