Benchmark comparing Python and Rust AWS Lambda performance on an identical, realistic workload: read a file from S3, parse it, and batch-write 50,000 event registration records to DynamoDB — with real-time progress streamed to the browser over a WebSocket API.
This is the source code for the blog post "We Cut Our Lambda Bill by 33% Switching to Rust — And AI Wrote the Code".
What it measures
- 50,000 event registration records across 30 music concerts, 11 fields each
- Stored in S3 as both CSV (7.8 MB) and JSON (17.1 MB)
- Identical config for both runtimes: 1024 MB, ARM64/Graviton, on-demand DynamoDB, batch writes of 25 with retry
- Only difference: Python 3.12 managed runtime vs Rust on
provided.al2023 - A verification Lambda confirms both tables contain identical data after each run
Browser (WebSocket) → API Gateway → Lambda → S3 + DynamoDB
← progress messages ←
Layout
cdk/ AWS CDK stack (Python) — defines Lambdas, DynamoDB, S3, WebSocket API
data/ generate_data.py — produces the CSV/JSON test data (not committed)
lambdas/
python_processor/ Python 3.12 handler
rust_processor/ Rust handler (cargo-lambda, provided.al2023)
verify/ confirms both tables match
configure/ runtime wiring
ui/ static dashboard (WebSocket client) served locally
Reproduce
# Prerequisites rustup install stable brew install zig # for cross-compilation cargo install cargo-lambda # Build the Rust Lambda cd lambdas/rust_processor cargo lambda build --release --arm64 # Generate test data python data/generate_data.py # Deploy cd cdk python -m venv .venv && source .venv/bin/activate pip install -r requirements.txt cdk deploy --outputs-file outputs.json # Wire the UI to your deployed WebSocket URL node update_config.js # writes ui/config.js from cdk/outputs.json # Run the UI cd ui && python -m http.server 8080
Open http://localhost:8080, click Warm Up, then Run All Tests. Watch the progress stream in real time, then click Verify Data to confirm both tables match.
Note:
cdk/outputs.jsonandui/config.jshold the WebSocket URL for your deployment and are git-ignored. Copyui/config.example.jstoui/config.jsif you want to point the UI at an existing endpoint by hand.
Results (warm, 50k records)
| Test | Total time | Parse | Avg / 1k records |
|---|---|---|---|
| Rust + CSV | 14,740 ms | 140 ms | 295 ms |
| Rust + JSON | 12,416 ms | 167 ms | 248 ms |
| Python + CSV | 21,194 ms | 469 ms | 424 ms |
| Python + JSON | 20,205 ms | 170 ms | 404 ms |
Rust runs ~33% faster on this workload. The gap is bounded by DynamoDB write I/O rather than CPU; pure-compute workloads would favour Rust by a wider margin.