IoT and AI

Federated Learning for IoT Explained: Training Without Centralizing Data

Federated learning lets IoT devices improve a shared model while their raw data stays local. This explainer covers how it works, where it fits, its pitfalls, and how an MQTT broker can carry model updates between devices and a coordinator.

Federated learning IoT diagram with several devices training locally and exchanging model updates with a coordinator through an MQTT broker
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

Federated learning for IoT is a way to train one shared model across many devices while each device keeps its raw data to itself. In this explainer you will learn how the training rounds work, when federated learning is worth its complexity, what typically goes wrong, and how an MQTT broker can carry the global model and the local updates, with a small runnable simulation you can try against broker.connectmq.com.

The Problem Federated Learning Solves

Standard machine learning collects data in one place and trains there. For IoT that is often impractical. Cameras, wearables and machines produce sensitive or bulky data; customers may forbid it leaving their sites; and cellular links make uploading everything expensive. Yet a model trained on one device's data alone sees too little variety to generalize.

Federated learning flips the flow. The model travels to the data, each device trains briefly on what it has, and only the resulting parameter updates travel back. A coordinator combines those updates into a better global model and sends it out again. Raw readings never leave the device.

How a Federated Training Round Works

The most common algorithm, Federated Averaging (FedAvg), repeats these steps:

  1. Broadcast: the coordinator publishes the current global model with a round number.
  2. Select: a subset of eligible devices participates, often those that are idle, charging and on an unmetered connection.
  3. Local training: each participant trains for a few epochs on its local data, starting from the global weights.
  4. Report: each participant sends its updated weights (or the difference from the global weights) and its sample count.
  5. Aggregate: the coordinator averages the updates, weighted by sample count, to form the next global model.
  6. Repeat until accuracy stops improving, then deploy the global model for inference.

The devices then run the model locally as ordinary edge AI. If you are new to on-device inference, read what edge AI is first.

When Federated Learning Fits IoT

Federated learning is a strong candidate when:

  • Data is sensitive: audio, video, health signals, or production data owned by different customers.
  • Data is large or continuous, so uploading it is costly.
  • Behaviour differs per site, and you want one model that has learned from all of them.
  • Devices have enough compute to train, which usually means gateways, industrial PCs, phones or Linux edge boxes rather than small microcontrollers.

It is often the wrong choice when the data is not sensitive and can be uploaded cheaply, because centralized training is simpler to debug and usually more accurate. Microcontroller-class devices can run inference well but rarely have the memory to train; in those fleets, the gateway is the natural federated participant. The what TinyML is guide covers those limits.

Challenges You Will Meet

Challenge What happens Common mitigation
Non-IID data Each device sees a different distribution, so local updates pull in different directions Fewer local epochs, more rounds, algorithms designed for heterogeneity
Stragglers and dropouts Some devices go offline mid-round Round deadlines; aggregate whatever arrived
Communication cost Model updates can be large and frequent Smaller models, quantized or compressed updates, fewer rounds
Privacy leakage Updates can reveal information about local data Secure aggregation, differential privacy, update clipping
Poisoned updates A faulty or malicious device sends harmful weights Authentication, update validation, robust aggregation
Versioning Old updates arrive for a newer round Round numbers in every message; discard stale updates

Federated learning reduces exposure of raw data, but it is not automatically private. Treat updates as sensitive and protect them in transit and at rest.

Federated Learning IoT Communication over MQTT

Open-source federated learning frameworks generally ship their own transport, often gRPC, which assumes devices can hold a connection to the coordinator. IoT fleets already have a messaging layer that copes with intermittent links: MQTT. Mapping federated learning onto MQTT is natural:

Federated concept MQTT mechanism
Broadcast global model Publish to fl/<task>/global, retained, so devices that connect late still receive the current round
Participant updates Each device publishes to fl/<task>/update/<deviceId> with QoS 1
Coordinator inbox Subscription to fl/<task>/update/+
Stale rounds MQTT 5 message expiry so old global models are not delivered after a deadline
Device availability Retained status topic plus Last Will
Scaling the coordinator MQTT 5 shared subscriptions across aggregator workers

Two constraints deserve attention. First, message size: an MQTT broker enforces a maximum message size, for example 64 KB on the public test area, 256 KB on the ConnectMQ Serverless (Free) plan and 1 MB on Serverless (Paid). Small models fit easily; larger ones need quantized updates, compression or chunking across several messages. Second, access control: only the coordinator should be able to publish global models, and devices should only publish their own updates, so run production federated jobs on a private broker with per-device credentials and TLS, never on a public topic. If you want a refresher on what an MQTT broker does, start there.

Try It: FedAvg over MQTT in One Script

This simulation runs a coordinator and three devices as separate MQTT clients in one Python process. Each device holds its own private dataset for a linear model, drawn from a different distribution to mimic non-IID data. Only weights and sample counts cross the broker.

pip install "paho-mqtt>=2.0" numpy
import json
import threading
import time
import uuid

import numpy as np
import paho.mqtt.client as mqtt

HOST, PORT = "broker.connectmq.com", 1883
P = f"connectmq/demo/{uuid.uuid4().hex[:8]}/fl/demo-task"
TRUE_W, TRUE_B = np.array([2.0, -1.0, 0.5]), 0.3
ROUNDS, N_DEVICES = 10, 3
done = threading.Event()


