Resolving Ignition 8.3 Memory Tag Persistence Resets

Ryan Tanaka9 min read
HMI / SCADAOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

After a gateway restart or an 8.1-to-8.3 upgrade, memory tags in the Tag Browser show their default value, or a value you overwrote weeks ago, instead of the last value written. In 8.3 that comes down to five causes:

  • the tag's Value Persistence mode
  • a missing or stale value store file
  • the tag being a UDT member rather than an atomic tag
  • an upgrade migration miss on nested UDTs with a parameter-bound data type
  • Configuration persistence being used for tags that change too often

Work the checks in order. The first one takes thirty seconds and settles most calls.

Match the symptom to the likely cause

What you see Most likely cause Go to
Every restart resets the tag to the same value Effective Value Persistence is None Check 1
Tags show default values right after copying config to a new gateway valueStore.idb not copied, or it has no record for these tags Check 2
Tags created after a backup show defaults once that backup is restored Older value store restored from before the tags existed Check 2
Editing the Default Value property does nothing on UDT members UDT members take their default from the definition or instance override Check 3
After upgrade, most memory values survived but some nested UDT instances lost theirs Parameter binding on the UDT Data Type Check 4
Values persist, but the gateway slows under frequent memory tag writes Configuration persistence rewriting whole tags.json files Check 5

Check 1: Read the effective Value Persistence on the tag and its provider

Open the memory tag in the Designer tag editor and read Value Persistence. A new tag defaults to Inherited. That means it takes whatever Value Persistence is set on the tag provider in the gateway configuration. Read both settings. The tag-level setting alone tells you nothing when it says Inherited.

Each mode stores the live value in a different place:

  • None: nothing is stored. On every restart the tag loads its Default Value. This is the only mode where Default Value controls normal startup behavior.
  • Database: the live value goes to a separate SQLite value store, data/config/ignition/tags/valueStore.idb. Only the tag system uses it. The tag's tags.json entry holds defaultValue and has no value field.
  • Configuration: the live value is written into the tag configuration file itself. This is closest to how 8.1 behaved, where the persisted value appeared in the tag config.

The provider default is Database. An upgrade from 8.1 also sets the provider to Database. So if you find None, someone set it deliberately, either on the provider or as a tag-level override.

  • Effective mode is None and the tag must survive restarts: change it to Database and stop here. Values written after the change persist. Values lost earlier have to be re-entered or restored (see the final section).
  • Effective mode is Database: go to Check 2.
  • Effective mode is Configuration: values should survive restarts. If they do but performance suffers, go to Check 5. If they don't survive, go to Check 3.

Check 2: Confirm valueStore.idb exists and holds a record for the tag

Under Database persistence, Default Value is the fallback. The tag loads it when the value store is missing, or when the store has no record for that particular tag. Two field situations cause this.

  1. Config moved without the value store. 8.3 keeps tag configuration in flat files, such as tags.json and udts.json per folder. Copying those files to another gateway, or pulling them from version control, brings the configuration only. If valueStore.idb did not come along, every Database-persisted memory tag starts at its default. When you are promoting from test to production, this is the intended result.
  2. Older value store restored. A gateway backup or file restore made before certain tags were created has no rows for them. Those tags fall back to Default Value, while older tags come back with their stored values.

How to decide:

  • Confirm data/config/ignition/tags/valueStore.idb exists on the gateway. If it does not, the defaults you are seeing are correct fallback behavior. Restore the file from the source gateway if you need the live values, or re-enter them.
  • If the file exists, check whether the affected tags share a creation date later than the restored backup. If they do, the missing records explain it.
  • If the file exists, the tags are old, and they still show defaults, go to Check 3.

Do not hand-edit the value store to fix this. Restore it, or write the values back through the tag system.

Check 3: Separate atomic memory tags from UDT members

The 8.3 defaultValue property applies only to individual atomic memory tags. Memory tags inside a UDT, whether in the definition or an instance, behave as they did in 8.1:

  • the default value comes from the UDT Definition
  • an instance overrides it at the instance level

This explains a common wasted hour. You set a default on what looks like a standalone tag, it has no effect, and the tag turns out to be a UDT member.

  • Tag is atomic: Checks 1 and 2 cover it. If it still misbehaves, capture the tags.json entry and the provider settings, then escalate.
  • Tag is a UDT member: check the definition default and any instance override. If this is a post-upgrade loss on a nested UDT, go to Check 4.

Check 4: Trace upgrade losses to parameter-bound Data Types in nested UDTs

In a normal 8.1-to-8.3 upgrade with provider persistence set to Database, memory tag values carry over, including those in nested UDTs. There is one known failure pattern. Nested UDT instances whose Data Type had a parameter binding lost their memory tag values after the upgrade, while the rest of the provider migrated cleanly.

