# Write Multiple OPC tags - Slow Response

**URL:** <https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [July 1, 2025, 6:00am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968 "2025-07-01T06:00:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 1, 2025, 6:00am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/1 "2025-07-01T06:00:07Z")

</div>

Hello everyone,

I'm trying to read bulk 500 derived tags and write bulk OPC tags as fast as I can.

First, I tested reading **Derived** tags and writing into **Memory** tags.

- Using `system.tag.readBlocking` and `system.tag.writeBlocking` - It took around 4s.
- Using `system.tag.readBlocking` and `system.tag.writeAsync` - it took around 100ms (which is perfect!)

To measure I used `system.date.now()`. For `writeBlocking` I printed end time after execution, while to measure `writeAsync` I used a callback function to print end time.

Now, when writing to **OPC** tags

- Using `system.tag.readBlocking` and `system.tag.writeBlocking` - It took around 50 - 60s.
- Using `system.tag.readBlocking` and `system.tag.writeAsync` - it took around 40 - 50s
- Using `system.tag.readBlocking` and `system.opc.writeValues` - it took around 30 - 40s

How can I improve this behaviour? I'm writing to an Open ModSim Server from Ignition 8.1.48 Edge.

The OPC connection has default configurations

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/b/8b0552b299a42603cb337abf0fe2a32597d04421.png)

OPC tags are configure with this Tag Group

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/d/b/dbe5a23c43cb4e5030bdea35868aaa036d1b7175.png)

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 1, 2025, 12:01pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/2 "2025-07-01T12:01:11Z")

</div>

> [@David\_Lopez](#):
>
> Using `system.tag.readBlocking` and `system.tag.writeAsync` - it took around 100ms (which is perfect!)

No it didn't. You're not "Timing" what you think you're timing.

Fundamentally, the only difference between `writeBlocking()` and `writeAsync()`, is that the system doesn't wait around for the return telling you if the writes were successful or not. Instead firing the write command and returning instantly.

You only timing the execution time of the script that you wrote, which not suprisingly took longer when you blocked it from continuing.

Also, remeber when writing to OPC tags, `system.tag.write*()` doesn't actually write to the device.

> [@David\_Lopez](#):
>
> Using `system.tag.readBlocking` and `system.tag.writeBlocking` - It took around 50 - 60s.

This seems like forever, for 500 tags. My gut reaction to this execution time is that their is an issue with the script that you're using. Please share the script, as I really do not think these times have anything to do with the driver or tag configuration.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 1, 2025, 1:14pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/3 "2025-07-01T13:14:17Z")

</div>

You might want to share some code and more about your Modbus setup (Addresses used, etc...)

---

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 2, 2025, 2:30am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/4 "2025-07-02T02:30:28Z")

</div>

This is the code for `writeAsync` and **OPC tags** and how I measure execution the time

```python
def update():
    # Browse UDT instances
    udt_name = "point_2v1"
    tag_provider = "[edge]"
    filter_tags = {"tagType":"UdtInstance","typeId":udt_name,"recursive":True}
    browse_results = system.tag.browse(tag_provider,filter_tags).getResults()
    
    #Define input/output tag paths
    udt_instances = [str(res["fullPath"]) for res in browse_results]    
    input_paths = [str(inst) + "/inputValue" for inst in udt_instances]
    output_paths = [str(inst) + "/outputValue" for inst in udt_instances]
    
    #Read input values
    write_values = system.tag.readBlocking(input_paths)
    values_list = [val.value for val in write_values]
    
    #Write output values
    system.tag.writeAsync(output_paths, write_values,myCallback)

def myCallback(asyncReturn):
	print ("End time: {} ms".format( system.date.now()))

# Run the function
import system
print("Start time: {} ms".format( system.date.now()))
update()

```

The Start time is printed on the script console while the End time is printed on the output console once the operation was complete. This time took 20s to write 480 OPC tags.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/7/f7e62e250c55c702e78895b63b7c9168b8357826.png)

