Too many tags in readBlocking?

Is there a limit of how many tags in a single system.tag.readBlocking? If so, I think I might have reached it. The error I'm getting is: "java.util.concurrent.TimeoutException: null"

I'm trying to read 2.2 million tags. What's the tag limit? How many is too many for such a call?

tagPaths = [] #100K tags
columns = ['Enabled', 'TagType', 'DataType', 'AccessRights', 'Documentation', 'Tooltip', 'EngUnit', 'EngHigh', 'EngLow', 'EngLimitMode', 'ScanClass', 'Deadband', 'DeadbandMode', 'HistoryEnabled', 'HistoricalScanclass', 'HistoricalDeadband', 'HistoricalDeadbandMode', 'HistoryMaxAge', 'HistoryMaxAgeMode', 'InterpolationMode', 'OpcItemPath', 'OpcServer']
qvs = system.tag.readBlocking(['%s.%s' % (tagPath, column) for tagPath in tagPaths for column in self.columns])
# 100K tags * 22 columns

There's no explicit quantity limit, but I'm gonna guess you've hit a practical limit. Unless you are trying to do this from the designer or a Vision client, in which case you've probably hit the 60 second timeout on traffic between designer/client and the gateway.

With trying to read 2.2 million qualified values, that gives you 6.6 milliion points of data.
Have you tried using system.tag.getConfiguration()

system.tag.getConfiguration is too slow for what I need. It takes only 1 base path, but I need a list of tags.

It is running this from the gateway script. This is the error on the log.

Scripting[system_util_tag]	09Nov2026 21:58:15	Error during blocking read of tags through scripting.
java.util.concurrent.TimeoutException: null

at java.base/java.util.concurrent.CompletableFuture.timedGet(Unknown Source)

at java.base/java.util.concurrent.CompletableFuture.get(Unknown Source)

at com.inductiveautomation.ignition.gateway.script.GatewayTagUtilities.readBlockingImpl(GatewayTagUtilities.java:246)

at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.readBlocking(AbstractTagUtilities.java:510)

at jdk.internal.reflect.GeneratedMethodAccessor90.invoke(Unknown Source)

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.base/java.lang.reflect.Method.invoke(Unknown Source)

at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)

at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:553)

at org.python.core.PyObject.__call__(PyObject.java:461)

at org.python.core.PyObject.__call__(PyObject.java:465)

at org.python.pycode._pyx266356.export$7(:97)

at org.python.pycode._pyx266356.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:173)

at org.python.core.PyBaseCode.call(PyBaseCode.java:168)

at org.python.core.PyFunction.__call__(PyFunction.java:437)

at org.python.core.PyMethod.__call__(PyMethod.java:156)

at org.python.pycode._pyx266352.cache_tags$18(:548)

at org.python.pycode._pyx266352.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:173)

at org.python.core.PyBaseCode.call(PyBaseCode.java:187)

at org.python.core.PyFunction.__call__(PyFunction.java:449)

at org.python.core.PyMethod.__call__(PyMethod.java:171)

at org.python.pycode._pyx266352.cache_provider_configs$15(:486)

at org.python.pycode._pyx266352.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:173)

at org.python.core.PyBaseCode.call(PyBaseCode.java:306)

at org.python.core.PyBaseCode.call(PyBaseCode.java:158)

at org.python.core.PyFunction.__call__(PyFunction.java:437)

at org.python.core.PyMethod.__call__(PyMethod.java:156)

at org.python.pycode._pyx266370.handleMessage$1(:10)

at org.python.pycode._pyx266370.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:173)

at org.python.core.PyBaseCode.call(PyBaseCode.java:306)

at org.python.core.PyFunction.function___call__(PyFunction.java:474)

at org.python.core.PyFunction.__call__(PyFunction.java:469)

at org.python.core.PyFunction.__call__(PyFunction.java:464)

at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:847)

at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:829)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:868)

at com.inductiveautomation.ignition.common.script.message.MessageHandlerRunnable.run(MessageHandlerRunnable.java:121)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

If there is a limit, it would be nice to know what that is, so I can slice the list of tagpaths into a smaller list.

You've hit a timeout, so as PTurmel says, there is no "limit", however depending on hardware this will take too long and hit a timeout limit. We can't answer the value of how many to batch this down to because it is very dependent on your hardware/network. Running this on a Raspberry Pi or a datacenter cluster will give very different results. 2.2 million tags might be OK for a cluster, but 1000 tags may be too much for a RPi.

What you will have to do is testing on your side to determine how many tags you can read without overloading your network/server, then add in some margin and set that as your batching value (and gracefully handle any Timeout's with a retry on smaller batches).

Dare I ask...why?

What's the Y problem you're trying to solve with this X task statement?