Two points save you time here:

  • Removing the binding and upgrading again did not fix it. In one case the gateway was rolled back to 8.1, the binding deleted, the gateway restarted and confirmed working, and then upgraded to 8.3 again. The same values were lost. Do not spend a maintenance window repeating the upgrade.
  • Importing a tag export taken on the working 8.1 gateway fixed it. That export carries the correct values. Import it into 8.3 and the affected instances recover.

Binding the Data Type of a UDT member to a parameter is fragile design, and this migration case is one more reason to avoid it. Once you have recovered, replace parameter-bound data types with fixed types, or with separate member tags per type.

Check 5: Move frequently written tags off Configuration persistence

Configuration persistence writes the live value into the tag configuration file. Each tags.json or udts.json holds the full configuration of every tag in that folder. Every value write therefore makes the gateway recreate the whole file. That is acceptable for a setpoint changed once a shift. It is not acceptable for counters, status flags, or anything written by scripts on a timer.

  • Use Configuration only for values that change very infrequently and that you want visible in the config files and version control.
  • Use Database for everything else. This is why the separate value store exists: writing atomic tag updates to thousands of individual files cannot keep up.
  • Use None only when you want the tag to start from its default on every restart.

Configuration-persisted tags rarely hit the Default Value fallback, because the value lives in the same file as the configuration.

Promote tag config between environments without carrying test values

Default Value exists partly for this job. Commissioning on a test gateway leaves memory tags holding whatever values testing produced, and you do not want those in production. Under Database persistence:

  1. Set defaultValue on each atomic memory tag to the value you want production to start with.
  2. Copy or commit only the tag configuration files, such as tags.json.
  3. Leave the test gateway's valueStore.idb behind.
  4. On the target gateway, tags with no value store record start at defaultValue.
  5. If the target already has a value store with records for those tags, the stored values win. Clear or overwrite those tag values deliberately rather than expecting the default to apply.

There is no built-in command to copy current runtime values into defaultValue. If you want commissioned values promoted as defaults, script it for atomic memory tags. This does not work for UDT members; change those at the definition or instance level instead.

# Jython, gateway or Designer script console. Run on a dev gateway first.
# Tag paths are placeholders - replace with your atomic memory tags.
paths = ["[default]Line1/Setpoint", "[default]Line1/BatchSize"]
values = [qv.value for qv in system.tag.readBlocking(paths)]
system.tag.writeBlocking([p + ".defaultValue" for p in paths], values)

After running the script, open the folder's tags.json and confirm each entry's defaultValue changed. If the property write did not land, change the property through the tag editor or system.tag.configure.

Restore lost values and prove persistence with a restart test

For the resolving branch, whether that was a None override corrected, a missing value store, or the nested UDT upgrade loss:

  1. Before any 8.1-to-8.3 upgrade, export the full tag provider from the 8.1 gateway and archive it. It is your recovery path for Check 4.
  2. Correct the cause. Set the provider or tag to Database, restore valueStore.idb, or remove parameter-bound data types.
  3. Restore values. For upgrade losses, import the pre-upgrade 8.1 tag export into the 8.3 provider. For environment moves, write production values directly or promote them through defaultValue.
  4. Pick three to five test tags: one atomic memory tag, one simple UDT member, and one nested UDT member that was affected. Write a distinctive non-default value to each.
  5. Restart the gateway.
  6. Read the tags. All of them should hold the written values. Any tag showing its default points back to Check 1 (effective mode None) or Check 2 (no value store record).
  7. For Database-persisted atomic tags, open tags.json. It should show defaultValue and no value field. If you see a value field, the tag is actually using Configuration persistence.

FAQ

How do I check which value persistence an Ignition 8.3 memory tag actually uses?

Open the tag's Value Persistence property. If it reads Inherited, check the tag provider's Value Persistence in the gateway configuration. The provider default, and the setting applied on upgrade from 8.1, is Database.

How do I move memory tags from test to production without copying test values?

Set defaultValue on the atomic memory tags, then copy only the tag configuration files and leave valueStore.idb behind. Database-persisted tags with no value store record start at their default value. UDT members still take their defaults from the definition or instance override.

When should I contact Inductive Automation support about lost memory tag values?

Escalate when values are lost with an effective Database setting, a present valueStore.idb, and tags older than any restored backup. Escalate the same way if nested UDT values fail again after a re-upgrade. Send Inductive Automation support the UDT definition exports and the pre-upgrade 8.1 tag export so they can reproduce the problem, and restore production from that export in the meantime.

Back to blog