Commercial FaaS is excellent until the bill, the region, or the runtime is not yours. ServerlessFlow is a self-hosted function platform: OpenWhisk for orchestration, Docker for isolation, a pool of already-started containers so the common path is reuse rather than boot.
Before and after
| Metric | Cold path (no pool) | Warm reuse path |
|---|---|---|
| Wall time to handler | 800ms–1.2s | <200ms (published runs) |
| Pool hit rate | 0% | ~85% under measured load |
| Operator visibility | "feels slow" | spawn + hit rate on Grafana |
Those numbers are from our dashboard, not a benchmark blog post. Your images and import graph will differ.
The latency that actually matters
"Cold start" is a slogan. The bill is container create, runtime init, and loading your code. Function CPU time is rarely the first problem.
We keep a warm pool sized from recent concurrency, not from hope. The scheduler prefers an idle warm container over a new one. When traffic falls, the pool shrinks so you are not paying to heat empty rooms.
Isolation and honesty
cgroup limits stop one noisy function from eating the node. Prometheus makes pool hit rate and spawn time visible, which is the only way a "sub-200ms" claim stays true after the demo.
I would not tell a team to rebuild Lambda for a CRUD app. I would tell them to measure spawn time before they declare serverless "too slow," and to treat pool hit rate as a product metric if they insist on running their own.
See also: cold start is a pool-sizing problem and write workers you can replay.