Go & Rust for Cost-Effective Serverless: What the Data Actually Shows
Are people actually squeezing real cost savings out of Go and Rust in serverless infrastructure? Yes — and the numbers are significant enough that this has become a serious trend rather than enthusiast experimentation.
TL;DR
Go and Rust consistently deliver the lowest cold-start times and memory footprints across serverless platforms. On AWS Lambda specifically, real-world rewrites show cost reductions of 70-75% compared to Node.js/TypeScript equivalents. The sweet spot is ARM64 (AWS Graviton) with either language — lower compute price + better performance. The main trade-off is not cost or performance, but developer ergonomics and team familiarity.
Context
The serverless cost model punishes slow startups and high memory usage twice: once in latency, once in the bill. Languages with a garbage collector (Node.js, Python, Java, even Go to a lesser extent) introduce unpredictable latency spikes under load. Rust and Go eliminate or minimize this — Rust has no GC at all, Go’s is fast and tunable. Combined with the move toward ARM64 infrastructure, this is driving real adoption in cost-sensitive engineering teams.
Analysis / Key Findings
1. AWS Lambda: The Benchmark Picture
The most comprehensive ongoing benchmark is lambda-perf which tracks cold starts across all runtimes. Key numbers from late 2025:
| Runtime | Cold Start (ms) | Architecture |
|---|---|---|
| Rust (custom runtime) | ~20 ms | arm64 |
| Go (provided.al2023) | ~40 ms | arm64 |
| Node.js 22 | ~180–300 ms | arm64 |
| Python 3.12 | ~200–400 ms | arm64 |
| Java 21 (GraalVM) | ~300–600 ms | arm64 |
| Java 21 (JVM) | ~1000–3000 ms | arm64 |
Rust cold starts are 5-8x faster than interpreted runtimes. Go sits comfortably in second place, still dramatically faster than the Node/Python tier.
Critical 2025 change: In August 2025, AWS started billing for the Lambda INIT phase (previously free). For functions with heavy startup logic, this can increase Lambda costs by 10–50%. This single change made Go/Rust even more attractive economically.
2. ARM64 / Graviton: The Multiplier
ARM64 instances on Lambda cost ~20% less than x86 by default. Combined with Rust’s efficiency:
- 30% average cost reduction on arm64 vs x86
- Up to 42% savings for memory-heavy workloads
- Rust on arm64: ~4.5x faster than x86 for compute-intensive tasks (per TechRadar, 2025 benchmarks)
The recommendation from multiple teams is now: arm64 should be the default for all Lambda deployments, and Go/Rust maximize that advantage.
3. Real-World Cost Numbers
The most concrete public data point is a case study published in December 2025:
A microservice handling 2 million requests/day with API gateway functionality:
- Node.js/TypeScript: $847/month
- Go: reduced significantly (~$300–400 range reported)
- Rust: $214/month
— Stop Assuming Efficiency: A Real-World AWS Cost Study (Go vs Rust)
Extrapolated: at 100,000 requests, cost per run is approximately $0.03 with Rust vs $2.45 with TypeScript — roughly 80x cheaper at the per-request level.
Memory usage matters too: Rust typically uses 20-30% less memory than equivalent Go services, which directly affects Lambda pricing (billed per GB-second).
4. Go vs Rust: When Each Wins on Lambda
They’re not interchangeable for all scenarios:
| Scenario | Winner | Reason |
|---|---|---|
| Infrequently invoked functions | Rust | Lower cold start cost, now billed |
| Short-lived compute tasks | Rust | Sub-25ms init, minimal memory |
| High-throughput streaming / compute | Rust | No GC pauses at all |
| API gateway / routing / proxying | Go | ~equal perf, much faster to write |
| Data processing pipelines | Go | Great stdlib, easier concurrency |
| Very high memory (3GB+) | Go | GC overhead disappears at high memory |
| Team productivity | Go | Simpler language, faster iteration |
Go’s garbage collector does cause occasional latency spikes under heavy load — not catastrophic, but measurable at p99. Rust has zero GC pauses by design.
5. How People Are Structuring These Services
Pattern A: AWS Lambda + Custom Runtime (Rust)
Rust doesn’t have a managed Lambda runtime, so you compile a bootstrap binary and use provided.al2023:
# Cargo.toml
[dependencies]
lambda_runtime = "0.13"
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
use lambda_runtime::{service_fn, LambdaEvent, Error};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct Request { name: String }
#[derive(Serialize)]
struct Response { message: String }
async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> {
Ok(Response {
message: format!("Hello, {}!", event.payload.name),
})
}
#[tokio::main]
async fn main() -> Result<(), Error> {
lambda_runtime::run(service_fn(handler)).await
}
Build for Lambda’s ARM64 target:
cargo lambda build --release --arm64
cargo lambda deploy
The cargo-lambda tool (cargo-lambda.info) handles cross-compilation and deployment. Highly recommended.
Pattern B: AWS Lambda + Go (provided.al2023)
Go has official AWS SDK and Lambda runtime support:
package main
import (
"context"
"github.com/aws/aws-lambda-go/lambda"
)
type Request struct { Name string `json:"name"` }
type Response struct { Message string `json:"message"` }
func handler(ctx context.Context, req Request) (Response, error) {
return Response{Message: "Hello, " + req.Name + "!"}, nil
}
func main() {
lambda.Start(handler)
}
Build:
GOOS=linux GOARCH=arm64 go build -o bootstrap main.go
zip function.zip bootstrap
aws lambda update-function-code --function-name myFunc --zip-file fileb://function.zip
Pattern C: Containerized Services (Cloud Run / Fly.io)
For services that need persistent connections, long processing, or aren’t a good fit for function-per-endpoint architecture, containers on managed platforms are the alternative.
Google Cloud Run autoscales to zero (true serverless billing), handles HTTP routing, and accepts any container image. A Rust service with Axum or Actix-web fits well here:
FROM rust:1.80 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/myservice /usr/local/bin/
CMD ["myservice"]
Final image: typically 15-50MB for Rust (vs 500MB+ for Node.js). Cloud Run bills per CPU-second and memory-second — a 15MB Rust binary with 128MB RAM allocation costs a fraction of an equivalent Node app at 512MB.
Fly.io is popular for Go services — deploys globally across Fly’s edge network, scales to zero between requests, and has a generous free tier. The Go HTTP server starts fast enough that the “cold” container resume time isn’t painful.
6. Cloudflare Workers: Rust at the Edge
Cloudflare Workers runs JavaScript/WASM at the network edge in ~300 locations worldwide. Rust compiles to WASM and runs here with sub-10ms cold starts globally.
use worker::*;
#[event(fetch)]
async fn main(req: Request, env: Env, _ctx: Context) -> Result<Response> {
let name = req.path();
Response::ok(format!("Hello from the edge, {}!", name))
}
The honest picture: Rust/WASM in Workers is best for compute-heavy edge tasks — JWT validation, image processing, cryptography, data transformation. For simple routing or header manipulation, JavaScript is faster to write and performance-equivalent. The WASM memory model requires data copying between JS and WASM memory, which adds overhead for lightweight tasks.
Where it shines: computationally intensive work that previously would need a server round-trip can be handled at the edge node closest to the user, with near-zero latency and Cloudflare’s pricing model (100k free requests/day, $0.30/million after).
7. Web Framework Landscape
For teams building full HTTP services (not just Lambdas):
Rust:
| Framework | Focus | Notes |
|---|---|---|
| Axum | Modern, ergonomic | Built on Tokio; best DX; community favorite 2025 |
| Actix-web | Raw throughput | Slightly faster benchmarks; older design |
| Rocket | Ease of use | Good for beginners, less control |
Axum vs Actix-web is the main debate. Actix-web leads in raw throughput; Axum is within 5-10% but integrates more naturally with the async Rust ecosystem (same Tokio foundation). Most new projects choose Axum for its cleaner API.
Go:
| Framework | Focus | Notes |
|---|---|---|
net/http (stdlib) | Simplicity | Production-ready, no deps, idiomatic |
| Chi | Lightweight routing | Composable middleware, stdlib-compatible |
| Gin | Full-featured | Most popular, slightly opinionated |
| Echo | Performance | Similar to Gin, good for REST APIs |
| Fiber | Express-like | Fastest benchmarks, non-stdlib HTTP |
For Lambda and small services, Go’s net/http stdlib with no external framework is common and sensible. For larger APIs, Chi or Gin add routing ergonomics without much overhead.
8. The Graviton / ARM64 Strategy in Full
The combination of ARM64 hardware + Go or Rust is now a documented cost optimization strategy, not just a curiosity:
- Lambda ARM64: 20% cheaper per GB-second than x86, better performance per watt
- EC2 Graviton3: 40% better price/performance than comparable x86 instances for compiled workloads
- ECS/Fargate ARM64: Same discount applies to container workloads
- Go and Rust cross-compile trivially to ARM64 — a one-line change in the build
The TechRadar benchmark summary (2025): Rust on ARM64 delivers 4.5x the throughput of the same Rust code on x86 in some compute-bound Lambda scenarios, at 30% lower cost. The combination is described as “the optimal serverless configuration” for latency-sensitive workloads.
9. Adoption Signal
This is no longer experimental:
- AWS itself publishes guides on production Rust Lambda deployments
- Cloudflare’s own infrastructure is heavily Rust — Workers is partly eating its own cooking
- Shopify, Discord, Dropbox, Figma have all published Rust adoption case studies (not serverless-specific, but validates production readiness)
- QCon San Francisco 2024 featured a dedicated talk: “High-Performance Serverless with Rust” — now a recorded resource on InfoQ
- Multiple startups report Go as their default Lambda language since 2023-2024
The Go path is more mature and has more community resources for AWS specifically. Rust is catching up fast, driven largely by the Cargo Lambda tooling.
10. Billing Models Across Providers
Understanding how each platform charges is as important as the per-unit price — the billing model determines which workload profiles are cheap or expensive, regardless of language.
AWS Lambda
| Dimension | Detail |
|---|---|
| Per request | $0.20 per million (after 1M free/month) |
| Duration | $0.0000166667 per GB-second (arm64: ~20% cheaper) |
| INIT phase | Billed since August 2025 — cold start init time now counts |
| Minimum billing | 1ms increments |
| API Gateway | +$3.50/million HTTP API calls (often the bigger cost) |
The key gotcha: API Gateway costs frequently exceed Lambda compute costs at scale. A Lambda function that costs $50/month in compute might have $300/month in API Gateway charges. Teams working around this use Lambda Function URLs (no extra cost) or Application Load Balancer ($0.008/LCU-hour) as alternatives.
The 2025 INIT billing change hit hardest for infrequently-invoked functions with heavy startup — exactly where Node.js/Python are slow and Go/Rust win most. A Rust function initializing in 20ms vs a Python function taking 400ms on a cold start is now a real line item, not just a latency concern.
Go/Rust advantage here: Short init time + low memory allocation = lowest possible Lambda bill. A 128MB Rust Lambda at 10ms duration costs ~$0.21/million invocations total (compute + requests). The same Python function at 512MB and 200ms runs ~$16.90/million — 80x more expensive.
Google Cloud Run
| Dimension | Detail |
|---|---|
| CPU | $0.000024/vCPU-second (~$0.086/vCPU-hour) |
| Memory | $0.0000025/GiB-second (~$0.009/GiB-hour) |
| Requests | $0.40 per million (after 2M free/month) |
| Minimum billing | 100ms increments |
| Idle | Not billed when scaled to zero |
| Concurrency | Up to 1000 concurrent requests per instance |
Cloud Run’s billing model is fundamentally different from Lambda: you pay for a container instance while it’s processing requests, but a single instance handles many concurrent requests. This makes it dramatically cheaper than Lambda for sustained traffic, but comparable or more expensive for sporadic invocations.
The high concurrency limit (1000 req/container) strongly favors Go and Rust — both handle concurrent requests efficiently without spawning threads per request. A Go service with goroutines or a Rust service with Tokio can saturate that concurrency limit with very low CPU and memory usage. A Node.js service would struggle to serve 1000 concurrent requests from a single 256MB container.
Go/Rust advantage here: Smaller container images (15-50MB vs 500MB+ for Node) = faster cold starts from zero. Lower memory per request = pack more concurrency per instance = fewer instances = lower bill.
Cloudflare Workers
| Dimension | Detail |
|---|---|
| Free tier | 100,000 requests/day, 10ms CPU/request |
| Paid (Workers Paid) | $5/month flat, then $0.30/million requests |
| CPU billing | Per CPU-millisecond — not wall-clock time |
| Waiting on I/O | Free — you don’t pay while waiting for fetch/DB |
| KV / Durable Objects | Separate pricing |
| Egress | No egress fees for most Worker traffic |
The CPU-time billing model is the critical differentiator. On Lambda, if your function waits 200ms for a database call, you’re billed for those 200ms. On Workers, you pay only for actual CPU work. For I/O-heavy services (most web APIs), this can be 5-10x cheaper than Lambda at equivalent request volumes.
Real-world case: an analytics ingestion pipeline moved from Lambda to Workers and saved $50k/year — the workload was predominantly I/O (receiving events, writing to storage) with minimal CPU, which Lambda bills fully but Workers bills almost nothing for.
The limitation: 10ms CPU time limit on the free tier, 30 seconds on paid (wall-clock). CPU-bound tasks (image processing, crypto, parsing) hit this ceiling. That’s where Rust/WASM earns its place — it fits more computation into the CPU budget than JavaScript would.
Go/Rust advantage here: Go doesn’t run on Workers (no WASM support yet in Workers’ Go runtime). Rust/WASM is the play. For compute-heavy tasks, Rust squeezes more work into the CPU time limit, making previously-impossible edge computation feasible within budget.
Fly.io
| Dimension | Detail |
|---|---|
| Compute | From $0.0000008/vCPU-second (~$1.94/vCPU-month) |
| Memory | $0.0000096/GB-second (~$1.94/GB-month) |
| Idle (machines) | Billed unless scaled to zero (opt-in) |
| Egress | $0.02/GB after 160GB/month free |
| Regions | ~35 global regions, automatic routing |
Fly.io is closer to a traditional VPS with fast global deployment than a pure serverless platform. You pay for machine uptime unless you configure scale-to-zero. The value proposition is global proximity — your Go or Rust service runs in the region closest to each user, with the simplicity of fly deploy.
For small services with predictable traffic, the monthly fixed cost is often less than Lambda’s per-invocation costs. For completely sporadic traffic (occasional jobs, webhooks), Lambda or Cloud Run’s true pay-per-use wins.
Side-by-Side: Which Billing Model Fits Which Workload
| Workload Pattern | Best Platform | Why |
|---|---|---|
| Sporadic invocations, low traffic | Lambda | True per-invocation billing |
| High-volume, I/O-heavy API | Cloudflare Workers | CPU-only billing, no idle cost |
| Sustained traffic, concurrent requests | Cloud Run | Per-instance billing + high concurrency |
| Global latency-sensitive, edge logic | Cloudflare Workers | 300 PoPs, ~5ms to any user |
| Full app, predictable traffic | Fly.io | Simplicity + global + flat monthly |
| Compute-intensive bursts | Lambda ARM64 | Scales to zero, scales to infinity |
The language choice compounds with the billing model:
- Rust on Lambda: wins on compute-intensive sporadic workloads (cold start cost now billed, small memory = low GB-seconds)
- Go on Cloud Run: wins on sustained API traffic (goroutines handle high concurrency per instance efficiently)
- Rust/WASM on Workers: wins on CPU-heavy edge logic that previously needed a server round-trip
- Go on Fly.io: wins for simple always-on services where developer experience and global distribution matter more than pure cost optimization
Conclusion
The case for Go/Rust in serverless is now well-supported by real numbers:
- Cold starts: 5-8x faster than Node/Python, now directly billable
- Memory: 20-50% lower, directly reduces Lambda costs
- Throughput: Rust handles 60k+ req/s, Go 40k+ req/s in microservice benchmarks
- Real-world cost: 70-80% cost reduction vs TypeScript equivalents reported
Decision framework:
- Highest cost pressure + compute-intensive + team can invest in Rust → Rust on Lambda ARM64
- Cost-sensitive + team wants productivity + async workloads → Go on Lambda ARM64
- Global edge latency is the constraint → Cloudflare Workers + Rust/WASM (compute tasks) or Workers + JS (simple tasks)
- Persistent service + autoscale-to-zero → Cloud Run or Fly.io with either language, smallest possible container image
The biggest remaining barrier isn’t performance or cost — it’s team familiarity. Go has a gentle enough learning curve that it’s increasingly being adopted as a “primary Lambda language” by Node.js teams. Rust requires more investment but the payoff is proportionally larger for high-traffic services.
References
- lambda-perf — Live Lambda Cold Start Benchmarks
- AWS Lambda Cold Starts in 2025: When They Matter and What They Cost
- Arm64 crushes x86 in 2025 AWS Lambda benchmarks — TechRadar
- Comparing AWS Lambda Arm64 vs x86_64 Performance Across Multiple Runtimes in Late 2025
- Stop Assuming Efficiency: A Real-World AWS Cost Study (Go vs Rust)
- Go vs Rust on AWS: We Measured Cost per Request
- High-Performance Serverless with Rust — InfoQ/QCon
- Optimizing Compute-Intensive Serverless Workloads with Multi-threaded Rust — AWS Blog
- Serverless Rust on Cloudflare Workers — Cloudflare Blog
- Why You Should Consider Rust for Your Lambdas
- Benchmarking AWS Lambda with Node.js, Go, and Rust
- cargo-lambda — Build and deploy Rust Lambdas
- Axum vs Actix Web: 2025 Rust Web Framework War
- Deploying Rust to Google Cloud Run
- Cloudflare Workers vs AWS Lambda Cost Comparison — Vantage
- Serverless Showdown: Workers vs Lambda vs Cloud Functions vs Azure Functions
- From AWS Lambda to Cloudflare Workers: $50K Annual Savings
- Google Cloud Run Pricing — Official Docs
- Google Cloud Run Pricing and Cost Optimization — ProsperOps