86 / 95 · 05 Performance & Chaos Engineering · Serverless Performance Testing← prev⊞ allnext →☰ Read as one page
13.5Memory Configuration Testing
For AWS Lambda, CPU is proportional to memory. More memory means more CPU, which can reduce execution time enough to offset the higher per-ms cost:
# lambda_memory_optimizer.py
"""
Test a Lambda function across memory configurations to find the cost-optimal setting.
More memory = faster execution but higher per-ms cost.
The sweet spot minimizes (execution_time_ms * memory_mb * cost_per_gb_ms).
"""
import boto3
import time
import json
lambda_client = boto3.client('lambda')
def benchmark_memory_config(function_name: str, payload: dict, memory_sizes: list[int]) -> list:
results = []
for memory_mb in memory_sizes:
# Update function memory
lambda_client.update_function_configuration(
FunctionName=function_name,
MemorySize=memory_mb,
)
time.sleep(10) # wait for update to propagate
# Run 10 invocations and collect timings
durations = []
for _ in range(10):
start = time.perf_counter()
response = lambda_client.invoke(
FunctionName=function_name,
Payload=json.dumps(payload),
)
wall_time = (time.perf_counter() - start) * 1000
billed_ms = json.loads(response['Payload'].read())
durations.append(wall_time)
avg_duration = sum(durations) / len(durations)
# AWS pricing: $0.0000166667 per GB-second
cost_per_invocation = (memory_mb / 1024) * (avg_duration / 1000) * 0.0000166667
results.append({
"memory_mb": memory_mb,
"avg_duration_ms": round(avg_duration, 1),
"p99_duration_ms": round(sorted(durations)[8], 1),
"cost_per_invocation": f"${cost_per_invocation:.8f}",
})
return results
# Example usage
results = benchmark_memory_config(
"my-function",
{"key": "test-payload"},
[128, 256, 512, 1024, 2048, 3072],
)
for r in results:
print(f"{r['memory_mb']}MB: {r['avg_duration_ms']}ms avg, {r['cost_per_invocation']}/invocation")