A
AgentKick
Back to blog
Industrial IoT / edge firmware·

Modbus RTU vs TCP: what changes when you actually implement both

Modbus looks like one protocol with two transports, and at the register level it is. The differences that matter show up in the code that talks to real devices, and they are large enough that the same poller needs distinct handling for each. Having implemented both against field equipment, here is what actually changes.

The register batch limit is the first wall

A Modbus read asks for a contiguous range of registers, and you cannot ask for an unbounded range in one request. We cap a single read at 100 registers and split anything larger into multiple requests, because devices stop responding (or return an exception) when a read spans too far. This holds on both transports, but it shapes everything else. A device with sparse, widely-spaced registers turns into many small reads, and that read count governs your poll-cycle time more than the choice of transport does.

Function codes are not interchangeable

The function code decides how a request is framed and how much you can ask for at once. Reading holding or input registers (codes 3 and 4) lets you batch up to roughly a hundred registers. Reading coils or discrete inputs (codes 1 and 2) is bit-oriented and framed differently. A poller that treats every point as a register read will misframe the digital points, so the dispatch on function code has to happen before batching, because the limits differ by code.

RTU: the serial layer is the reliability story

RTU runs over a serial line, RS-485 or RS-232, and the protocol gives you almost no help. There is no connection, framing depends on inter-character timing, and a noisy bus produces CRC errors that look exactly like a missing device. You set baud rate, data bits, stop bits, and parity to match each device, and you accept that one misbehaving device on a shared bus can disrupt the rest. Retry-with-timeout is mandatory rather than optional, and the timeout has to be sized for the slowest device on the line.

TCP: connection management replaces timing

Modbus TCP puts the same register semantics over a socket, which removes the serial timing problems and introduces connection ones. We pool one connection per IP-and-port and reuse it across every device behind that endpoint, reconnecting when the socket drops. The failure modes move from CRC and timing to socket resets, half-open connections, and firewalls. A device that reads as "offline" over TCP is often a network path that is down rather than the device itself, and your diagnostics have to tell those two apart or you will dispatch a technician to a healthy inverter.

Choosing between them

You rarely choose; the equipment chooses for you. Direct serial devices speak RTU, and a protocol gateway or a native-Ethernet device speaks TCP. The practical guidance is to keep one normalized internal model and isolate the transport behind it, so the rest of the system reads "register 40001 of device X" without caring whether that arrived over a serial line or a socket. The transport is a driver detail. The moment it leaks into your business logic, you have coupled your application to the wiring.

Where AgentKick fits

We build the device-integration layer for industrial platforms: multi-protocol pollers, normalized data models, and the diagnostics that separate a dead device from a dead network. If you are integrating a fleet that speaks Modbus over both serial and Ethernet, that is the work we do, usually as a short scoping engagement into a phased build.

modbusiotembeddedprotocols

Working on something like this?

Tell us the system, the timeline, and a budget range. You will get a feasibility note and rough sizing within one business day, or an honest no.

Tell us about your project