faas-netes: the OpenFaaS Kubernetes provider that is source available rather than open source
Serverless Functions For Kubernetes
At a glance
- What is it?
- The Kubernetes provider behind OpenFaaS is MIT-shaped in structure but EULA-labelled in its own Dockerfile, and the free tier is pinned to the operating mode the project plans to delete.
- Who is it for?
- faas-netes is a well-built Kubernetes provider with an unusually candid README, and the candour cuts both ways. The project tells you plainly that the controller mode you get in the Community Edition is legacy, unsupported for new customers, and scheduled for removal, which means the free tier is the tier you are meant to leave.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 45 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The license terms are stated three times and none of them say open source
The most important paragraph in this README is a block quote near the top, and it is not about Kubernetes. It says OpenFaaS Community Edition is licensed for individual exploration and hobbyist use, that a 60 day limit applies for commercial proof of concepts, and that commercial and production workloads require OpenFaaS Standard or OpenFaaS for Enterprises. Later, under Highlights, the same terms are restated: free for personal and non-commercial use, commercial use limited to 60 days, then you must buy a license.
Now set that against the word open source, which appears a few paragraphs further down under Community: an independent open-source project with over 300 contributors, with a commercial option available. Both statements are in the same document. The code is public, the history is public, and the contributor count is real, but the grant is not an OSI one. GitHub's license field for the repository reads NOASSERTION rather than MIT or Apache-2.0, and the shipped image is labelled directly in the Dockerfile as `org.label-schema.license="OpenFaaS CE EULA - non-commercial"`. A LICENSE file does exist in the tree, but the image metadata is the unambiguous statement of intent from the build itself.
The practical consequence is that you can read every line, contribute patches and run the thing on your laptop indefinitely, and you still cannot put it in front of paying customers after day 60 without a license. If your procurement process asks for an SPDX identifier, NOASSERTION is going to be a difficult conversation, and the fix is to talk to the vendor rather than to interpret the README charitably.
Scale to zero appears in both the free list and the paid list
Under Highlights, the free and general capability list, scale to and from zero is listed as a platform feature alongside the built-in UI portal and native Kubernetes integrations. Under Commercial options, further down the same README, the first bullet reads scale to zero and horizontal scaling, with the specifics spelled out as capacity, requests per second, CPU, memory and custom rules.
Both are accurate about what OpenFaaS does and neither can be true about what the Community Edition does. The plain reading is that a function can scale to zero as part of the platform, while the policy engine that decides when a function is allowed to go to zero, and the configuration surface for capacity and custom rules, are what the commercial tiers sell. Scale from zero, meaning a cold start that the platform handles without your involvement, sits in the free column; scale to zero on your terms sits in the paid one.
This is the kind of ambiguity that only bites after deployment, when a finance team asks why an idle function is still holding memory. The `maintainMinimumReplicas` chart value added in release 0.18.16 is a hint at how fine-grained the paid control is, since a value that exists to stop the autoscaler going all the way down is a value the free edition does not expose in a meaningful way. Read both lists before writing a capacity model, and treat the pricing page as the authority rather than the README.
Community Edition ships only the mode the project plans to delete
The README describes two operating modes in a section titled controller or operator. The operator mode, where functions are managed as Kubernetes Custom Resources, is described as the one supported for production. The controller mode is called legacy, is stated to be removed in a future release, and comes with a line that says in plain words that the maintainers cannot support new customers who use it and that it may not have feature parity.
The next line is the one to sit with: the controller mode is the only option for OpenFaaS Community Edition. Those two paragraphs together mean the free edition is locked to the deprecated path, on an explicit timetable, with no supported upgrade available inside the free tier. The migration route the project points to is a blog post about upgrading to the Function Custom Resource Definition, and the operator mode itself is linked from Highlights as available with OpenFaaS Pro.
There is a second layer here. The Highlights list also places Role Based Access Control and single sign-on, OIDC integration and commercial add-on connectors, alongside affinity and advanced scheduling constraints, in the commercial bucket, while the free bucket offers a built-in UI portal and custom routes. Multi-tenant function hosting appears only in the paid list. So the free tier is a single tenant, no RBAC, no SSO, legacy control path install. That is a coherent product decision, but it is not what a reader skimming the Highlights section would conclude.
The configuration table reinforces the split without naming it. Values like `faasnetes.resources`, `operator.resources`, `queueWorker.resources` and `basicAuthPlugin.resources` appear together, yet the operator and basic auth components are the ones tied to the paid mode, so a Community Edition deployment finds empty or inert settings for several rows of that table.
The container build runs the test suite and a copyright check before it produces a binary
The Dockerfile is unusually honest about what a build enforces. Three commands sit between copying the source and compiling, and each one can fail the image build:
RUN license-check -path /go/src/github.com/openfaas/faas-netes/ --verbose=false "Alex Ellis" "OpenFaaS Author(s)"
RUN gofmt -l -d $(find . -type f -name '*.go' -not -path "./vendor/*")
RUN CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} go test -v ./...The middle command lists formatting differences, which means an unformatted file fails the build rather than quietly shipping. The last one means every image build runs the full Go test suite for the target platform, so a red test blocks a container that might not have needed the code path at all. That is a defensible choice for a project where the image is the product, and it does slow down builds considerably on large change sets.
The first command is the interesting one. It runs a license-check binary copied in from a pinned image, against two specific copyright holder strings. Any file carrying a different copyright line fails the build. That is a strong governance signal for a project with 300 contributors, and it also means the check encodes an expectation about who holds copyright in the tree. Note also that `GOFLAGS=-mod=vendor` is set as an environment variable and a `vendor/` directory is committed, so the dependency set is fixed in the repository rather than resolved at build time.
Configuration lives in environment variables and one helm chart
The README is explicit that faas-netes is configured with environment variables and that the full option set is in the helm chart at chart/openfaas/. The table it does include is a useful summary of the defaults that matter most. `httpProbe` defaults to true, meaning function readiness and liveness use HTTP probes rather than process checks. `read_timeout` and `write_timeout` both default to 60 seconds, which is a generous ceiling for a function and worth lowering deliberately for anything user-facing.
`image_pull_policy` defaults to `Always`, so every restart re-pulls the function image even when the tag has not moved. That is the safe default and it is also the slow one on a constrained network or a rate-limited registry. Memory requests and limits default to 120Mi for the gateway, the provider, the operator and the NATS component, with CPU at 50m, while Prometheus gets 512Mi and Alertmanager only 25Mi. The queue worker and basic auth plugin are listed with the same figures, which is a hint that they are sized for light duty rather than for a busier deployment.
The dependency versions in go.mod are also worth a glance before planning an upgrade. The module targets `go 1.26.0` and pins `k8s.io/api`, `k8s.io/apimachinery` and `k8s.io/client-go` all at v0.36.1, alongside faas-provider v0.25.12. Release 0.18.15 was titled an update to Go 1.24 with client-go at v0.33.2, so the Kubernetes client has moved two minor versions since that tag without a corresponding release title.
A version line that ships infrequently against a recently pushed branch
The repository has 2172 stars, 489 forks and 39 open issues, and was last pushed on 2026-08-27. The newest release is 0.18.17, published on 2026-05-13, titled an update of the Go version, go.mod and GitHub Actions. Before that, 0.18.16 landed on 2025-07-16 and 0.18.15 on 2025-07-09, so the visible history has a long gap of about ten months followed by a burst in 2026.
That pattern says more than the dates themselves. The bulk of 0.18.17 comes from a single contributor, welteki, covering queue-worker adaptive concurrency, a Traefik ingress example, raising the default maximum retry attempt from 10 to 100, moving buildkitd calls onto a shared socket, and several chart updates. Commits credited to alexellis cover Go version bumps and a headroom controller with static license keys. Work is landing, but it is landing in release-sized batches rather than continuously.
The functional detail in 0.18.17 is worth more than the version number. A queue-worker retry ceiling moving from 10 to 100 is a behavioural change that will keep failed messages alive much longer before they are dropped, and the queue modes and queue depth scaling chart support in the same release changes how you configure that worker. If you are upgrading, read those two entries together rather than treating 0.18.17 as a dependency refresh.
One last detail for anyone who has followed OpenFaaS from the beginning: the README claims over 30k GitHub stars under Community. That figure is for the wider OpenFaaS organisation, not for this repository, which sits at 2172. The gap is not deceptive so much as out of place, since it invites a reader to judge the maturity of this provider by a number that belongs to the umbrella project.
Editorial conclusion
faas-netes is a well-built Kubernetes provider with an unusually candid README, and the candour cuts both ways. The project tells you plainly that the controller mode you get in the Community Edition is legacy, unsupported for new customers, and scheduled for removal, which means the free tier is the tier you are meant to leave. The build is honest about its own constraints too, with tests and a license check baked into the image build. If you want the operator mode and scale to zero you will be paying for Standard, and the 60 day clock on commercial proof of concept starts the day you deploy. For evaluation, the helm chart at chart/openfaas/ plus the operator CRD blog post settle the architecture questions, while the README settles the commercial ones.
Frequently asked questions
What license does faas-netes use?
The code is public but the grant is a custom EULA, not an OSI license. GitHub reports the license as NOASSERTION, the README limits Community Edition use to personal and hobbyist work plus a 60 day commercial proof of concept window, and the shipped image carries the label OpenFaaS CE EULA - non-commercial. Production and commercial use require OpenFaaS Standard or OpenFaaS for Enterprises.
What is the difference between the controller and operator modes in faas-netes?
In operator mode, functions are managed as Kubernetes Custom Resources and that mode is the one supported for production. Controller mode is described as legacy, scheduled for removal, without feature parity, and unsupported for new customers. The controller mode is also the only mode available in the Community Edition, so the free tier is confined to the deprecated path.
Does OpenFaaS Community Edition support scaling functions to zero?
The README lists scale to and from zero among the platform highlights, and also lists scale to zero and horizontal scaling among the commercial options, with capacity, requests per second, CPU, memory and custom rules as the paid specifics. Both statements appear in the same document, so the policy and configuration surface for going to zero belongs to the commercial tiers while the underlying platform can handle a cold start.
How do you configure the faas-netes provider once it is deployed?
Through environment variables, with the complete set defined in the helm chart at chart/openfaas/. The README summarises the defaults: httpProbe enabled, read and write timeouts of 60 seconds, and an image pull policy of Always, which means function images are re-pulled on every restart. Component resource requests default to 120Mi of memory and 50m of CPU for the gateway, provider, operator, queue worker and NATS.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/openfaas-faas-netes)