# Best practice for handling DB writes for multiple UDT tag events safely

**URL:** <https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996>\
**Category:** Ignition\
**Tags:** ignition81\
**Created:** [November 6, 2025, 2:14pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996 "2025-11-06T14:14:11Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![RodrigoR](https://avatars.discourse-cdn.com/v4/letter/r/d78d45/32.png) [@RodrigoR](https://forum.inductiveautomation.com/u/RodrigoR)\
**Post date:** [November 6, 2025, 2:14pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996/1 "2025-11-06T14:14:11Z")

</div>

Hi everyone,

I’m working on Ignition 8.1 and would appreciate some expert advice for tag change event design and database operations. Whether using “Value Changed” tag value event is a viable alternative to a “Tag Change” gateway event script

We have a UDT that’s instantiated around 40 times across different machines.  
Each instance includes a `Reset` tag and a `RuntimeHours` tag.

When maintenance is performed, the operator sets the `Reset = True`.

We are in charge of setting the `Reset = False`.  
At that moment, we need to store the current runtime hours into a database table before the counter is resets.

Right now, I’m handling this using a Gateway Tag Change script that monitors all 40+ tags.

I’m wondering if a more maintainable approach would be to use a Tag Value Change script directly on the Reset tag, something like this:

```python
from com.inductiveautomation.ignition.common.tags.paths.parser import TagPathParser

if not initialChange and previousValue.value==0 and currentValue.value==1:
	value = system.tag.readBlocking(["[.]RuntimeHours"])[0].value
	if value>0:
		query = 'INSERT INTO IOT.maintenance_log (tag_path, runtime_hours, maintenance_date) VALUES (?, ?, ?)'
		tag_path = TagPathParser.parse(tagPath)

		parent_path = tag_path.getParentPath().toStringFull()
		args = [parent_path, value, system.date.now()]
		datasources = ['IoT_Wind']
		system.db.runSFPrepUpdate(query, args, datasources)
		system.tag.writeBlocking(["[.]RuntimeHours"], [0])
	system.tag.writeBlocking(["[.]Reset"], [False])

```

I understand the general recommendation is to avoid performing slow operations (like DB writes) inside tag change events, since this can block the tag event thread pool.

So I’d like to know what the best practice would be here:

1. Wrap the DB call in system.util.invokeAsynchronous() so the tag thread returns immediately
2. Use the Store & Forward system with runSFPrepUpdate() (since it handles temporary DB outages safely)
3. Continue using a single Gateway Tag Change script

Thanks in advance for any insights or recommendations!

---

<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:** [November 6, 2025, 2:52pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996/2 "2025-11-06T14:52:53Z")

</div>

In this case, I'd use (2).

---

<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:** [November 6, 2025, 3:32pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996/3 "2025-11-06T15:32:03Z")

</div>

Further note: it is not safe to use `system.tag.writeBlocking()` with anything other than memory tags within a tag valueChange event. Since you aren't checking the status return value, you can substitute with `system.tag.writeAsync()`.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [November 6, 2025, 7:38pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996/4 "2025-11-06T19:38:40Z")

</div>

> [@RodrigoR](#):
>
> `from com.inductiveautomation.ignition.common.tags.paths.parser import TagPathParser`

Surprised you didn’t mention the import within an event script, @pturmel

I Clauded that one

 ![Screenshot_20251106_073325_Chrome](https://us1.discourse-cdn.com/inductiveautomation/original/3X/3/2/3293e950b3bd37c0bede00698201cc80120b165d.jpeg)

---

<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:** [November 6, 2025, 7:52pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996/5 "2025-11-06T19:52:59Z")

</div>

> [@nminchin](#):
>
> didn’t mention the import within an event script

Didn't notice, actually. The `tag` object handed to a valueChange event already has a `BasicTagPath` attribute, avoid the need to parse the string version.

---

<div class="post-metadata">

**Author:** ![RodrigoR](https://avatars.discourse-cdn.com/v4/letter/r/d78d45/32.png) [@RodrigoR](https://forum.inductiveautomation.com/u/RodrigoR)\
**Post date:** [November 7, 2025, 7:47am UTC](https://forum.inductiveautomation.com/t/best-practice-for-handling-db-writes-for-multiple-udt-tag-events-safely/111996/6 "2025-11-07T07:47:05Z")

</div>

Thanks you both! I ended up removing the import and using the `tag.path` property as suggested — works perfectly.  
Always learning something new here.
