Choosing the right memory configuration for AWS Lambda is a balancing act between performance and cost. Too little memory causes slow execution (Lambda allocates CPU proportionally to memory). Too much wastes money. AWS Lambda Power Tuning, an open-source tool built on Step Functions, automates this optimization by benchmarking your function across multiple memory configurations and identifying the optimal balance. This guide covers installation, interpretation of results, and advanced tuning strategies.
How Lambda Pricing Works
Lambda charges $0.0000166667 per GB-second. This means:
- 128 MB running 1 second = $0.0000021
- 1024 MB running 1 second = $0.0000167
- 3008 MB running 1 second = $0.0000501
But here’s the crucial insight: at higher memory, functions run faster. A function taking 1000ms at 128 MB might complete in 150ms at 1024 MB. Let’s calculate:
| Memory | Duration | Cost per Invocation |
|---|---|---|
| 128 MB | 1000 ms | $0.0000021 |
| 512 MB | 350 ms | $0.0000029 |
| 1024 MB | 150 ms | $0.0000025 |
| 2048 MB | 100 ms | $0.0000033 |
The optimal configuration (1024 MB) is actually cheaper than the minimum (128 MB) because duration dropped significantly.
Installing Power Tuning
# Using SAR (Serverless Application Repository)
aws serverlessrepo create-cloud-formation-change-set \
--application-id arn:aws:serverlessrepo:us-east-1:451282441545:applications/aws-lambda-power-tuning \
--stack-name lambda-power-tuning \
--capabilities CAPABILITY_IAM
# Or using SAM
sam deploy -t template.yml --guided
Running the Tuner
{
"lambdaARN": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
"powerValues": [128, 256, 512, 1024, 1536, 2048, 3008],
"num": 50,
"payload": {"customerId": "test-123"},
"parallelInvocation": true,
"strategy": "balanced"
}
Strategy options:
- cost: Minimize cost (may sacrifice performance)
- speed: Minimize duration (may increase cost)
- balanced: Optimize cost * duration
Interpreting Results
Power Tuning generates a visualization URL showing cost vs duration across configurations. Look for:
- Knee Points: Where cost decreases flatten out
- CPU-Bound Functions: Linear improvement with memory
- I/O-Bound Functions: Flat line (more memory doesn’t help)
flowchart LR
subgraph CPU ["CPU-Bound Function"]
C1["128MB: 2000ms"] --> C2["512MB: 500ms"] --> C3["2048MB: 125ms"]
end
subgraph IO ["I/O-Bound Function"]
I1["128MB: 500ms"] --> I2["512MB: 480ms"] --> I3["2048MB: 475ms"]
end
style C3 fill:#C8E6C9,stroke:#2E7D32
style I1 fill:#C8E6C9,stroke:#2E7D32
For I/O-bound functions (waiting on DynamoDB, HTTP calls), choose minimum memory. For CPU-bound functions (image processing, JSON parsing), choose higher memory.
Automation with CDK
// Run Power Tuning as part of CI/CD
const tuningStep = new tasks.StepFunctionsStartExecution(this, 'RunPowerTuning', {
stateMachine: powerTuningStateMachine,
input: TaskInput.fromObject({
lambdaARN: fn.functionArn,
powerValues: [128, 256, 512, 1024, 2048],
num: 20,
strategy: 'balanced'
}),
resultPath: '$.tuningResult'
});
// Parse recommendation and update function
const updateConfig = new tasks.LambdaInvoke(this, 'UpdateFunctionConfig', {
lambdaFunction: configUpdaterFn,
payload: TaskInput.fromJsonPathAt('$.tuningResult.output')
});
Key Takeaways
- Lambda Power Tuning automates memory optimization
- CPU-bound functions benefit from higher memory
- I/O-bound functions should use minimum memory
- The “balanced” strategy optimizes cost × duration
- Integrate into CI/CD for continuous optimization
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.