Skip to main content

infinimesh 3.4: the device layer for your IoT and AI stack gets rules, alarms and OTA

Struggling with delivery, architecture alignment, or platform stability?

I help teams fix systemic engineering issues: processes, architecture, and clarity.
→ See how I work with teams.


Summary

infinimesh is an Apache-2.0 IoT backend you run on your own servers. Version 3.4 is in release candidate testing now. It adds rules and alarms with CEL conditions, an OTA contract in the device shadow, a file service, fleet bulk updates, quotas, metrics, CoAP ingest, an audit log, and a stable v1 API. This post explains what changed, why it matters for EU device makers who want to keep their data at home, and how to try it on one machine in a few minutes.

Bottom Line

Every connected product ends up building the same backend: a list of devices, rules about who may see them, and a record of what each device last said. I have built that backend more than once, and so have most teams I talk to. infinimesh is my attempt to stop doing it again.

Version 3.4 is the release where infinimesh grows from "registry and shadow" into a device layer you can actually run a product on. Rules and alarms, an OTA contract, files, fleet tools, quotas and metrics are now in core. The release candidates are out and being tested now. The final v3.4.0 tag is coming.

The practical takeaway: if you make devices in the EU and want the backend on your own servers under an open license, this is a good moment to try it and tell us what breaks.

What infinimesh is, in one paragraph

infinimesh is an open source IoT platform written in Go. It gives you a device registry, device auth with client certificates, a device shadow (reported and desired state), an MQTT bridge, and REST, gRPC and Connect APIs from one schema. Accounts, namespaces and devices form a permission graph, so a customer can see their devices at READ and their service partner can manage them, and neither sees anything past that. The project calls itself "the device layer for your IoT and AI stack", and that is the right scope. It is not a dashboard product. Your data goes to the tools you already run.

I co-founded infinimesh and I still maintain it. That is the bias you should read this post with.

How infinimesh 3.4 fits together

Devices in, state and events out. Everything in the blue box runs on your servers.

Devices
MQTT 3.1.1 / 5TLS 1.2 and 1.3 on 8883, client certificate
CoAPUDP 5683, private network
HTTP ingestPOST /v1/ingest with a device token
HardwareESP32, Pico W, gateways
infinimesh core
Device layer
Registryidentity, certificates
Permission graphper customer and partner
Shadowreported and desired state
Rules and alarmsCEL, raise, ack, clear
OTA contracttarget version and status
Fileshttp-fs, local or S3
Audit logreads, tokens, OTA assigns
Quotas and metricsper namespace, Prometheus
Stable v1 APIREST, gRPC, Connect, OpenAPI
Your stack
Your appsconsole, inf CLI, your own code
Data addonsKafka, Postgres, InfluxDB, webhook, S3, more
OTA addonshawkBit, Mender
AIMCP server, LLM addon

Desired state, rule actions and OTA targets flow back to the device over the same channel.

in core before 3.4 new in 3.4 coming soon, after 3.4

Why I care about where this runs

Most IoT platforms I see in projects are either a managed cloud service or an open core product where the parts you need in production sit in the paid edition. For a lot of European device makers both are a problem. The data leaves the building, or the license changes the math once the fleet grows.

infinimesh takes the other route. Apache-2.0, self-hosted, and the project says plainly that the open source core is complete and no feature is held back for a paid tier. Per customer access is in the core graph, not an upsell.

There is also the EU Data Act. If you sell connected products, your customers will ask for access to their device data, and sometimes for access by a third party they pick. 3.4 has the pieces for that: grants with an expiry date and a consent record, a device export endpoint that returns the registry entry and the current shadow, and an audit log of who read what. To be clear, and the project says the same: infinimesh gives you the access model. It does not make your product compliant by itself.

What is new in 3.4

What's new in infinimesh 3.4

From the core changelog, v3.4.0 release candidates

new

Rules and alarms

CEL conditions such as reported.temp > 70. Alarms are raised, acked or cleared, with a cooldown. Actions: log, signed webhook, MQTT, desired state.

new

OTA contract

Target version in desired state, status reported back. Only a registered OTA addon, such as hawkBit or Mender, can enable OTA for a namespace.

new

Files (http-fs)

Namespace files for the console media page. Local volume by default, or any S3 endpoint. Size and type limits.

new

Fleet bulk patch

One desired state for every device in a namespace or with a tag. Bulk create, factory claim tokens, certificate rotation and revocation.

new

Quotas

Per namespace limits on devices and message rates, on the MQTT bridge and on HTTP ingest. Zero means no limit.

new

Metrics and traces

/metrics on every service for Prometheus. OTLP trace export with one environment variable.

new

CoAP ingest

Reported state over UDP CoAP on 5683. Plaintext, so keep it on a private network.

new

Audit log

Append only. Shadow reads, device creation, device tokens and OTA assigns, queryable by device or account.

stable

v1 API

