Home / C# / How fast is a PLC driver with C#?

How fast is a PLC driver with C#?

This post comes as a response to a recent comment on my YouTube channel.

Hello Michele,
I’m interested how fast would be your HMI application in case to communicate with 5-10 CPU connections, and around 4k-15k Tags?
Do you have had something like that?

We can start by making a distinction between the presentation layer and the data layer. By presentation layer I mean the user interface and the graphical part. By data layer I mean plc drivers, services, database and every data provider that our application is accessing.

Speed of presentation layer

As for the presentation layer (WPF), a lot of UI applications where performance and responsivity matter are based on WPF. Just think about finance, stock-trading, Visual Studio itself.
Here is an interesting video on usage of WPF in enterprise: https://www.lynda.com/Visual-Studio-tutorials/Examples-WPF-applications/518697/554167-4.html

For example in finance applications, the requirements are to gather a lot of data from the servers, aggregate and present them in advanced UI that are as fast and responsive as possible, with failure rate near zero.

If you go with WPF you can achieve a very nice and responsive UI, also with personalized controls, because it’s easy to personalize. At the moment WPF is the best framework at the moment to develop rich Windows applications, which means that you can get the best that your designers can conceive.

Speed of data layer

As for the data layer, it depends on what technology we choose to communicate. By using C# we can choose among OPC servers, open source libraries and eventual proprietary libraries.

The difference between a library and an OPC server regards the optimization.

If you use a communication library you are responsible for optimizing the reads to reduce the number of requests to the plc.
If you use an OPC server, which is a software staying between the HMI and the PLC, you use its OPC API to connect your HMI to the PLC. The responsibility of OPC server is also to hide the complexity of the protocol and to optimize the requests to the plc based on its configuration (groups, poll rate, number of tags, number of plc).

Given that we have no control over an OPC server, let’s talk about performance of open source libraries.

For the most (all?) plcs there is the need to poll for the data, instead of data being pushed directly from the plc once the data change.

In this case to measure the performance we have to measure the time for a single request to the plc under various circumnstances, like when reading single data, multiple data, consequent data, arrays, etc…

In case of a network of 10 plc to be polled and 15k tags to be gathered, we have to create 10 independent plc services, every one of which will poll a single plc in its own thread, with no impact on the UI. In this case the “data-refresh” performance is determined by the “worst case scenario”, which is the plc that requires the highest number of TCP requests to get all data.

Also with so many plc, we should take in consideration the network loading, to prevent the bandwidth saturation. Sometimes we are forced to reduce the polling rate to avoid the network saturation. This depends heavily on the communication protocol and the number of data exchanged.

Benchmarking NModbus on real equipment

Let’s see how to write some code to benchmark the NModbus library (that can also be used for Siemens PLC) and test it on a Real plc.

Here is the setup:

  • MicroLogix 1400 connected to my home router with an ethernet cable.
  • PC connected to my home router with an ethernet cable.
  • The router has at least 6 devices connected.

To test the speed of the communication I will not use a profiler, because I don’t need such a great accuracy. Instead I will use StopWatch, which is the most precise timer that’s available on .Net.

Here is the code when using NModbus4:

using (TcpClient client = new TcpClient("", 502))
    ModbusIpMaster master = ModbusIpMaster.CreateIp(client);

    // read five input values
    ushort startAddress = 0;
    // Create new stopwatch.
    Stopwatch stopwatch = new Stopwatch();

    for (int i = 0; i < 10; i++)

        // Begin timing.

        // Execute the function to benchmark
        var registers = master.ReadHoldingRegisters(1, startAddress, 123);

        // Stop timing.

        // Write result.
        Console.WriteLine("Read Time elapsed: {0}", stopwatch.Elapsed);

    var buffer = new ushort[121];
    for(int i = 0; i < buffer.Length; i++)
        buffer[i] = (ushort)i;

    for (int i = 0; i < 10; i++)

        // Begin timing.

        // Execute the function to benchmark
        master.WriteMultipleRegisters(1, startAddress, buffer);

        // Stop timing.

        // Write result.
        Console.WriteLine("Write Time elapsed: {0}", stopwatch.Elapsed);

And the results:

We must remove the first line because of the JIT (just in time compiler).
So by looking just at the worst case scenario, the read time for 123 consecutive tags is 3ms. To write 123 tags I need 4ms.
Pretty impressive I would say.

Real applications

In a recent machine I was polling through OPC-XML-DA (another TCP protocol like S7 and Modbus, not an OPC server) from a single Simotion unit around 3k tags on 2 HMI.

The scan time was around 200ms and it needed a bit more than 100ms to be executed. So this means 5 refreshes every seconds to all the data. The data on the plc were optimized in arrays and structs, because of the poor optimization of the communication protocol itself (it’s an xml based protocol, where a lot of useless data were being transmitted, like full names of tags).
The poor optimization of the protocol was causing a lot of network traffic. Maybe that’s one of the reasons why OPC-XML-DA was not developed any further by OPC Foundation.

In another previous application, we were communicating with 6-7 plcs on the field, but the architecture was with 1 master plc (ControlLogix) connected to the other 6 plcs (MicroLogix) on the field on WiFi (except for the safety cables). In that case the data aggregation happened in the plc, rather than the HMI, and the communication was only between the HMI and the Master plc.
Communication via OPC server, around 6k tags, refresh time of 1 second and good network balance.
For that kind of application it wasn’t important to optimize it more.

For simple applications, like 1 plc and 1 hmi, I usually use a refresh time of 100ms. That’s my default scan rate.

So how fast is the plc application?

To wrap up, regarding the User Interface part, with WPF you are choosing the best technology available at the moment to develop Windows applications.
As for the driver you can choose between OPC servers or external libraries.
In case of external libraries, the driver is as fast as you can optimize the data that you have to read.
The less TCP requests you do, the faster your refresh time can be. But always take into account the network balance in case of multiple plc.


  1. In your speed test, you are only “stop watching” the WriteMultipleRegisters execution time, not the time for the write, the PLC to acknowledge, and being ready for the next write. Using a Wireshark capture to see the full round trip time stamps will expose some more true times. From my experience an ML1100 will round trip on an average of 8-10ms for a read.

    If comparing to OPC, that can be misleading also. If the OPC driver caches data, a read of 1000 registers may seem to happen in a few ms, but in reality the data may have already been read into local memory and the read is only returning old data. Hence it is important to check the quality of the data.

    • Hey Archie, thanks for your reply.
      Regarding reads and writes you are correct, I should have taken in consideration the whole roundtrip, but thanks to confirm that we are under 10 ms.
      I didn’t do any comparison with OPC servers on purpose. It should be the OPC vendor that should compare his product performance against the open source libraries.

  2. Great post. I went to school for EE and have a career in Controls Engineering. It has made me really want to get into more software application type programming but it seems like there is so much to it. I have a much better idea of how software works. Thanks so much!!!

Leave a Reply