Lambda Power Tuning Case Study

· 2 min · medium

AWS Lambda bills on two things: memory size and duration. Because the charge is in GB-seconds, a faster function costs less. More memory also means more vCPU, so for CPU-bound work you could raise memory, run faster and pay less. Interesting, right?

Measuring

Measuring that is harder than it sounds. It takes many invocations at each memory setting to get a statistically significant result, repeated across many settings. The AWS Lambda Power Tuning tool does it for you. It runs as a Step Functions state machine, invokes your function n times at each memory setting and records the execution time.

It then charts execution time and average cost for each configuration:

In this example, execution time falls from 35s at 128MB to under 3s at 1.5GB, and it's 14% cheaper to run.

The scenario

The test subject is a real Lambda in production. Digging through its logs, I found a non-I/O operation that looked slow and likely CPU-bound, a good case for power tuning.

The y-axis, which I cropped off above (sorry), is response time. The same goes for the charts below.

At 30 invocations per memory setting, the first results were disappointing. More memory should give a fairly linear improvement, and it didn't. A third-party service the function called had varying response times, which skewed the results.

The goal was to find the right memory for CPU-bound work, so I/O wasn't relevant. I removed every I/O call, mocking the HTTP calls, so only the computation was measured and the results were deterministic.

Round 2

That gave a much more linear progression. Cost stayed similar across configurations, because each step up in memory cut the time by a matching amount.

The highest memory setting performed best, so the next run started from that result, 1536MB, and stepped up to 3072MB. The x-axis shows each value tested.

Which is best depends on whether you're optimising for cost or speed. 1792MB is the cheapest. 2240MB saves under 10ms more, which isn't worth the extra cost for a service that isn't latency-sensitive.

The result

With I/O removed, the computation went from 900ms to under 100ms, at a fractionally lower cost. That's an 88.8% reduction for very little work, and the tool makes it easy to try on your own functions.