REST under /v1, gRPC and Connect from one proto schema. Breaking changes go into a new version. OpenAPI spec and Swagger view online.

install

Kubernetes and Compose

Helm chart for production, Docker Compose on one machine for local work.

tooling

inf CLI

A single Go binary. brew install inf on macOS and Linux, archives for Windows.

planned

Air-gapped install

An offline bundle per release for Docker and Kubernetes. Open proposal, not built yet.

coming soon

OTA addons

hawkBit and Mender addons that plug into the OTA contract.

coming soon

MCP server and LLM addon

Device state for AI agents and OpenAI compatible APIs, scoped by the same permission graph.

Rules and alarms

This was the biggest gap. Until now the honest answer to "where do I put my alert logic" was "in another system". In 3.4 rules live in core.

A rule belongs to a namespace. The condition is a CEL expression that can read reported, desired, connected, the device, its title, its tags and the namespace. A reading stored at reported.data.temp is just reported.temp in the rule. So reported.temp > 70 does what you think it does.

When the condition is true, the rules service raises an alarm for that rule and that device. Someone can ack it, it clears when its clear condition is true, and a cooldown sets the shortest time before the same alarm can be raised again. Actions are a log line, a webhook signed with HMAC-SHA256, an MQTT publish, or a patch to the device's desired state. That last one is the useful one: a rule can tell the device to do something, not only tell a human.

Two details I like. A new rule is checked against the current state of every device right away, not on the next reading. And you manage rules and alarms over REST (/v1/rules, /v1/alarms) or the Connect API, the same way the console does.

OTA as a contract, not a feature

I did not want infinimesh to become yet another firmware server. hawkBit and Mender already do that job well. What was missing was a clean place in the device layer where "this device should run version X" and "this device is now downloading, installing, done or failed" live.

So 3.4 adds an OTA document to the shadow. The target version, URL, SHA-256 and size go into desired state. The device reports its status back. POST /v1/devices/ota:assign sets a target for a list of devices, a tag, or a whole namespace, returns one result per device, and writes an audit row for each success.

The important rule: OTA stays off for a namespace until an OTA addon is registered for it. Nothing can write the desired OTA target while it is off. The addons for hawkBit and Mender come after 3.4. Until then the contract is there for you to build against.

Fleet, quotas and the boring production parts

Bulk create, factory claim tokens, certificate rotation that keeps the previous certificate valid during rollover, and revocation. A device can claim itself into a namespace with a factory token and its certificate, which matters a lot once you produce hardware in batches. I wrote about why the factory side needs its own evidence trail in IoT device manufacturing needs verifiable assembly records. infinimesh is the place where that device identity lands after it leaves the line.

Then the part nobody demos: per namespace quotas on device count and message rates, Prometheus metrics on every service, OTLP traces, and MQTT sessions that can live in Redis so a reconnect can land on another bridge replica. This is what lets you run it for customers instead of for yourself.

CoAP, files, and a stable API

CoAP ingest is for constrained devices that cannot afford MQTT over TLS. It is plaintext UDP with no DTLS, so treat it like a field bus: private network only, or a terminator in front. Same honesty as with BACnet. Protocol bridges look small and turn into infrastructure, which is the whole point of my posts on the real cost of bridging BACnet to MQTT and on bacnet-mqtt-gateway. A building gateway that publishes to infinimesh over MQTT is a very normal setup.

The http-fs service stores files per namespace, on a local volume or any S3 endpoint such as MinIO or Hetzner Object Storage. And the v1 API is now stable: new fields can be added, breaking changes go into a new version. You can browse it in the API reference, which is a Swagger view of the OpenAPI spec.

Try it on your laptop

You need Docker with Docker Compose. This runs the whole stack on one machine. To test the 3.4 release candidate, pin it in .env:

git clone https://github.com/infinimesh/core.git
cd core
cp .env.example .env
# test the 3.4 release candidate
sed -i.bak 's/^INFINIMESH_VERSION=.*/INFINIMESH_VERSION=v3.4.0-rc.6/' .env
docker compose up -d

Open https://console.127.0.0.1.nip.io and log in as infinimesh / infinimesh. Change that password right away. The local setup uses a self-signed certificate, so accept it once each for console, api and media. If login fails with no message, you have not accepted the api one yet.

Get the CLI:

brew tap infinimesh/inf-cli https://github.com/infinimesh/inf-cli
brew install inf

Then create a rule that raises an alarm when a device runs hot. Use the namespace id from inf namespaces list:

API=https://api.127.0.0.1.nip.io

TOKEN=$(curl -sk -X POST "$API/v1/token" \
  -d '{"auth":{"type":"standard","data":["infinimesh","infinimesh"]}}' \
  | python3 -c 'import sys, json; print(json.load(sys.stdin)["token"])')

