TL;DR:
- OpenFaaS is an open-source FaaS platform that runs on bare Docker (faasd) without Kubernetes, making it viable on edge nodes with 1GB+ RAM
- faasd is the edge-appropriate runtime — ~25MB overhead, runs on Raspberry Pi 4, deploys functions as containerd workloads
- MQTT connector lets functions subscribe to IoT topics directly, so sensor events trigger functions without polling loops
- Stateless by design: edge functions that need persistence require an external store; OpenFaaS handles the execution, not the state
IoT data processing at the edge tends to start simple and grow complex. A single temperature sensor feeding a database requires a small Python script. A hundred sensors feeding alerts, anomaly detection, and time-series databases requires dozens of processing components that need to be deployed, updated, and monitored across distributed hardware. At that scale, the question of how you manage function deployment becomes as important as what those functions do.
OpenFaaS applies the serverless functions model to this problem. Rather than maintaining persistent processes for each processing task, you deploy discrete functions that fire on events, run to completion, and scale independently. The deployment mechanism — HTTP API calls to the OpenFaaS gateway — works the same whether your edge node is a Raspberry Pi in a factory or a mini-PC in a retail backroom.
The faasd Runtime
The standard OpenFaaS distribution runs on Kubernetes (faas-netes). For edge deployments, Kubernetes is often too heavy — a three-node k3s cluster on Raspberry Pi hardware works, but it’s complexity that isn’t always justified for a single-site deployment processing a moderate event volume.
faasd addresses this. It’s a lighter alternative that runs OpenFaaS directly on containerd, with systemd managing the runtime lifecycle. The overhead is roughly 25MB of RAM for the faasd process itself plus the gateway — viable on any edge node with 1GB RAM and upward.
Installing faasd on a Raspberry Pi 4 with Ubuntu takes about ten minutes:
git clone https://github.com/openfaas/faasd
cd faasd
./hack/install.sh
After installation, the OpenFaaS gateway runs on port 8080. Functions are deployed via the faas-cli from any machine with network access to the edge node — including via a VPN or tunnel if the node is behind NAT.
Deploying a Function
Functions are any Docker container that speaks HTTP on port 8080. OpenFaaS ships a watchdog process that wraps your function binary and handles the HTTP lifecycle, so most language templates — Python, Node.js, Go, Rust — just require you to write your processing logic and let the template handle the rest.
A function that processes temperature sensor readings and sends an alert when thresholds are exceeded:
# handler.py
import json
import os
import requests
THRESHOLD = float(os.getenv("ALERT_THRESHOLD", "85.0"))
WEBHOOK_URL = os.getenv("WEBHOOK_URL", "")
def handle(event, context):
reading = json.loads(event.body)
temp = reading.get("temperature", 0)
sensor = reading.get("sensor_id", "unknown")
if temp > THRESHOLD:
requests.post(WEBHOOK_URL, json={
"alert": f"Sensor {sensor} exceeded threshold: {temp}°C"
})
return {"statusCode": 200, "body": "alert sent"}
return {"statusCode": 200, "body": "ok"}
The function stack file deploys it with configuration:
version: 1.0
provider:
name: openfaas
functions:
temperature-alert:
image: myregistry/temperature-alert:latest
environment:
ALERT_THRESHOLD: "85.0"
WEBHOOK_URL: "https://alerts.internal/temperature"
Deploy with faas-cli deploy and the function is running on the edge node within seconds of the container pulling.
MQTT Integration for IoT Events
Most IoT sensor networks publish readings to MQTT brokers. OpenFaaS connects to MQTT through the connector bridge — a lightweight process that subscribes to MQTT topics and forwards matching messages to functions as HTTP POSTs.
# mqtt-connector deployment
topics: "sensors/temperature/#,sensors/humidity/#"
broker_host: "localhost"
broker_port: 1883
gateway: "http://localhost:8080"
With this running, any message published to sensors/temperature/rack1 automatically invokes the temperature-alert function. No polling, no persistent subscription code in the function itself — the connector handles the MQTT lifecycle, functions just process HTTP.
This pattern scales cleanly: adding a new processing function for the same MQTT topic is a new faas-cli deploy, not a modification to existing processing code.
When OpenFaaS Makes Sense at the Edge
OpenFaaS works well at the edge when the event processing logic changes frequently enough that redeploying Docker containers is preferable to reflashing firmware or SSH’ing into nodes to edit scripts. It’s also well-suited to sites with multiple event sources — MQTT, HTTP webhooks, scheduled triggers — that all need to fan out to different processing functions with independent scaling.
The deployment model’s biggest advantage is operational: every function deployment is a versioned Docker image, function configs are YAML files in version control, and rollbacks are a single faas-cli deploy with the previous image tag. For teams managing processing logic across dozens of edge sites, this is significantly cleaner than bespoke process management on each node.
Limitations to Understand
Stateless design: OpenFaaS functions don’t retain state between invocations. An edge function that needs to track cumulative sensor readings across multiple messages needs an external store — Redis, SQLite on the local filesystem, or a time-series database. This is by design, not a bug, but it does mean stateful patterns require a storage strategy.
Cold starts: Functions that haven’t been invoked recently may be scaled to zero containers, adding latency on the first invocation. faasd mitigates this with the scale_from_zero=false option which keeps at least one container warm for latency-sensitive functions.
Resource floor: faasd is not appropriate for microcontrollers or single-board computers below the 512MB RAM mark. For ultra-constrained devices, bare-metal firmware or MicroPython remain the right approach. OpenFaaS targets the layer above that — edge gateway nodes and site computers, not the sensors themselves.
Alternatives: AWS Greengrass Lambda (managed but cloud-dependent), Azure Functions on Arc (enterprise integration but complex), Fermyon Spin (WebAssembly-based, lighter but younger ecosystem). OpenFaaS’s advantage over all of them is that it runs without any cloud dependency once deployed.