For `writeBlocking` I just replace this part of the code, and both Start/End time are printed on scripting console.

```python
 #Write output values
 system.tag.writeBlocking(output_paths, write_values)
 print ("End time: {} ms".format(system.date.now()))

```

**Modbus Setup Description Using Ignition OPC UA server:**

The Modbus setup consists of a single Modbus TCP connection to a locally installed Open ModSim server. Both the Edge Gateway and the ModSim server are hosted on the same local machine.

The Edge Gateway is configured with 500 UDT instances. Each UDT instance contains two tags: one Derived tag and one OPC tag. These OPC tags correspond to Modbus Holding Registers (Int, Float, Double), mapped sequentially from address 1.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/d/fdf3b5feffc9cb73f96b9bdbd159458b17459ed4.png)

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 2, 2025, 2:52am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/5 "2025-07-02T02:52:59Z")

</div>

You're including the tag browse in your timing. Have you measured without that?

---

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 2, 2025, 3:23am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/6 "2025-07-02T03:23:36Z")

</div>

Yes! I've measured even without all `for` loops for tagPath creation and there's no big difference

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 2, 2025, 3:29am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/7 "2025-07-02T03:29:20Z")

</div>

Can you take a Wireshark capture?

This is more or less instant when I try it.

```python
from java.lang import System

start = System.currentTimeMillis()

# Browse UDT instances
udt_name = "MbTest"
tag_provider = "[default]"
filter_tags = {"tagType":"UdtInstance","typeId":udt_name,"recursive":True}
browse_results = system.tag.browse(tag_provider,filter_tags).getResults()

print browse_results

#Define input/output tag paths
udt_instances = [str(res["fullPath"]) for res in browse_results]    
input_paths = [str(inst) + "/I" for inst in udt_instances]
output_paths = [str(inst) + "/O" for inst in udt_instances]

#Read input values
input_values = system.tag.readBlocking(input_paths)
output_values = [val.value for val in input_values]

#Write output values
print system.tag.writeBlocking(output_paths, output_values)

print ("Duration: {} ms".format(System.currentTimeMillis() - start))

```

```python
>>> 
(snipped prints)
Duration: 190 ms
>>> 

```

---

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 2, 2025, 5:36am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/8 "2025-07-02T05:36:34Z")

</div>

That is amazing!

How many OPC tags are you writing? Are you using Ignition OCP UA Server? Could you share more details about your test please.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 2, 2025, 11:39am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/9 "2025-07-02T11:39:21Z")

</div>

500 OPC tags from 500 instances of the following UDT, Ignition OPC UA server.

UDT definition:

 ![Screenshot 2025-07-02 at 04.39.02](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/8/a84d9a0a31137fbdecfa9eb511ba7e764079abea.jpeg)

---

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 2, 2025, 2:31pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/10 "2025-07-02T14:31:00Z")

</div>

This is my UDP config, the only differences I see

1. Different data types (Integer, Float, Double) which means different modbus designators and not consecutive registers
2. I'm using parameters.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/6/b668ba4165c572d4b33bd7ae5ba4bf18a3065cd2.png)

While this is the OPC connection

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/2/e28e95fd1054ef5c03b5694421504d5e44dc9215.png)

When I run the same code as you, I have this result:  
First, I check the initial values for HR1 and HR1103 in Ignition and Open ModSim Server.  
Then executed the script and once it finishes check the new values HR1 and HR1103. This time took 33sec.

![java_XQLba9TqMW](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/f/2feca655c99c495fb3ee38636b490dc5284e67c1.gif)

I try to configure each OPC tag as Integer and consecutive, but I see this error message on Gateway Logs

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/c/eccf32d47106e88cd0290454d79901763e58a1d9.png)

What software do you use to simulate a Modbus Device and create your connection? I only have experience with Open ModSim

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 2, 2025, 2:36pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/11 "2025-07-02T14:36:37Z")

</div>

