The best self-hosted FaaS platforms in 2026
"Self-hosted serverless" is a phrase that has to fight itself. The pitch of serverless was that somebody else owns the machines, the patching, the capacity planning, and the pager. Run it yourself and you haven't eliminated the servers — you've adopted them and taken responsibility for their upbringing. What you get back is real: functions run on hardware you control, in regions you choose, with no per-invocation bill. That trade is worth making. It's just worth making with your eyes open.
This is the field guide I wish existed when people ask which open-source FaaS to run. It covers the platforms worth evaluating, then gets to the part most roundups skip: nearly all of them run functions as containers on a shared host kernel, which is fine right up until the code stops being yours. For hosted platforms see /blog/best-serverless-function-platforms-2026; for self-hosted sandboxes rather than function runtimes, /blog/best-self-hosted-code-sandboxes-2026. This post is the intersection those two miss.
Why run FaaS on your own infrastructure
Self-hosting a function platform is a standing operational commitment, so name the reason out loud first. There are four honest ones, and if none describes you, a hosted platform is less work.
- Cost at steady volume — per-invocation pricing is a bargain at low volume and a line item at high, predictable volume. Owning capacity can beat renting each call, but check the spreadsheet.
- Data residency — functions and everything they touch run on machines you operate, in jurisdictions you chose. For regulated workloads this is often the only reason that matters.
- Air-gapped or on-prem delivery — if you ship into environments with no outbound internet, hosted FaaS isn't a candidate at any price. Only a bundleable runtime works.
- Avoiding lock-in — a function platform ends up owning your trigger model, deploy pipeline, and handler signature. Some teams want that surface forkable rather than rented.
The counterweight: you now operate a control plane, and usually a Kubernetes cluster underneath it, forever. That cost is recurring and the thing teams under-budget most. We'll come back to it.
What actually separates them
Every platform here will accept a Python handler and return a response over HTTP. That baseline tells you nothing. Six things decide fit, and the ranking inverts depending on which one is forcing your hand:
- Substrate — Kubernetes required, or will it run on a single host? The biggest fork in the road, and mostly a question about your team.
- Isolation model — container on a shared kernel, or something stronger. Decisive if your functions are ever written by someone else.
- Cold-start strategy — pre-warmed pools, keep-alive replicas, or scale-to-zero with a cold path. Every option trades idle memory for latency.
- Trigger model — HTTP-first, or a real event substrate. The two diverge once you need retries, dead-lettering, and ordering.
- Operational surface — how many components you're on the hook for, and what degrades when one is down.
- Project health and licensing — which features sit in the open-source edition versus a commercial one, and how active recent releases are.
The field, project by project
Qualitative only, from each project's own docs — a confident wrong number is worse than none.
OpenFaaS
OpenFaaS is the approachable one, and has been for long enough that it's the default answer when someone says "open-source Lambda." The model is easy to hold in your head: a function is a container image, a small supervisor called the watchdog sits in front of your handler and turns HTTP requests into invocations, and templates give you a per-language starting point so you write a handler rather than a Dockerfile. The CLI loop is genuinely good, and the ecosystem around it — UI, metrics, autoscaling, an async queue — is more complete than most projects here.
One thing to check carefully: OpenFaaS has an open-source edition and a commercial edition, and the boundary has moved over the project's life. Features people assume are included — scaling, multi-tenancy, event connectors, enterprise operations — may sit on the commercial side depending on when you last looked. That's a legitimate business model, not a criticism — but verify it against current docs, because "we'll use OpenFaaS, it's open source" has surprised people at procurement time.
# Scaffold a Python handler from a template, then build and deploy it.
faas-cli template store pull python3-http
faas-cli new resize-image --lang python3-http
# Edit resize-image/handler.py, then:
faas-cli up -f resize-image.yml --gateway http://127.0.0.1:8080
# Invoke it like any HTTP endpoint.
curl -sSL --data-binary @in.png \
http://127.0.0.1:8080/function/resize-image > out.png
# Async path: the gateway enqueues and returns immediately.
curl -X POST --data-binary @in.png \
http://127.0.0.1:8080/async-function/resize-imagefaasd
faasd is OpenFaaS with the Kubernetes removed: same gateway, same function-image model, same CLI, on containerd on one machine. I want to be unfashionably enthusiastic here, because it's the option most teams should consider first and the one they skip fastest. An enormous number of "we need a serverless platform" requirements are met by one adequately-sized VM running a dozen functions and a queue — which isn't incrementally simpler than a cluster, it's the difference between a service you restart occasionally and a platform you staff. The limits follow: no cluster-level HA, and you scale the box until you can't.
Knative (Serving and Eventing)
Knative is less a product than the substrate a large share of "serverless on Kubernetes" is built on, including several managed cloud offerings. Serving handles the request-driven half — a revision model that versions each deploy, traffic splitting, request-driven autoscaling, scale-to-zero on idle. Eventing handles the rest with brokers, triggers, and sources: a CloudEvents routing layer more thought-through than the ad-hoc triggers elsewhere here.
What you're signing up for is the reality underneath. Knative is Kubernetes plus a networking layer, and that layer is a component you now own — its upgrades, its failure modes, its interaction with your ingress. It also gives you a container-and-a-port model rather than handler-and-a-template, so OpenFaaS-style conveniences are yours to add. Maximum composability, minimum hand-holding.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: resize-image
namespace: functions
spec:
template:
metadata:
annotations:
# Scale to zero when idle, or keep one warm if you'd rather
# pay memory than pay the cold path.
autoscaling.knative.dev/min-scale: "0"
autoscaling.knative.dev/max-scale: "20"
autoscaling.knative.dev/target: "10"
spec:
containerConcurrency: 10
timeoutSeconds: 300
containers:
- image: registry.internal/resize-image:1.4.0
ports:
- containerPort: 8080
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
memory: 512MiFission
Fission is a Kubernetes-native FaaS whose defining decision is a pool of pre-warmed, generic runtime containers waiting for a function to be injected into them. Rather than starting a container per cold invocation, it keeps warm pods around and specializes one on demand — the clearest expression of the trade everyone here makes implicitly. The developer model is function-shaped rather than image-shaped: you deploy source plus an environment, which many teams prefer and some find constraining.
Nuclio
Nuclio comes at FaaS from the data-processing side rather than the web-request side, and it shows: stream and message-queue sources as first-class citizens, parallelism inside a single replica, and a focus on ML and data-pipeline workloads rather than "replace my API endpoints." If your functions consume a stream, run inference, or transform records at volume, its shape fits better than a general-purpose HTTP-first platform. The corollary is a heavier, more opinionated system — if your need is twelve webhook handlers, that's more platform than the problem deserves.
Apache OpenWhisk
OpenWhisk is the mature, foundation-governed option: an Apache project with a long production history, multi-runtime support, a well-defined action/trigger/rule/sequence model, and the distinction of having backed a major cloud's commercial function service. Sequences and compositions build workflows from small actions instead of hand-rolled orchestration inside handlers, and vendor-neutral governance matters if lock-in avoidance is why you're here. It's also the most operationally involved system here, with more moving parts across its controller, invoker, and data tiers.
Fn Project, Kubeless-style projects, and the long tail
There's a long tail: Fn Project, the Kubeless-style "functions as Kubernetes custom resources" approach, and smaller runtimes that keep appearing on comparison lists. Some are actively developed, some have slowed, some are archived — and I'm deliberately not saying which is which, because that changes, and a confident wrong claim is how a team ends up building on something that stopped shipping two years ago. Do this instead, for every project here including the famous ones: open the repository, check the most recent release date, whether issues get responses, and whether the docs match the current API. A quiet project isn't automatically dead — some are simply finished — but know which one you're adopting.
The isolation question nobody puts in the comparison table
Here's the cross-cutting fact that matters more than any feature checkbox: nearly every platform above runs functions as containers. The boundary is Linux namespaces and cgroups, with every function on a host sharing one kernel. A container is a resource boundary that happens to be useful for security, not a security boundary that happens to manage resources. The full syscall interface is exposed, and a kernel-level escape is a host compromise — on a multi-tenant host, of everything else scheduled there.
For most deployments that's completely fine, and I'd rather say so plainly than fear-sell. If functions are written by your own engineers and deployed from your own CI, a container is an appropriate boundary. The problem is the trajectory. Almost every FaaS-on-your-own-infra project I've watched starts at "our code" and ends at "our customers' code" — a plugin system, a customer-authored webhook transform, an LLM writing the handler body. Nobody reopens the isolation decision on the day that happens, because it happens one feature at a time.
Cold starts, and the memory you spend to avoid them
Every platform here has a cold-start story, and every one is the same trade in different clothes: keep something running so the first request doesn't wait. Fission's pre-warmed pools do it explicitly. Knative does it with minimum-scale settings that stop a revision reaching zero. OpenFaaS does it with keep-alive replicas. The names differ; the physics don't. You buy latency with idle memory.
That sets an uncomfortable floor under self-hosted economics. Scale-to-zero is the feature everyone wants, but a platform that genuinely reaches zero pays a cold path on the next request, so teams set a warm floor — capacity you pay for whether traffic arrives or not. Self-hosted, that lands on your capacity plan rather than a vendor's: the whole point, and also the part left out of the cost model that justified it.
The operational bill nobody budgets
You did not eliminate the servers. You're now running a control plane, and unless you chose faasd, Kubernetes underneath it. Concretely, somebody owns:
- The cluster — upgrades, node lifecycle, capacity, and the networking layer your platform sits on.
- The function control plane — version skew against the cluster, its CRDs, its gateway, and its autoscaler under traffic you didn't test.
- The image pipeline — a registry, a patch cadence, and a plan for the day a CVE lands in a runtime forty functions share.
- Observability — logs, metrics, and traces that survive a pod which lived 200 milliseconds. Harder than for long-lived services, and discovered late.
- Queue and event infrastructure — async invocation means a message broker, and it's now yours.
- The pager — a hosted outage is an incident you communicate about. A self-hosted one is an incident you fix, at whatever hour it starts.
None of this argues against self-hosting; it argues for costing it honestly. The comparison usually made is "vendor invoice versus hardware." The true one is "vendor invoice versus hardware plus a slice of an engineer, permanently." If your driver is residency or air-gap you pay that regardless. If it was cost, redo the number with the engineer in it.
Where a microVM approach fits
If the isolation question is the one biting you — customer-authored functions, LLM-generated handlers, a plugin marketplace, a compliance requirement a shared kernel doesn't meet — the alternative is to give each execution its own kernel. A Firecracker microVM is a hardware-virtualized guest with a minimal device model behind a privilege-dropping jailer: the boundary is KVM rather than namespaces, and the trusted surface is a small, well-audited VMM rather than the full syscall interface. The old objection was that VMs boot too slowly to sit in front of an invocation. Snapshot-restore changed that.
PandaStack is our take on it, and since these are our own measurements I'll be specific: a create is a snapshot restore, landing around 179ms p50 and 203ms p99, with the restore step near 49ms. There's no warm pool of idle VMs behind that number, which is what makes per-invocation VM isolation practical rather than theoretical. The only slow path is the first-ever spawn of a new template, which cold-boots in roughly 3 seconds and bakes the snapshot for everything after. Copy-on-write forking runs 400–750ms same-host and 1.2–3.5s cross-host, and per-sandbox networking comes from 16,384 pre-allocated /30 subnets per agent.
from pandastack import Sandbox
# Each invocation gets its own Firecracker guest kernel.
# ~179ms p50 to create, because it's a snapshot restore, not a boot.
sbx = Sandbox.create(template="base", ttl_seconds=300)
# Drop in the handler body - yours, your customer's, or an LLM's.
sbx.filesystem.write("/tmp/handler.py", handler_source)
result = sbx.exec("python /tmp/handler.py")
print(result.stdout, result.exit_code)
sbx.destroy() # or let the TTL reap it
# Warm once, fork per request when setup is expensive:
base = Sandbox.create(template="base", ttl_seconds=3600)
base.exec("pip install -r /app/requirements.txt")
base.snapshot()
worker = base.fork() # 400-750ms same-host, copy-on-write
worker.exec("python /app/job.py")
worker.destroy()Now the part I'd want a competitor to state about their own product: PandaStack is a hosted platform with an open-source agent, which is a genuinely different trade from a fully self-hosted control plane. If you're here for air-gapped delivery, or a requirement that no control plane you don't operate sits in the loop, that isn't what we are — OpenFaaS, faasd, or Knative is your answer. If you're here because of the isolation gap and would rather not build a Firecracker orchestration layer yourself, we're worth benchmarking. We are not a drop-in self-hosted OpenFaaS replacement.
The field at a glance
Scan-and-shortlist form. Qualitative on purpose — verify substrate requirements, edition boundaries, and maintenance status against each project's own repository before deciding.
- OpenFaaS — Runs on: Kubernetes, or one host via faasd. Isolation: container, shared host kernel. Best for: the friendliest template-and-CLI experience, after checking which features are open-source versus commercial.
- faasd — Runs on: a single host, containerd, no Kubernetes. Isolation: container, shared host kernel. Best for: deployments where one machine is enough and not running a cluster is the point.
- Knative — Runs on: Kubernetes plus a networking layer. Isolation: container, shared host kernel. Best for: the strongest primitives — revisions, traffic splitting, CloudEvents routing — if you have cluster expertise.
- Fission — Runs on: Kubernetes. Isolation: container, shared host kernel. Best for: latency-sensitive work where cold starts drive the decision and pre-warmed pools are worth the idle memory.
- Nuclio — Runs on: Kubernetes. Isolation: container, shared host kernel. Best for: high-throughput data and ML event processing, not general-purpose HTTP endpoints.
- Apache OpenWhisk — Runs on: Kubernetes or its own topology. Isolation: container, shared host kernel. Best for: teams valuing foundation governance and multi-runtime maturity enough to carry the footprint.
- Fn Project / Kubeless-style projects — Runs on: varies. Isolation: container, shared host kernel. Best for: niches where one already fits your stack — check recent release activity first.
- PandaStack — Runs on: hosted platform, open-source per-host agent. Isolation: Firecracker microVM, own guest kernel per execution, ~179ms p50 create. Best for: untrusted or customer-authored code; a poor fit if you need a self-hosted control plane.
How to choose
Four questions, in this order. The first two eliminate most of the list before you read a single feature comparison.
- Single host or cluster? If one machine holds your workload, faasd is the honest first answer and you should have a specific reason to reject it. If you need HA and scale-out, the field narrows to the cluster-native options.
- Trusted or untrusted code? If every function is written and reviewed by your own team, a container boundary is appropriate. If they come from customers, plugins, or a model, decide explicitly — and if a shared kernel isn't acceptable, you need a microVM.
- Event-driven or HTTP? Request/response is well served by almost everything here. Stream and pipeline workloads should look hard at Knative Eventing or Nuclio first.
- Do you already run Kubernetes, and who owns it? With real cluster expertise, Knative's power is cheap at the margin. If you'd stand up a cluster specifically to run functions, price that separately — it's usually larger than the platform itself.
Then do the thing that settles it faster than any reading: pick your top two, spend a day on each, and deploy a real function — one with awkward native dependencies, not a hello-world. Watch a cold path after genuine idle. Find the logs of an invocation that already finished.
The bottom line
There's no best self-hosted FaaS platform — there's a best one for your substrate, your trust model, and your team. If one host is enough, faasd deserves a try before you build a cluster. If you need the strongest primitives and already run Kubernetes well, Knative is what much of this industry quietly stands on. If cold starts are the constraint, Fission attacks them directly. If you process streams at volume, Nuclio was designed for it. If governance matters most, OpenWhisk has it and asks for operational weight in return. And if the functions aren't yours, none of the container-based options give you a strong enough boundary — a per-execution microVM is the honest answer, on raw Firecracker or something like ours. Verify every claim here against the project's own repo, and remember: you didn't get rid of the servers. You moved in with them.
Frequently asked questions
What is the best self-hosted FaaS platform in 2026?
There's no universal winner — your substrate and trust model decide it. If a single host is enough, faasd gives you the OpenFaaS experience on containerd with no Kubernetes, and it's the most under-considered option in the category. If you need a cluster: OpenFaaS has the friendliest developer experience, Knative has the strongest primitives at the cost of operating Kubernetes plus a networking layer, Fission attacks cold starts with pre-warmed pools, Nuclio targets high-throughput data and ML event processing, and Apache OpenWhisk offers foundation governance and multi-runtime maturity with a heavier footprint. Shortlist two, deploy a real function on each for a day, and decide from that rather than from a table.
Is running functions in containers secure enough for untrusted code?
It depends entirely on who wrote the code. Nearly every open-source FaaS runs functions as containers, so the boundary is Linux namespaces and cgroups with every function on a host sharing one kernel — the full syscall interface is exposed, and a kernel-level escape is a host compromise. When the functions come from your own engineers and your own CI, that's an appropriate boundary. When they're written by customers, supplied as plugins, or generated by a model, the risk is materially different: a container is a resource boundary useful for security, not a security boundary. The trap is drift — platforms start with "our code" and add customer-authored functions one feature at a time, without anyone reopening the isolation decision.
What's the difference between OpenFaaS and Knative?
They sit at different layers. OpenFaaS is a function platform with an opinionated developer experience: language templates, a watchdog that turns HTTP requests into handler invocations, a CLI that scaffolds and deploys, a UI, and an async queue path. Knative is closer to a building block — Serving gives you revisions, traffic splitting, request-driven autoscaling and scale-to-zero, while Eventing provides CloudEvents broker/trigger routing, and many managed "serverless on Kubernetes" products are built on it. Knative's model is container-and-a-port rather than handler-and-a-template, so developer conveniences are yours to add, and it requires operating a networking layer alongside Kubernetes. Check the current open-source versus commercial boundary on the OpenFaaS side before assuming a feature is included.
Do I need Kubernetes to run a self-hosted serverless platform?
No, and establishing this first saves the most time. faasd runs the OpenFaaS gateway and function model directly on containerd on one machine, with the same CLI and the same function images, and no cluster at all. For internal tooling, webhook handlers, scheduled jobs, and plenty of small-to-medium production workloads that's genuinely sufficient — and the gap between one host and a Kubernetes cluster isn't incremental, it's the difference between a service you restart occasionally and a platform you staff. The limits are real: no cluster-level high availability, and you scale by making the box bigger until you can't. Knative, Fission, and Nuclio are Kubernetes-native and don't offer that escape hatch.
How do self-hosted FaaS platforms handle cold starts?
All of them make the same trade in different packaging: keep something running so the first request doesn't wait. Fission maintains pre-warmed generic runtime pods and specializes one on demand. Knative exposes minimum-scale settings that prevent a revision from reaching zero. OpenFaaS uses keep-alive replicas. The physics are identical — you buy latency with idle memory. That warm floor is the part most self-hosting cost models omit: scale-to-zero is the headline, but teams set a floor in practice, and that floor is capacity you pay for regardless of traffic. A microVM approach changes the shape of the trade by making the create itself a snapshot restore — PandaStack's runs about 179ms p50, with no warm pool behind it.
Keep reading
- The best serverless function platforms in 2026 — the hosted side of this comparison
- Best self-hosted code execution sandboxes in 2026 — if you want a sandbox rather than a function runtime
- Firecracker vs Docker: the isolation ladder
- Running user-defined functions in microVMs
49ms p50 cold start. Fork, snapshot, and scale to zero.