# readBlocking vs readValues

**URL:** <https://forum.inductiveautomation.com/t/readblocking-vs-readvalues/116232>\
**Category:** Ignition\
**Tags:** ignition81, scripting, database\
**Created:** [July 1, 2026, 3:09pm UTC](https://forum.inductiveautomation.com/t/readblocking-vs-readvalues/116232 "2026-07-01T15:09:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bmeyers](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmeyers/32/37453_2.png) [@bmeyers](https://forum.inductiveautomation.com/u/bmeyers)\
**Post date:** [July 1, 2026, 3:09pm UTC](https://forum.inductiveautomation.com/t/readblocking-vs-readvalues/116232/1 "2026-07-01T15:09:58Z")

</div>

Looking for best practices advice and make sure I understand my options better.

A PLC updates two specific registers and then latches a trigger bit telling Ignition data is ready to be stored in the database. I want to guarantee I get the correct data. Is it better to use system.tag.readBlocking or system.opc.readValues to accomplish this?

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

In sticking with best practices is it better to do this on a value changed script on the tag or create a gateway tag change event?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 1, 2026, 3:14pm UTC](https://forum.inductiveautomation.com/t/readblocking-vs-readvalues/116232/2 "2026-07-01T15:14:18Z")

</div>

Gateway tag change event, by a country mile.  
You **must** not run blocking operations in value change scripts - they're run on a built-in pool with only three threads by default and expect to complete ~instantly.

---

<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 1, 2026, 3:19pm UTC](https://forum.inductiveautomation.com/t/readblocking-vs-readvalues/116232/3 "2026-07-01T15:19:44Z")

</div>

You **must** use `system.opc.readValues()` to get everything **other than** the trigger deterministically. `system.tag.readBlocking()` does **not** reach out to the PLC--it simply grabs the latest delivered value(s), which may have been read **before** the trigger change.

And, since `system.opc.readValues()` can stall thread for a substantial time, it is **not safe** to use in tag events (on the tag).

---

<div class="post-metadata">

**Author:** ![bmeyers](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmeyers/32/37453_2.png) [@bmeyers](https://forum.inductiveautomation.com/u/bmeyers)\
**Post date:** [July 1, 2026, 3:23pm UTC](https://forum.inductiveautomation.com/t/readblocking-vs-readvalues/116232/4 "2026-07-01T15:23:51Z")

</div>

So the general idea is create a gateway tag change event, compile the list of tags I want to read, and then use system.opc.readValues() to get them? Will system.opc.readValues wait to get the values before I erase the PLC tags?

```python
# Gateway tag change script
system.opc.readValues(itemPaths=itemPaths)

system.db.runNamedQueries(projectName, nameQueryPath, params)

system.tag.writeBlocking([tagPaths], [0, 0, 0])
```

Is it safe to use writeBlocking in the gateway tag change script then?

Or stick with system.opc.writeValues?

---

<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 1, 2026, 3:32pm UTC](https://forum.inductiveautomation.com/t/readblocking-vs-readvalues/116232/5 "2026-07-01T15:32:18Z")

</div>

`system.opc.readValues()` doesn't take a list of tags. It takes a list of OPC Item Paths. I find it helpful (and most performant) to simply **not have** Ignition tags at all for the OPC items retrieved with `.readValues()`.

I don't recommend wasting bandwidth wiping all of the read values. Simply use an incrementing integer or microsecond timestamp trigger, and echo the latest completed trigger value to a paired PLC tag as the acknowledgement. The PLC should look for trigger==echo to know that it can write a new payload.

It doesn't much matter whether you use `system.opc.writeValues()` or `system.tag.writeBlocking()` to perform the echo. (I would not use `system.tag.writeAsync()`.)