> [@David\_Lopez](#):
>
> What software do you use to simulate a Modbus Device and create your connection?

Something custom based on my Modbus library.

> [@David\_Lopez](#):
>
> but I see this error message on Gateway Logs

This might mean you are writing to an address the simulator you're using doesn't consider valid.

It would help if you could get a Wireshark capture of the writes.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 2, 2025, 2:38pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/12 "2025-07-02T14:38:47Z")

</div>

Ooh, or this could be a bug in the driver... I kind of remember something about the max number of registers to write actually being 123 and not 125...

Try setting the "Max Holding Registers Per Request" setting on the driver to 123 instead. The bug was that it's supposed to be 125 for reads and 123 for writes, but the driver only has one shared setting that is wrong for writes.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 2, 2025, 2:42pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/13 "2025-07-02T14:42:56Z")

</div>

> [@Kevin.Herron](#):
>
> only has one shared setting that is wrong for writes.

Huh. Never noticed this. (Mine has separate settings.)

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 2, 2025, 2:48pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/14 "2025-07-02T14:48:13Z")

</div>

Yeah... it should be two on ours as well.

It's rare that you ever have writes packed so well that you fill out a request, and then I think on top of that some servers will happily accept 125 registers in a write, because it does actually fit when you're doing Modbus TCP without any regard for the size limit inherited from the original serial implmentation. I think you can fit 127 before you overflow the "Byte Count" byte in the request.

But the spec limits it to 123 so the overall PDU/ADU doesn't exceed 256 bytes, even though that doesn't matter on Modbus TCP.

---

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 2, 2025, 3:28pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/15 "2025-07-02T15:28:04Z")

</div>

Thank you for your fast response!

After setting **Max Holding Registers Per Request** to 123

- Writing to 500 OPC tags (Integer, Float, Double) with no consecutive registers - took 42sec.
- Writing to 500 Integer OPC tags with consecutive registers - took 3.7 sec (it stills high)

I will try to get Wireshark capture

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 2, 2025, 3:37pm UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/16 "2025-07-02T15:37:45Z")

</div>

Too bad this is Edge. You could use my Integration Toolkit's Republish action to do this without a script. Unless you buy my alternate Modbus driver for Edge, which gives me an opportunity to include the Toolkit....

/shameless plug

😁

---

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 3, 2025, 1:31am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/17 "2025-07-03T01:31:57Z")

</div>

Is there any other way to pass the `inputValue` to the `outputValue` without scripting but using derived tags ?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 3, 2025, 1:42am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/18 "2025-07-03T01:42:56Z")

</div>

Not that I'm aware of. That's why I added Tag Actions to my toolkit module.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 3, 2025, 1:51am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/19 "2025-07-03T01:51:53Z")

</div>

Ever get that Wireshark capture?

Even when I modify mine so the registers have gaps and the driver has to do 500 separate Write Single Register requests it only takes 500-600ms.

---

<div class="post-metadata">

**Author:** ![David\_Lopez](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@David\_Lopez](https://forum.inductiveautomation.com/u/David_Lopez)\
**Post date:** [July 3, 2025, 3:18am UTC](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968/20 "2025-07-03T03:18:04Z")

</div>

It's my first time using Wireshark, so let me know if it's okay.

Now I'm using Modbus Slave instead of Open ModSim which improved writing to 17sec.  
After running wireshark I only saw **Write Single Register** requests.  
[Test 1.pcapng](https://forum.inductiveautomation.com/uploads/short-url/bZIqa3LneQbHSTc3Fx7KrricET3.pcapng) (841.0 KB)

During Test 2 I enabled **Force Multiple Register Writes** but it took 17sec as well.  
[Test 2.pcapng](https://forum.inductiveautomation.com/uploads/short-url/8cFjhx0vw4g9Ko5YKg1b1txxdiW.pcapng) (720.6 KB)

[Next page](https://forum.inductiveautomation.com/t/write-multiple-opc-tags-slow-response/107968.md?page=2)