curl -sk -X POST "$API/v1/rules" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "namespace": "<namespace-uuid>",
    "name": "Too hot",
    "when": "reported.temp > 70",
    "clear": "reported.temp < 65",
    "cooldown": "10m",
    "actions": [{"log": {"message": "temperature above 70"}}]
  }'

Send a reading above 70 from a device, with inf devices state, an ESP32 or Pico W example, or the curl script in the docs repo, and the alarm shows up on the "Rules and Alarms" page.

For production, use the Helm chart in infinimesh/k8s. An air-gapped install for factories, labs and regulated sites is planned as an open proposal. If you need it, comment there.

When not to use it

  • You want a fully managed cloud service and do not want to run servers.
  • You want dashboards in the box. Use Grafana on top of an addon, or a different product.
  • You have a few devices and one user. A plain MQTT broker is simpler.
  • You need OTA end to end today. The contract is in 3.4, the hawkBit and Mender addons are not.

What comes after 3.4

First the OTA addons, so hawkBit and Mender plug into the contract above. Then AI, which is where the tagline comes from. An MCP server will let an agent read device state and set desired state, and an LLM addon will send device state to any OpenAI compatible API, such as vLLM, Ollama or Mistral. Both are coming soon and neither is built yet.

The part I care about is that both will be scoped by the same permission graph as people. An agent sees only the devices its token can see. You can run the model locally, so device data stays on your servers. Until those ship, the webhook or MQTT bridge addon is the way to feed your own agent.

Videos

A few older videos about the platform, made with my startup Infinite Devices, which I founded with my friend Bruno in 2021 and sold in 2024. They are in German and show earlier versions, but the idea has not changed: IoT data under your control.

Infinite Devices: Infinimesh, skalierbare Open-Source-AIoT-Plattform (2022, German)

Infinite Devices at ITT21: IoT, the eyes and ears of AI (2021, German)

More from the archive:

Star it, run it, break it

If you build connected hardware and want to own the backend, give it ten minutes. If the quickstart runs on your machine, it is worth a closer look. If it does not, that is a bug and I want to hear about it.

infinimesh is also listed on the Scalytics open source page.

If you need help with distributed systems, backend engineering, or data platforms, check my Services.

Most read articles

Building a Model-Agnostic Multi-Agent System with OpenClaw

Over one week we rebuilt our AI stack around OpenClaw’s multi-agent architecture to avoid provider lock-in and stop wasting premium tokens. By aligning models to tasks, diversifying fallbacks across providers, enforcing minimal tool access, and switching to memory-first workflows with ephemeral sessions, we reduced token usage per task by about 70% and cut our monthly bill by 77% while improving operational resilience. How We Achieved 77% Cost Reduction and Provider Independence Over the past week, we rebuilt our AI infrastructure around OpenClaw’s multi-agent architecture. The result was a 77% cost reduction , provider independence , and a delegation system that routes work to the most cost-effective model for each job. Below is the technical journey of optimizing a 7-agent squad with OpenClaw. The Challenge: Model Provider Lock-In We started with a simple problem: our entire squad defaulted to a single model provider. This created three issues: Cost inefficiency beca...

BacNet => MQTT in Production: The Real Cost of Bridging BACnet to MQTT at Scale

bacnet2mqtt looks simple in a README and expensive in production. Once BACnet polling, reconnection behavior, stale state, and MQTT publishing collide, teams discover they are not deploying a lightweight adapter but operating infrastructure. This article breaks down where bacnet2mqtt works, where it becomes a bottleneck, and which production patterns reduce the operational damage before incidents, backlogs, and silent data loss turn a building integration into a long-running engineering problem. I inherited a building controls integration problem 18 months ago. Three office floors. 217 BACnet sensors covering temperature, occupancy, and HVAC actuators. The data was trapped inside the building automation network while the business wanted analytics, reporting, and compliance visibility in the data platform. The obvious answer looked easy enough: deploy bacnet2mqtt, bridge BACnet into MQTT, and push the stream into the lakehouse stack. The repository made it sound like a w...

Connect BACnet to the Cloud with bacnet-mqtt-gateway

The bacnet-mqtt-gateway project is an open source protocol bridge that translates BACnet building automation traffic into MQTT messages for cloud and IoT systems. It provides discovery, polling, bidirectional writes, APIs, security, and easy deployment via Docker. Many enterprises struggle to unify BACnet with modern data pipelines and cloud platforms because BACnet is local-network only and not cloud ready. This gateway provides a scalable, secure, production-ready adapter for MQTT ecosystems and smart building integrations. The Problem with BACnet Building automation runs on BACnet . HVAC controllers, lighting systems, metering equipment: they all speak ASHRAE 135 . The protocol handles local control loops well. It fails at cloud ingress. BACnet relies on UDP broadcasts. These do not route over the internet or into VPCs. Your chiller controller cannot talk to AWS IoT Core . Your VAV box cannot publish to an MQTT broker. The air gap between operational technology and modern cl...