def make_client(name, on_connect, on_message):
    c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"{name}-{uuid.uuid4().hex[:6]}")
    c.on_connect, c.on_message = on_connect, on_message
    c.connect(HOST, PORT, keepalive=60)
    c.loop_start()
    return c


class Device:
    def __init__(self, name, n, shift, seed):
        rng = np.random.default_rng(seed)
        self.X = rng.normal(shift, 1.0, (n, 3))          # private data, never published
        self.y = self.X @ TRUE_W + TRUE_B + rng.normal(0, 0.1, n)
        self.name, self.last_round = name, -1
        self.client = make_client(name, self.on_connect, self.on_global)

    def on_connect(self, client, userdata, flags, reason_code, properties):
        client.subscribe(f"{P}/global", qos=1)

    def on_global(self, client, userdata, msg):
        if not msg.payload:
            return
        g = json.loads(msg.payload)
        if g["round"] <= self.last_round or g["round"] >= ROUNDS:
            return
        self.last_round = g["round"]
        w, b = np.array(g["w"]), g["b"]
        for _ in range(5):                                # local epochs of gradient descent
            err = self.X @ w + b - self.y
            w -= 0.05 * self.X.T @ err / len(self.y)
            b -= 0.05 * err.mean()
        update = {"round": g["round"], "n": len(self.y), "w": w.tolist(), "b": float(b)}
        client.publish(f"{P}/update/{self.name}", json.dumps(update), qos=1)


class Coordinator:
    def __init__(self):
        self.round, self.updates = 0, {}
        self.client = make_client("coordinator", self.on_connect, self.on_update)

    def on_connect(self, client, userdata, flags, reason_code, properties):
        client.subscribe(f"{P}/update/+", qos=1)

    def publish_global(self, w, b):
        msg = {"round": self.round, "w": list(map(float, w)), "b": float(b)}
        self.client.publish(f"{P}/global", json.dumps(msg), qos=1, retain=True)

    def on_update(self, client, userdata, msg):
        u = json.loads(msg.payload)
        if u["round"] != self.round:
            return                                        # stale update from an old round
        self.updates[msg.topic.rsplit("/", 1)[-1]] = u
        if len(self.updates) < N_DEVICES:
            return
        total = sum(x["n"] for x in self.updates.values())
        w = sum(np.array(x["w"]) * x["n"] for x in self.updates.values()) / total
        b = sum(x["b"] * x["n"] for x in self.updates.values()) / total
        print(f"round {self.round}: w={np.round(w, 3)} b={b:.3f}")
        self.round, self.updates = self.round + 1, {}
        self.publish_global(w, b)
        if self.round >= ROUNDS:
            done.set()


coord = Coordinator()
devices = [Device("gw-a", 200, -1.0, 1), Device("gw-b", 120, 0.0, 2), Device("gw-c", 80, 1.5, 3)]
time.sleep(2)                                             # let subscriptions settle
print("topics under", P)
coord.publish_global(np.zeros(3), 0.0)
done.wait(timeout=120)
print("true  : w=", TRUE_W, "b=", TRUE_B)

coord.client.publish(f"{P}/global", b"", qos=1, retain=True).wait_for_publish()   # clear retained model
for c in [coord.client] + [d.client for d in devices]:
    c.loop_stop()
    c.disconnect()

Each round prints the aggregated weights, which move steadily toward the true values even though no device ever shares its data points. To watch the traffic, subscribe to the printed prefix with mosquitto_sub -h broker.connectmq.com -p 1883 -i fl-viewer-42 -t '<prefix>/#' -v. Note how small the update messages are; a real neural network would be far larger, which is where the size limits above matter.

Production Checklist

  1. Authenticate every device with its own credentials and TLS; bind client IDs to devices.
  2. Sign or validate updates on the coordinator: check shapes, value ranges and round numbers.
  3. Set a round deadline and aggregate whatever arrived, so one slow device cannot stall training.
  4. Keep the global model retained and versioned, and clear it when a task ends.
  5. Track per-round metrics, such as validation loss on a held-out set the coordinator owns.
  6. Consider secure aggregation or differential privacy if updates themselves are sensitive.

For deploying the resulting model to the fleet, see deploying ML models to edge devices. For edge versus central trade-offs in general, read edge AI vs cloud AI, and for the full landscape the AI and IoT guide.

Run Federated Experiments on ConnectMQ

Federated learning needs a broker that every participant can reach securely from any network. ConnectMQ is a hosted MQTT broker with TLS, MQTT 5 message expiry and shared subscriptions on paid plans, and Dedicated or BYOC options when model updates must stay in an isolated environment. Create a broker on the free Serverless plan at app.connectmq.com, no credit card required. For a quick experiment like the one above, the free public MQTT broker is enough.

Frequently Asked Questions

Is federated learning private by default?

It keeps raw data on devices, which reduces exposure, but model updates can still leak information. Combine it with encrypted transport, secure aggregation or differential privacy when data is sensitive.

Can microcontrollers take part in federated learning?

Rarely as full participants, because training needs much more memory than inference. A common design lets a gateway train on data collected from nearby microcontrollers.

Why use MQTT instead of gRPC for federated learning?

MQTT suits fleets with intermittent connectivity: devices connect outbound, retained messages deliver the current model to late joiners, and QoS handles retries. gRPC works well when participants are always reachable servers.

How large can a model update be over MQTT?

It is limited by the broker's maximum message size. Larger models need quantized or compressed updates, or splitting an update into several messages with a sequence number.

Related articles

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.