Serverless on Rust: When Every Millisecond Counts
\n\nHave you ever waited for an AWS Lambda to start for a whole 3-4 seconds? If you've worked with Python or Node.js in a serverless environment, you're familiar with this pain — cold start. Now imagine: your function starts in 50-100 milliseconds, consumes 10 times less memory, and the binary weighs only 5 megabytes. Welcome to the world of serverless functions on Rust.
\n\nRust burst into serverless for a reason. It's a language that gives you control over memory without a garbage collector, compiles to native code, and is perfect for edge computing. At PythonLib we love Python, but when it comes to speed and cost — especially under high loads — Rust becomes a killer.
\n\nIn this article, we'll cover:
\n- \n
- Why Rust is the best language for serverless (spoiler: not just because of speed) \n
- How to write and deploy AWS Lambda on Rust \n
- Alternatives: Cloudflare Workers and Vercel Edge Functions \n
- Cold start benchmarks: Rust vs Python \n
Ready? Let's go.
\n\nWhy Rust for Serverless is Not Hype, But Math
\n\nLet's get straight to the numbers. The average cold start of AWS Lambda on Python is 400-800 ms (with dependency loading). On Node.js — 200-400 ms. On Rust — 30-100 ms. Why such a difference?
\n\n- \n
- No interpreter or JIT. Rust compiles to machine code. Lambda just loads the binary — and it's ready. \n
- Minimal size. Even with tokio and serde, the binary weighs 5-15 MB (compressed zip — 2-4 MB). Python with numpy or pandas — 50-200 MB. \n
- Memory savings. Rust functions consume 20-50 MB compared to 128-256 MB for Python. On 10 million requests, the difference in the bill is hundreds of dollars. \n
But there's a nuance: writing in Rust is harder. You need to understand ownership, lifetimes, async. However, if your Lambda is a critical microservice with RPS > 1000, Rust pays off quickly.
\n\nPractice: Writing AWS Lambda on Rust
\n\nStep 1: Installing Tools
\n\nYou will need:
\n- \n
- Rust (rustup) \n
- cargo-lambda — utility for building for AWS \n
- Docker (for building under Linux if you have macOS/Windows) \n
# Install cargo-lambda\ncargo install cargo-lambda\n\n# Create a new project\ncargo lambda new my-rust-lambda\ncd my-rust-lambda\n\nStep 2: Function Code
\n\nOpen src/main.rs. The standard template already contains a basic structure. Let's write something useful — an API that accepts JSON with a name and returns a greeting.
use lambda_runtime::{run, service_fn, Error, LambdaEvent};\nuse serde::{Deserialize, Serialize};\n\n#[derive(Deserialize)]\nstruct Request {\n name: String,\n}\n\n#[derive(Serialize)]\nstruct Response {\n message: String,\n timestamp: u64,\n}\n\nasync fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> {\n let request = event.payload;\n let timestamp = std::time::SystemTime::now()\n .duration_since(std::time::UNIX_EPOCH)\n .unwrap()\n .as_secs();\n\n Ok(Response {\n message: format!("Hello, {}! You're on PythonLib, but we're on Rust 🦀", request.name),\n timestamp,\n })\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Error> {\n tracing_subscriber::fmt()\n .with_max_level(tracing::Level::INFO)\n .init();\n\n run(service_fn(handler)).await\n}\n\nStep 3: Build and Deploy
\n\n# Build for Linux (for Lambda)\ncargo lambda build --release\n\n# Deploy (AWS credentials required)\ncargo lambda deploy --iam-role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role\n\nDone! Now you have a Lambda on Rust that runs 5-10 times faster than its Python counterpart.
\n\