Skip to content
EnergyCalcHQ
7 min read

MQTT, Modbus TCP or HTTP: moving meter data to a server

Poll versus publish, what each protocol costs in bandwidth and firewall holes, how to design topics and payloads, and where each one genuinely belongs.

Written byDivakar

Once a gateway is reading meters reliably, the next question is how the data gets to wherever it is going to live. Three answers dominate, and they are not really competing — they belong at different points in the same system.

The distinction that matters is not the wire format. It is who starts the conversation, because that decides your firewall rules, your bandwidth, and what happens when the link drops.

Poll versus publish

Polling model against publish model, showing the direction of connections
Every architectural difference between these protocols follows from the direction of that first arrow.

Polling — Modbus TCP, HTTP GET — means a server asks each device for data on a schedule. The server needs to reach every device, which means every device needs a reachable address and an open inbound port. Most polls return data that has not changed.

Publishing — MQTT — means each device connects outward to a broker and pushes data when it has some. Nothing needs an inbound port. Consumers subscribe to the broker, and adding a new consumer changes nothing at the edge.

The three options compared

Modbus TCP MQTT HTTP / REST
Model Poll Publish / subscribe Poll or push
Overhead per reading Very low Low (2-byte minimum header) High (headers, often more than the payload)
Direction Inbound to device Outbound from device Either
Works behind NAT / mobile Poorly Yes Yes, if pushing
Security None built in TLS, per-client credentials TLS, tokens
Knows a device died No — a timeout is ambiguous Yes — last will and testament No
Buffers on reconnect No With QoS 1 and persistent sessions Only if you build it
Best at The field bus, over existing Ethernet Everything northbound Occasional bulk transfer, integrations

Modbus TCP is Modbus RTU's data model over Ethernet. It is the right choice where structured cabling already exists and the devices are on a network you control — it is fast, simple and every SCADA package speaks it. It has no authentication and no encryption whatsoever, which is fine on an isolated OT VLAN and unacceptable anywhere else. Never expose it to the internet.

MQTT is the default for anything leaving the site. It is designed for unreliable links and small messages, it needs no inbound ports, and it has two features that are worth the switch on their own:

  • Last will and testament. The client registers a message when it connects, and the broker publishes it if the connection dies. Your monitoring system learns a gateway is gone within seconds, instead of inferring it from silence.
  • Persistent sessions with QoS 1. The broker holds messages for a disconnected subscriber and delivers them on reconnect.

HTTP is the right answer for what it is good at: batch uploads, integrating with somebody else's API, or a low-rate system where the operational simplicity of "just POST some JSON" is worth the overhead. Sending one reading per second over HTTPS means a TLS handshake and several hundred bytes of headers to carry twenty bytes of data.

Getting MQTT right

Topic structure. Hierarchical, specific to general on the left, one device per branch:

site/plant1/shed2/mcc3/compressor-1/telemetry
site/plant1/shed2/mcc3/compressor-1/status

Rules that save pain later:

  • No wildcards or variable depth. Subscribers use + and #, so a consistent depth is what makes site/plant1/+/+/+/telemetry work.
  • Never put data in the topic. .../current/47.2 cannot be subscribed to usefully.
  • Separate telemetry from status. Different rates, different retention, different consumers.
  • Identify by role, not by hardware, for the same reason as in the gateway post — replacing a meter should not break a topic.

Payload. JSON is the sensible default: readable, debuggable, universally supported. Include the timestamp in every message, in UTC, generated at the edge.

{
  "ts": "2026-08-31T09:15:00Z",
  "kwh_import": 148237.4,
  "kw": 61.2,
  "pf": 0.91,
  "i": [88.4, 91.2, 87.9]
}

Send one message per device per interval with all its quantities, not one message per quantity. Twenty meters × 40 registers as individual messages is 800 messages a cycle, and each carries its own overhead.

QoS. QoS 0 for high-rate telemetry where the next reading is along shortly. QoS 1 for anything you must not lose — energy totals, alarms, status changes. QoS 2 is rarely worth its round trips; design your consumers to be idempotent instead, which you need anyway.

Retained messages on status topics, so a newly connected dashboard immediately knows the current state rather than waiting for the next change.

If you want a standard rather than a house convention, Sparkplug B defines topic structure, payload encoding and birth/death certificates for industrial MQTT. It is more machinery than a twenty-meter site needs, and it is a genuinely good answer for a large estate with many vendors.

How much data is this, really?

Worth estimating before choosing a SIM plan, because the answer surprises people in both directions.

Twenty meters, forty quantities each, published once a minute as JSON:

~400 bytes per message × 20 meters × 60 min × 24 h = ~11 MB/day
                                                   = ~330 MB/month

Comfortable on any fixed line, and a real consideration on a metered mobile connection. If it needs to come down, the levers in order of effect are: publish less often (a minute is already far more often than energy analysis needs), publish only quantities that changed, drop JSON for a binary encoding, and enable MQTT 5 topic aliases so the topic string is not repeated on every message.

Note what is not on that list: reading fewer registers from the meter. Polling the field bus is free — it happens over your own RS485 cable. Read everything the meter offers, using contiguous register blocks worked out with the address converter, and decide separately what to publish northbound. Data you did not collect is gone forever; data you collected and chose not to send is still on the gateway.

Security, which is the actual differentiator

The protocol choice is largely a security choice, so be explicit:

  • TLS everywhere, with certificate verification actually enabled — not disabled to make the demo work and then forgotten.
  • Per-device credentials, so one compromised gateway can be revoked without touching the others.
  • Broker-side ACLs limiting each client to publishing on its own topic branch. A gateway should not be able to publish as another site.
  • Outbound connections only. No port forwarding, no inbound rules, ever.
  • Segment the OT network. The gateway may talk to meters and to the broker. Nothing else needs to talk to the meters.

A sensible default architecture

For almost every site under a few hundred points:

  1. Modbus RTU over RS485 from meters to a local gateway. Cheap, robust, works over a kilometre, no network infrastructure required.
  2. Local buffering on the gateway, with edge timestamps.
  3. MQTT over TLS northbound to a broker, outbound only.
  4. Subscribers on the broker for storage, dashboards and alerting — each independent, each addable without touching the field.

That gives you one polling domain, at the edge, where polling is appropriate because the devices are dumb and the bus is local. Everything upstream is event-driven, firewall-friendly and survives an intermittent link.

The mistake to avoid is polling across the internet — a central server reaching into twenty sites over VPNs to read Modbus TCP. It works, it is what many systems do, and every one of those VPN tunnels is a thing that breaks at 2 a.m. and a hole into an OT network that has no authentication behind it.

Related articles

More on metering & iot.

Comments

Loading…

Add a comment

Corrections especially welcome. Comments are approved by hand before they appear.

Your email is never published. We use it only to reply.