Cameleeringsimoom

simoom / Use cases / Serverless

Serverless and scale to zero

An HTTP layer that isn't your cold start

A function that scales to zero pays for its start-up on every cold request, and pays for its memory every second it runs. In benchmark campaign 4 (2026-11-12), simoom's default build gave its first answer 0.94 ms after the process started, the fastest of 21 servers, and sat at 901 KB of memory at rest, so the time and the memory go to your code.

0.94 msfrom process start to the first answer, default build; first of 21 servers, hyper 1.48 ms
1.49 msthe same for the full server with TLS 1.3 and HTTP/3; level with hyper
901 KBmemory at rest (PSS), default build; full server 1,844 KB
215 KBadded to the binary for HTTP/1.1 only

Start-up, measured

Cold start is the time from spawning the process to the first successful answer on its port. In campaign 4 every server ran on the same DigitalOcean c-4 droplet as simoom, in the same round.

serverstart-up to first answermemory at rest (PSS)program size, stripped
simoom, default build (HTTP/1.1, HTTP/2, WebSocket)0.94 ms901 KB735 KB
simoom, full server (also TLS 1.3 and HTTP/3)1.49 ms1,844 KB1,550 KB
hyper1.48 ms1,374 KB2,069 KB
axum1.56 ms1,518 KB2,246 KB
actix-web1.81 ms1,885 KB2,450 KB
Go net/http3.74 ms8,088 KB6,180 KB
may-minihttp8.03 ms9,061 KB515 KB
nginx19.57 ms72,469 KB1,283 KB
Kestrel (.NET)366.56 ms70,559 KBnot a single executable
Netty (Java)467.01 ms74,067 KBnot a single executable

Campaign 4, 2026-11-12, a selection of the 21 servers; the median of the 20 others started 6.4x slower than simoom's default build. Program size is shown only for self-contained executables. With HTTP/3 on, simoom starts every event loop at once instead of one, part of why the full server starts later than the default build. The platform's own sandbox start comes on top for every runtime. All servers: start-up, memory at rest. On a workstation, against the server it replaced, see Cameleer's old server.

Why it starts fast

Less to set up

  • No async runtime to build before the first request.
  • Lazy loops: start returns with one loop running; the others start in the background once that loop gets busy.
  • The descriptor table is grown once at start, not while threads run.
  • A P-256 key's signing table is built on the first signature, not at load.

Less to carry

  • An HTTP/1.1-only build adds 215 KB; the full server with HTTP/3 adds 935 KB.
  • Nothing from crates.io, so nothing extra to download, compile or ship.
  • One event loop per CPU core, so a small function with one vCPU runs one loop.

The start-up work behind these numbers is described in runtime. Build options: features and size.

A function's HTTP server

Container platforms such as Cloud Run send requests to a port; listen on it and answer. A graceful stop tells clients to finish when the platform retires the instance.

use simoom::{Backend, Reply, Request, Server};
use std::time::Duration;

let server = Server::builder()
    .listen("0.0.0.0:8080")
    .threads(2)               // 0 = one loop per core (the default)
    .backend(Backend::IoUring) // Linux 6.1+, falls back to epoll
    .service(|_: &mut Request<'_>, r: Reply<'_>| r.body_static(b"ok"))
    .start()
    .unwrap();
// ...
server.stop(Duration::from_secs(5)); // tells clients to finish, then waits up to 5 s
server.join();

simoom serves HTTP on a socket. On AWS Lambda that means a container image or an HTTP adapter in front of the port: simoom does not speak the Lambda Runtime API itself. Cameleer, which uses simoom, is its own Lambda runtime: see Cameleer on AWS Lambda.

Common questions

What is the smallest Rust web server for AWS Lambda or other serverless platforms?

An HTTP/1.1-only simoom build adds about 215 KB to a binary. In benchmark campaign 4 (2026-11-12), simoom's default build (HTTP/1.1, HTTP/2, WebSocket) gave its first answer 0.94 ms after the process started, the fastest of 21 servers (hyper: 1.48 ms), and used 901 KB of memory at rest. For the smallest build, turn off the default features and keep http1.

Does simoom speak the AWS Lambda Runtime API?

No. simoom serves HTTP on a socket, which suits container platforms such as Cloud Run directly. On Lambda it runs behind an adapter or in a container image. Cameleer, which uses simoom as its HTTP engine, is its own Lambda runtime.

How fast is the cold start with TLS?

In benchmark campaign 4 (2026-11-12), simoom's full server, with TLS 1.3 and HTTP/3 built in, gave its first answer 1.49 ms after the process started: level with hyper (1.48 ms) on the same droplet, and ahead of axum with rustls (1.91 ms). With HTTP/3 on, simoom starts every event loop at once; the default build starts one loop and adds the others when it gets busy.

Do I need tokio for a serverless HTTP handler in Rust?

No. simoom has no async runtime. A service is a plain function; slow work goes to a bounded offload pool or to your own threads.

How much memory does an idle simoom server use?

In benchmark campaign 4 (2026-11-12), the default build's process used 901 KB of PSS at rest, and the full server with TLS 1.3 and HTTP/3 used 1,844 KB. On the same droplets hyper used 1,374 KB and axum 1,518 KB, less than simoom's full server, and nginx 72,469 KB.

Measure it yourself

Build the hello example in release mode and time the first answer on your platform.

cargo add simoom
cargo run --release -p simoom --example hello -- 127.0.0.1:8080   # from a checkout of the repository