Overview
Modbus TCP loading on an industrial control network is a contractual and operational metric, not a single number reported by the controller. On a SIMATIC S7-400 system running STEP 7 V5.5 with the Modbus/TCP CP (catalog number 6GK7 443-1EX50-0XE0 family, often referenced as the 2XV9450-1MB11 application module), the network utilization must be derived from the byte volume of Modbus Application Protocol (MBAP) transactions divided by the wire capacity of the Ethernet segment, with the customer-imposed ceiling typically fixed at 60% of nominal bandwidth.
This reference covers four measurement paths: theoretical calculation from the application transaction table, runtime statistics from the CP diagnostics interface, online capture with a SPAN port and Wireshark, and CPU-side runtime measurement with OB_BEGIN/OB_END tags inside CFC V8.0. Each method produces a usable percent figure; combining them yields the documented acceptance value.
Modbus TCP Frame Architecture and Byte Accounting
The Modbus TCP frame consists of a 7-byte MBAP header followed by a 1-byte function code (FC), the data payload, and a trailing Ethernet/IP transport envelope. The minimum Ethernet frame carrying one Modbus TCP transaction is therefore:
- Ethernet header: 14 bytes (DA + SA + EtherType 0x0800 + VLAN tag if present)
- IP header: 20 bytes (IPv4, no options)
- TCP header: 20 bytes (no options, ACK-only)
- MBAP header: 7 bytes (Transaction ID 2 B + Protocol ID 2 B + Length 2 B + Unit ID 1 B)
- Function code: 1 byte
- PDU payload: variable, 1 to 252 bytes for data, plus address/quantity fields
- Ethernet trailer (FCS): 4 bytes
- Inter-frame gap + preamble: 20 bytes
The wire-byte total per Modbus TCP request/response pair is therefore:
Bytes_total = 14 + 20 + 20 + 7 + 1 + N_data + 4 + 20 = 86 + N_data
where N_data is the size of the Modbus PDU payload (excluding the function code byte). For the read holding registers (FC 03) and read input registers (FC 04) responses, N_data = 2 + 2 × N_registers; for write single coil (FC 05) and write single register (FC 06), N_data = 4; for write multiple registers (FC 16), N_data = 5 + 2 × N_registers.
Worked byte-count examples
| Function Code | Operation | Request PDU | Response PDU | Wire Bytes (req+resp) |
|---|---|---|---|---|
| FC 01/02 | Read 1 coil / discrete input | 5 B | 5 B | ~177 |
| FC 03/04 | Read 1 register | 5 B | 7 B | ~181 |
| FC 03/04 | Read 10 registers | 5 B | 25 B | ~217 |
| FC 03/04 | Read 100 registers | 5 B | 205 B | ~577 |
| FC 05 | Write single coil | 5 B | 5 B | ~177 |
| FC 06 | Write single register | 5 B | 5 B | ~177 |
| FC 16 | Write 10 registers | 26 B | 6 B | ~219 |
| FC 16 | Write 100 registers | 206 B | 6 B | ~579 |
For the full request/response cycle, double the single-frame total. If TCP keep-alive ACKs are counted separately, add 6 × 74 = 444 bytes per keep-alive interval. In practice, ignore keep-alives for steady-state utilization because they only affect the link during idle periods.
CP Module Identification and Specifications
The component referenced in the field report, Siemens material number 2XV9450-1MB11, is the SIMATIC MODBUS/TCP CP application package for the S7-400 family. It pairs with the CP 443-1 communications processor to expose the backplane as a Modbus TCP server or client. Relevant specifications:
| Parameter | Value |
|---|---|
| Ethernet interface | 10/100 Mbit/s, full duplex, RJ45 |
| Number of Modbus TCP connections | Up to 64 (CP-dependent) |
| Supported function codes | 01, 02, 03, 04, 05, 06, 15, 16, 22, 23 |
| Maximum PDU length | 253 bytes (FC 16) |
| Configuration tool | STEP 7 V5.5 SPx with the Modbus/CP option |
| Diagnostic interface | SNMP, STEP 7 online diagnostics, SFC 51 (SSL) |
| Throughput (sustained) | Wire-bound; not CPU-bound for Modbus TCP at the CP |
The CP 443-1 itself is documented in the SIMATIC NET CP 443-1 Manual. The Modbus/TCP option is described in the SIMATIC Modbus/TCP PN Coupler / CP Manual family.
Throughput Calculation Methodology
The theoretical network utilization on a 100 Mbit/s link (10 Mbit/s in older plants) is:
U_% = ( (Σ (N_req_i + N_resp_i) × 8) / T_window ) / B_link × 100
where:
-
N_req_i= wire bytes of request i -
N_resp_i= wire bytes of response i -
T_window= measurement window in seconds -
B_link= link bit rate (100 × 10^6 for Fast Ethernet, 10 × 10^6 for legacy)
Multiply by 100 to convert the decimal ratio to a percent value.
Calculation example: 1000 transactions per second, 100 registers each
Assume 1000 FC 03 reads of 100 registers per second, full duplex, 100 Mbit/s:
Bytes_per_cycle = 2 × (86 + N_data) = 2 × (86 + 2 + 200) = 576 bytes
Total_bits = 1000 × 576 × 8 = 4,608,000 bits/s
U_% = 4.608 × 10^6 / 100 × 10^6 × 100 = 4.608%
That figure represents only Modbus TCP application data; add TCP ACKs (~12% of data bytes for a saturated link) and ARP/ICMP overhead (~0.1% for a quiet network) before comparing to the customer threshold. Most auditors expect the comparison against nominal link capacity, not against application throughput alone, so report:
U_total_% = U_modbus_% × 1.15 (rule-of-thumb including ACKs and protocol overhead)
In the example, that is ~5.3%, well below the 60% ceiling.
CP 443-1 Diagnostics via STEP 7 SFCs
The CP 443-1 exposes its port statistics through the standard SIMATIC SFC 51 (Read System Status List, SSL). On the S7-400, the relevant partial lists are accessed with SFC 51 / SZL_ID combinations such as W#16#0132 (Port statistics) and W#16#00F0 (Module identification). To pull the byte counters from the user program, call:
CALL SFC 51
REQ := TRUE
SZL_ID := W#16#0132 // port statistics list
INDEX := W#16#0001 // port 1 of the CP
RET_VAL := #sfc51_ret
BUSY := #sfc51_busy
SZL_HEADER:= #hdr
DR := #port_stats // 20-byte record per call
Each SSL record contains:
| Byte Offset | Field | Meaning |
|---|---|---|
| 0-3 | Frames received OK | 32-bit counter |
| 4-7 | Frames sent OK | 32-bit counter |
| 8-11 | Octets received OK | Wire bytes received (incl. FCS) |
| 12-15 | Octets sent OK | Wire bytes transmitted |
| 16-19 | Collisions / errors | Quality indicator |
Sample the counters at T_window intervals using OB 35 (cyclic interrupt at 1 s), then compute:
Throughput_bits_per_s = ((ΔRx_octets + ΔTx_octets) × 8) / Δt
U_% = Throughput_bits_per_s / B_link_nominal × 100
Online Measurement with Wireshark
The cleanest measurement path is a SPAN/mirror port on the switch that connects the CP 443-1 to the third-party DCS. Capture for one full DCS scan cycle (typically 1 s, 2 s, or 5 s) and filter on modbus:
tcp.port == 502 && !arp && !dns && !ssdp
Then open Statistics → Conversations → TCP and read the bytes-per-conversation column. The Modbus Poll diagnostic utility (manual: Modbus Poll User Manual) is not required for measurement but is useful when testing point-to-point from an engineering station to validate transaction counts.
For a live readout, use Statistics → I/O Graph with the filter modbus and the Y axis set to Bytes/s. Capture at least 10 cycles and average.
Wireshark CLI alternative
For unattended logging on a plant-floor laptop, run tshark in a loop:
tshark -i eth0 -Y "tcp.port == 502" -T fields \
-e frame.time_epoch -e ip.src -e ip.dst \
-e modbus.func_code -e tcp.len -E header=y -E separator=, \
-a duration:60 -w modbus_capture.pcapng
Open the resulting file in Wireshark → Statistics → Capture File Properties for the byte total. The line rate of the recording interface should be checked with ethtool eth0 before drawing conclusions; a 10 Mbit/s capture on a 100 Mbit/s link truncates frames.
CPU Load Correlation with OB_BEGIN / OB_END
Network utilization is independent of CPU load, but customers often request both figures together. The CFC V8.0 environment allows runtime instrumentation by inserting the F-blocks OB_BEGIN and OB_END at the boundaries of the Modbus TCP handling cycle. Place OB_BEGIN immediately after the diagnostic OB 1 entry and OB_END before the next cycle's body:
// CFC chart: MODBUS_RUNTIME
// Run order: 1
OB_BEGIN (NAME := "MB_TCP_CYCLE", ID := 1001)
// FC calls for Modbus TCP request/response pairs
CALL "MB_CYC_REQ"
CALL "MB_CYC_RESP"
OB_END (ID := 1001)
Each pair writes a delta-time to the WinCC archive tag MB_TCP_CYCLE_MS. The 1-minute average multiplied by the OB 35 period yields the percent CPU load attributable to Modbus TCP. For the S7-400 CPU 416-3, typical values for a 1000 transaction/s loop fall between 12% and 25% of OB 1 time.
Tools and Methods Comparison
| Method | Granularity | Accuracy | Effort | Best Use |
|---|---|---|---|---|
| Manual byte calculation | Static design | ±5% | Low | Capacity planning before deployment |
| SFC 51 SSL counters | OB 35 period | ±2% | Medium | Continuous runtime logging |
| Wireshark SPAN capture | Per-packet | ±0.5% | Medium | Acceptance test, forensic |
| tshark CLI logging | Per-packet | ±0.5% | Medium | Unattended 24-h audit |
| Switch port counter (SNMP) | 15-60 s poll | ±3% | Low | Trend monitoring, dashboard |
| CPU_RT / OB_BEGIN timing | Per cycle | ±1% | High | CPU load report (paired with net load) |
Verification and Acceptance Against 60% Threshold
Follow this commissioning sequence to certify the link against the customer ceiling:
- Build the transaction table in Excel: every Modbus request with FC, register count, period, and computed bytes.
- Compute
U_%using the formula in the throughput section above. Add the 15% overhead multiplier for full-stack Ethernet framing. - Configure the SPAN port on the managed switch. Validate the SPAN destination port with
ethtool. - Capture three full DCS scan cycles in
Wireshark. Average the Bytes/s column for the Modbus filter. - Compare the measured value to the theoretical
U_%. Acceptable deviation: ±10%. - Log the SFC 51 counters for 24 hours, sampling every 5 seconds. Export to WinCC trend and confirm the 99th-percentile value remains below 60%.
- Document the measurement method, capture files, and acceptance certificate in the project's Functional Design Specification (FDS).
Edge Cases and Field-Proven Caveats
Burst vs. average. A DCS that fires 100 FC 16 writes within a single 200 ms window produces a momentary link utilization far above the steady-state average. The customer ceiling should be evaluated against the peak, not the 1-minute mean. Configure OB 35 to 100 ms for burst detection, then revert to 1 s for steady-state logging.
TCP retransmissions. A lossy industrial link can triple the effective byte volume because each retransmission re-ships the full PDU plus the SACK/ACK overhead. If the SFC 51 collision counter rises above 0.1% of frames sent, treat the resulting utilization figure as conservative and re-test on a clean physical layer.
Multicast and LLDP. Many managed switches carry LLDP, EDR, and PROFINET discovery frames on the same physical port. Wireshark captures on a SPAN port will include these. Exclude them from the Modbus filter or subtract their contribution before reporting.
VLAN tagged frames. If the plant routes Modbus TCP over an 802.1Q trunk, add 4 bytes to every wire-frame calculation. This is a frequent source of small discrepancies between theory and measurement.
WinCC V7.2 archive. When trending MB_TCP_CYCLE_MS in WinCC, the default archive cycle is 500 ms. Set the archive cycle to 100 ms for sub-second resolution. Lower cycles increase WinCC server load; on a single ES/OS architecture this is usually acceptable but verify with the OS Performance test.
Cross-Reference: Related Siemens Documentation
- SIMATIC NET CP 443-1 Manual
- Modbus/TCP PN Coupler Manual
- STEP 7 V5.5 SPx Programming Manual
- CFC V8.0 Manual
- Modbus Poll User Manual (third-party test utility)
FAQ
How many wire bytes does a Modbus TCP read of 100 holding registers consume?
A FC 03 read of 100 registers produces approximately 577 wire bytes per request/response cycle on a 100 Mbit/s full-duplex link (86 overhead bytes + 202 payload bytes, doubled for req+resp). Doubled for req+resp gives ~577 bytes per transaction. With a 1 s scan period this represents roughly 4.6 kbit/s of link load.
Does the CP 443-1 report Modbus TCP utilization directly?
No. The CP exposes port-level byte counters via SFC 51 (SSL ID W#16#0132). The application must compute utilization by dividing the measured byte rate by the negotiated link rate. The Modbus TCP protocol layer does not provide a percent-loaded register.
What is the formula for Modbus TCP network utilization percent?
U_% = ( (Σ (N_req_i + N_resp_i) × 8) / T_window ) / B_link × 100, where N_req_i and N_resp_i are the wire-byte lengths of each transaction and B_link is the negotiated line rate in bits per second. Add a 15% overhead multiplier to account for TCP ACKs and protocol traffic.
Can OB_BEGIN/OB_END tags measure CPU load attributable to Modbus TCP only?
Yes. In CFC V8.0, place OB_BEGIN immediately before the Modbus TCP function calls and OB_END after them. The block writes the elapsed time to a WinCC archive tag; dividing by the OB 35 period yields the percent CPU load attributable to the Modbus TCP cycle.
Why does the customer require the network load to stay below 60%?
The 60% rule (also called the 3-to-1 rule of thumb) reserves 40% of link capacity for retransmissions, multicast, broadcast, and burst traffic. Operating above 60% increases collision probability on half-duplex segments and degrades latency on full-duplex segments, which is unacceptable for closed-loop control traffic.