Skip to content
FerruleTech

OPC UA vs Modbus TCP vs MQTT — choosing a protocol for a retrofit

The three protocols solve different problems and are usually used together. A practical decision guide for brownfield plants.

The question comes up on almost every retrofit, and it is usually asked as if the three protocols compete. They do not. They sit at different points on the path from the machine to wherever the data is going, and a typical brownfield plant ends up using at least two of them together.

Modbus is the oldest of the three and the reason it survives is that it asks almost nothing of a device. A register map, a slave address, and a poll. There is no type system, no discovery, no security, and no concept of a device announcing itself — a Modbus register is sixteen bits and whether that means degrees Celsius, tenths of a bar, or a bitfield of alarm flags is something you find out from a PDF, or by experiment. That sounds like a weakness, and it is, but it is also why practically every energy meter, VFD, temperature controller and twenty-year-old PLC in your plant will speak it. On a retrofit, Modbus TCP is very often the only thing a given machine can do, and it is almost always safe: you are reading registers the controller already maintains, at a rate you choose, without touching the control program.

OPC UA is what you use when the equipment is modern enough to offer it. It solves precisely the things Modbus does not: tags are named and typed, units and engineering ranges travel with the value, the server describes its own address space so you can browse it instead of guessing, and the transport is authenticated and encrypted. The practical consequence is maintainability. A Modbus integration is a spreadsheet of register offsets that becomes wrong the moment somebody changes the PLC program; an OPC UA integration refers to tags by name and mostly survives that. Where a controller supports OPC UA and the licence is already paid for, use it.

MQTT is not a machine protocol at all, and this is the part that most often gets muddled. It is a lightweight publish-and-subscribe transport designed for unreliable networks. It has no idea what a PLC is. You do not connect MQTT to a machine; you connect something to the machine — Modbus, OPC UA, a native driver — and then use MQTT to move the resulting data somewhere else. Its value is in the direction of connection and in its behaviour when the link fails. The gateway connects outward to a broker, so no inbound firewall port is needed into the plant. Messages are published only when a value actually changes, so bandwidth tracks meaningful events rather than sample rate. And when the connection drops, a properly configured client queues locally and back-fills on reconnect.

Plain MQTT, though, gives you a transport and no conventions. There is no agreed payload format, no way to discover what a device publishes, and — the one that bites hardest — no way to distinguish “nothing has changed” from “this device is dead”. Both look identical: silence. Sparkplug B is a specification layered on top of MQTT that fixes this. It defines the payload encoding, requires a device to publish a birth certificate describing every metric it will send, and registers a death certificate with the broker in advance so that an unexpected disconnection is announced rather than inferred. If you intend to alarm on machine data, that distinction is not a nicety. A monitoring system that treats a dead gateway as a healthy machine producing no faults is worse than no monitoring system.

So the architecture that falls out of this for most plants looks like one shape. On the field side, read each machine over whatever it actually supports — OPC UA where it exists, Modbus TCP or RTU where it does not, a native driver where the diagnostics justify it. Normalise all of it at the edge into one tag model with consistent names and units, so that machine 7 and machine 12 describe the same quantity the same way. Then publish north over MQTT with Sparkplug B, with local buffering behind it.

That leaves the two decisions that actually matter, neither of which is a protocol choice. The first is your tag model: agreeing what things are called and in what units, before anything is configured, is what determines whether adding the thirteenth machine is a morning’s work or a redesign. The second is your poll and deadband policy per tag, which is what separates a system that produces a few megabytes a month from one that produces gigabytes nobody queries. Protocols are the easy part. Getting those two right is the engineering.

CallWhatsAppEstimate