Skip to content

Commit 0adc3af

Browse files
committed
Test at different memory sizes
1 parent e6210c4 commit 0adc3af

File tree

3 files changed

+49
-38
lines changed

3 files changed

+49
-38
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# python-lambda-benchmark
22

3-
Small repo to benchmark Lambda runtime execution across different layers.
3+
Small repo to benchmark Lambda runtime execution across different layers and memory sizes.
44

55
Tests:
66
* [AWS OpenTelemetry Collector layer](https://github.com/open-telemetry/opentelemetry-lambda)

benchmark/main.py

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,22 @@ def parse_args():
1818
parser.add_argument('--region', default='us-east-1', help='AWS region (default: us-east-1)')
1919
parser.add_argument('--handler', default='SimpleLambda.lambda_handler', help='Lambda function handler')
2020
parser.add_argument('--runtime', default='python3.13', help='Lambda runtime (default: python3.13)')
21+
parser.add_argument('--memory', type=int, default=128, help='Memory in MB')
2122
parser.add_argument('--environment', help='Environment')
2223
parser.add_argument('--layer', help="ARN of layer to include")
24+
parser.add_argument('--output', required=True, help="Output file")
2325
return parser.parse_args()
2426

2527
def delete_lambda_function(lambda_client, function_name):
2628
try:
2729
lambda_client.delete_function(FunctionName=function_name)
28-
print(f"Deleted Lambda function: {function_name}")
2930
except ClientError as e:
3031
if e.response['Error']['Code'] == 'ResourceNotFoundException':
3132
print(f"Lambda function not found: {function_name}")
3233
else:
3334
raise
3435

35-
def create_lambda_function(lambda_client, function_name, environment, zip_path, role_arn, handler, runtime, layer):
36+
def create_lambda_function(lambda_client, function_name, environment, zip_path, role_arn, handler, runtime, memory, layer):
3637
try:
3738
with open(zip_path, 'rb') as zip_file:
3839
zip_content = zip_file.read()
@@ -47,18 +48,15 @@ def create_lambda_function(lambda_client, function_name, environment, zip_path,
4748
Handler=handler,
4849
Code={'ZipFile': zip_content},
4950
Timeout=10,
50-
MemorySize=128,
51+
MemorySize=memory,
5152
Layers=[layer] if layer else [],
5253
)
53-
print(f"Created Lambda function: {function_name}")
54-
# Wait for function to be fully initialized
55-
time.sleep(5)
5654
return response['FunctionArn']
5755
except ClientError as e:
5856
print(f"Error creating Lambda function {function_name}: {e}")
5957
return None
6058

61-
def invoke_lambda_function(lambda_client, function_name, payload):
59+
def invoke_lambda_function(lambda_client, base_name, function_name, memory, payload):
6260
try:
6361
start_time = time.time()
6462
response = lambda_client.invoke(
@@ -94,15 +92,12 @@ def invoke_lambda_function(lambda_client, function_name, payload):
9492
if not lambda_init_duration:
9593
raise Exception("Could not extract the actual Lambda init duration from logs")
9694

97-
print(f"Invoked {function_name}:")
98-
print(f" HTTP Status: {status_code}")
99-
print(f" Client-side duration: {duration:.2f} ms")
100-
101-
if lambda_init_duration:
102-
print(f" Lambda-reported init duration: {lambda_init_duration:.2f} ms")
95+
print(f"Invoked {function_name}: Status: {status_code}, Duration: {duration:.2f} ms, Init Duration: {lambda_init_duration:.2f} ms")
10396

10497
return {
98+
'base_name': base_name,
10599
'function_name': function_name,
100+
'memory': memory,
106101
'status_code': status_code,
107102
'client_duration_ms': duration,
108103
'init_duration_ms': lambda_init_duration,
@@ -135,7 +130,7 @@ def main():
135130

136131
print(f"Deploying {args.count} Lambda functions...")
137132
for i in range(1, args.count + 1):
138-
function_name = f"{args.function_name}-{i}"
133+
function_name = f"{args.function_name}-{args.memory}-{i}"
139134
# Try to delete it first
140135
delete_lambda_function(lambda_client, function_name)
141136
function_arn = create_lambda_function(
@@ -146,12 +141,15 @@ def main():
146141
args.role_arn,
147142
args.handler,
148143
args.runtime,
144+
args.memory,
149145
args.layer,
150146
)
151147
if function_arn:
152148
functions.append(function_name)
153149

154-
print(f"\nSuccessfully deployed {len(functions)} Lambda functions")
150+
# Wait for all functions to be fully initialized
151+
time.sleep(5)
152+
print(f"Successfully deployed {len(functions)} Lambda functions")
155153

156154
# Invoke each function with a simple payload
157155
test_payload = {
@@ -163,25 +161,25 @@ def main():
163161
}
164162
}
165163

166-
print("\nInvoking each function and recording durations...")
167164
for function_name in functions:
168-
result = invoke_lambda_function(lambda_client, function_name, test_payload)
165+
result = invoke_lambda_function(lambda_client, args.function_name, function_name, args.memory, test_payload)
169166
if result:
170167
results.append(result)
171168

172-
# Write results to file
173-
output_file = 'lambda_benchmark_results.json'
174-
with open(output_file, 'w') as f:
175-
json.dump(results, f, indent=2)
176-
177-
print(f"\nResults have been saved to {output_file}")
178-
179169
# Print summary
180170
print(f"\nSummary of lambda init durations (cold start) for {args.function_name}:")
181171

182172
sorted_results = sorted(results, key=lambda x: x['init_duration_ms'])
183173
sorted_durations = list(map(lambda x: str(x['init_duration_ms']), sorted_results))
184-
print(f"Durations: {", ".join(sorted_durations)}")
174+
print(f"Init Durations: {", ".join(sorted_durations)}")
175+
176+
with open(args.output, 'a') as f:
177+
f.write("base_name, memory, client_duration_ms, init_duration_ms\n")
178+
for result in sorted_results:
179+
f.write(f"{result['base_name']}, {result['memory']}, {result['client_duration_ms']}, {result['init_duration_ms']}\n")
180+
181+
for function_name in functions:
182+
delete_lambda_function(lambda_client, function_name)
185183

186184
if __name__ == "__main__":
187185
main()

scripts/benchmark-coldstart.sh

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/bin/bash
22

3-
COUNT=${COUNT:-10}
3+
COUNT=${COUNT:-5}
4+
5+
MEMORY_SIZES="128 1024 2048 3072 4096 5120"
46

57
if [ $# -ne 1 ]; then
68
echo "Usage: $0 <output-file>"
@@ -32,6 +34,7 @@ fi
3234

3335
cat <<EOF
3436
Running benchmark with the following:
37+
- Memory size: $MEMORY_SIZES
3538
- AWS Region: $AWS_REGION
3639
- OTEL Layer: $OTEL_LAYER
3740
- Rotel Layer: $ROTEL_LAYER
@@ -43,19 +46,29 @@ make bundle
4346

4447
cd benchmark
4548

46-
echo "Testing base case"
49+
for MEMORY_SIZE in ${MEMORY_SIZES}; do
50+
echo "Testing base case at $MEMORY_SIZE MB"
51+
52+
uv run main.py --path ../function.zip --count $COUNT --function-name benchmark-coldstart \
53+
--role-arn "$AWS_ROLE_ARN" --region "$AWS_REGION" --output "$OUTPUT" \
54+
--memory "$MEMORY_SIZE"
55+
done
4756

48-
uv run main.py --path ../function.zip --count $COUNT --function-name benchmark-coldstart \
49-
--role-arn "$AWS_ROLE_ARN" --region "$AWS_REGION" --output "$OUTPUT"
5057

51-
echo "Testing OpenTelemetry collector layer"
58+
for MEMORY_SIZE in ${MEMORY_SIZES}; do
59+
echo "Testing OpenTelemetry collector layer at $MEMORY_SIZE MB"
5260

53-
uv run main.py --path ../function.zip --count $COUNT --function-name benchmark-coldstart-otel \
54-
--environment OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/collector.yaml \
55-
--role-arn "$AWS_ROLE_ARN" --region "$AWS_REGION" --layer "$OTEL_LAYER" --output "$OUTPUT"
61+
uv run main.py --path ../function.zip --count $COUNT --function-name benchmark-coldstart-otel \
62+
--environment OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/collector.yaml \
63+
--role-arn "$AWS_ROLE_ARN" --region "$AWS_REGION" --layer "$OTEL_LAYER" --output "$OUTPUT" \
64+
--memory "$MEMORY_SIZE"
65+
done
5666

57-
echo "Testing Rotel layer"
67+
for MEMORY_SIZE in ${MEMORY_SIZES}; do
68+
echo "Testing Rotel layer at $MEMORY_SIZE MB"
5869

59-
uv run main.py --path ../function.zip --count $COUNT --function-name benchmark-coldstart-rotel \
60-
--environment ROTEL_ENV_FILE=/var/task/rotel.env \
61-
--role-arn "$AWS_ROLE_ARN" --region "$AWS_REGION" --layer "$ROTEL_LAYER" --output "$OUTPUT"
70+
uv run main.py --path ../function.zip --count $COUNT --function-name benchmark-coldstart-rotel \
71+
--environment ROTEL_ENV_FILE=/var/task/rotel.env \
72+
--role-arn "$AWS_ROLE_ARN" --region "$AWS_REGION" --layer "$ROTEL_LAYER" --output "$OUTPUT" \
73+
--memory "$MEMORY_SIZE"
74+
done

0 commit comments

Comments
 (0)