# Faulty Database Connection (Idle Object)

**URL:** <https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024>\
**Category:** Ignition\
**Tags:** ignition81, database\
**Created:** [December 30, 2025, 2:54pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024 "2025-12-30T14:54:44Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [December 30, 2025, 2:54pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/1 "2025-12-30T14:54:44Z")

</div>

I have an MSSQL database connection that is working fine for the most part but it will occasionally fault out for a very short amount of time (less than 1 second) and then reconnect. This doesn’t really cause issues unless there’s a query in the GUI that is pulling from the database when it does this. Then, I get pesky error messages.

Are there any settings in the database connection that might help mitigate this issue?

---

<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:** [December 30, 2025, 3:15pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/2 "2025-12-30T15:15:44Z")

</div>

Maybe. There are a number of possible causes, some of which can be helped with settings.

- Network flakiness. If a network link or firewall is breaking your connections, there's nothing that can be done within Ignition. Get your IT to diagnose this (wireshark) and address it.

- Slow query stalls. If you fire several slow queries at the same time, you will exhaust the connection pool. Everything else will have to wait for one of the pooled connections to free up, and there's a timeout for that. (Might be the pesky errors. You should show an example.) This is common when your historian tables do not have proper indices, or you are simply allowing larger history queries than your DB can really handle. This can sometimes be mitigated by increasing the connection pool size.

- DB throughput stalls. If you have a wimpy database for your application, you can get stalls on inserts and updates, too, not just large queries. If this is the case, increasing the connection pool size will usually make it **worse** , so don't blindly do that.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [December 30, 2025, 3:16pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/3 "2025-12-30T15:16:42Z")

</div>

I just looked at the log after the latest fault.

```python
java.sql.SQLException: Cannot get a connection, pool error Timeout waiting for idle object

at org.apache.commons.dbcp2.PoolingDataSource.getConnection(PoolingDataSource.java:142)

at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:734)

at com.inductiveautomation.ignition.gateway.datasource.DatasourceImpl.getConnectionInternal(DatasourceImpl.java:300)

at com.inductiveautomation.ignition.gateway.datasource.DatasourceManagerImpl.getConnectionImpl(DatasourceManagerImpl.java:169)

at com.inductiveautomation.ignition.gateway.datasource.DatasourceImpl.getConnection(DatasourceImpl.java:293)

at com.inductiveautomation.ignition.gateway.datasource.DatasourceManagerImpl.getConnection(DatasourceManagerImpl.java:152)

at com.inductiveautomation.gateway.tags.history.processing.GatewayContextConnectionProvider.getConnection(GatewayContextConnectionProvider.java:31)

at com.inductiveautomation.gateway.tags.history.processing.GatewayContextConnectionProvider.getConnection(GatewayContextConnectionProvider.java:10)

at com.inductiveautomation.gateway.tags.history.query.DatasourceHistoryInterface.getConnection(DatasourceHistoryInterface.java:77)

at com.inductiveautomation.gateway.tags.history.query.DatasourceHistoryInterface.maybeLoadIds(DatasourceHistoryInterface.java:96)

at com.inductiveautomation.gateway.tags.history.query.DatasourceHistoryInterface.getSystemId(DatasourceHistoryInterface.java:159)

at com.inductiveautomation.gateway.tags.history.query.DatasourceQueryExecutor.initialize(DatasourceQueryExecutor.java:544)

at com.inductiveautomation.ignition.gateway.sqltags.history.query.AggregateHistoryQueryExecutor.initialize(AggregateHistoryQueryExecutor.java:78)

at com.inductiveautomation.ignition.gateway.sqltags.history.query.HistoryWriter.initLoader(HistoryWriter.java:141)

at com.inductiveautomation.ignition.gateway.sqltags.history.query.HistoryWriter.execute(HistoryWriter.java:211)

at com.inductiveautomation.ignition.gateway.sqltags.history.TagHistoryManagerImpl.queryHistory(TagHistoryManagerImpl.java:572)

at com.inductiveautomation.ignition.gateway.tags.model.ProjectDefaultTagManagerFacade.queryHistory(ProjectDefaultTagManagerFacade.java:440)

at com.inductiveautomation.ignition.gateway.servlets.gateway.functions.QueryTagHistory.invoke(QueryTagHistory.java:102)

at com.inductiveautomation.ignition.gateway.servlets.Gateway.doPost(Gateway.java:435)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:523)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)

at com.inductiveautomation.ignition.gateway.bootstrap.MapServlet.service(MapServlet.java:86)

at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410)

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)

at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570)

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543)

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at com.inductiveautomation.catapult.handlers.RemoteHostNameLookupHandler.handle(RemoteHostNameLookupHandler.java:121)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:301)

at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)

at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:141)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.server.Server.handle(Server.java:563)

at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:505)

at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:762)

at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:497)

at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282)

at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)

at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)

at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:416)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:385)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:272)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.lambda$new$0(AdaptiveExecutionStrategy.java:140)

at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)

at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)

at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)

at java.base/java.lang.Thread.run(Unknown Source)

Caused by: java.util.NoSuchElementException: Timeout waiting for idle object

at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:321)

at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:428)

at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:232)

at org.apache.commons.dbcp2.PoolingDataSource.getConnection(PoolingDataSource.java:134)

... 62 common frames omitted

```

---

<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:** [December 30, 2025, 3:18pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/4 "2025-12-30T15:18:03Z")

</div>

OK. You now have to study your database performance to see **why** you are exhausting the pool. Look at the diagnostics for slow queries first.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [December 30, 2025, 3:41pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/5 "2025-12-30T15:41:31Z")

</div>

I am dynamically building 5 tag history bindings (queries) when a window opens via indirect bindings on some internal props. I think the issue is that the tag history binding tries to run before those indirect properties are “ready” so it’s grabbing _way_ too much data.

For instance:

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

`trendStart` (result = 12/30/2025 08:42:30 -0600):

```python
try(sortDataset({Starter Diagnostics.startTimes},0,0)[0,0],0)

```

`trendEnd` (result = 12/30/2025 08:45:30 -0600):

```python
try(dateArithmetic({Starter Diagnostics.trendStart1},{Starter Diagnostics.trendWindow},'sec'),0)

```

(`trendWindow` = 165)

`startTimes`:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/5/4/540acf979287f07143c1ee80e03ff6d814eb5cc9.png) ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/8/f844116c2760a64052d28a1b9d320dd7ebc5e871.png)

(the 0 is used to index the “start” of the values so the script that updates these tags knows where it’s at)

Maybe the failover for the `try` statements shouldn’t be 0? Is that causing it to try and grab all rows?

When all of the values are “ready” and the tag history binding executes it ends up being ~60 rows each (x5) which shouldn’t take long to query.

Any ideas for delaying that tag history binding until the others are ready? Thinking I’ll have to change it to a property change script to run the queries and populate the datasets manually once it’s all ready.

---

<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:** [December 30, 2025, 4:51pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/6 "2025-12-30T16:51:30Z")

</div>

Arrange for the default start and end times to be null (non-persistent), then use `coalesce()` to substitute a time far in the future. That ensures the startup historian query returns nothing, and quickly.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [December 30, 2025, 5:28pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/7 "2025-12-30T17:28:33Z")

</div>

Not sure I fully understand

---

<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:** [December 30, 2025, 5:37pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/8 "2025-12-30T17:37:01Z")

</div>

You cannot stop the history binding from running at startup, before the correct timespan loads. The best you can do is make that first run quick and harmless.

So when the bindings propagate the correct settings, that history binding is idle and can restart with the those correct settings immediately.

Custom properties that are set to non-persistent start with a null, so a `coalesce()` can deliver a useful (future) timestamp at startup.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [December 30, 2025, 5:39pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/9 "2025-12-30T17:39:09Z")

</div>

Ok, I understand the concept and the issue, but I don’t really know what to “fix”

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [January 5, 2026, 4:11pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/10 "2026-01-05T16:11:26Z")

</div>

Phil, if you have time please enlighten me. I am unfamiliar with the `coalesce` function.

Instead of

```python
try(dateArithmetic({Starter Diagnostics.trendStart1},{Starter Diagnostics.trendWindow},'sec'),0)

```

something like

```python
coalesce(dateArithmetic({Starter Diagnostics.trendStart1},{Starter Diagnostics.trendWindow},'sec'),48282559859)

```

?

Or, I may even use an expression tag to just do now + 1 year?

---

<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:** [January 5, 2026, 4:29pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/11 "2026-01-05T16:29:24Z")

</div>

`coalesce()` is just like `try()`, except that it substitutes when the first expression yields a NULL. `try()` substitutes when the first expression produces an exception. A null is not an exception.

The first argument to `coalesce()` should be a **UI property** that has a binding and is set to **non-persistent**. That property will be **null** until the binding finally delivers a value. An expression that needs that property value can use `coalesce()` to supply an alternate value during view startup.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [January 5, 2026, 4:30pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/12 "2026-01-05T16:30:34Z")

</div>

Ok, I think I’ve got that for the start and end date, but now it’s the start times that are not ready in time. It’s an indirect binding on a long array. How do I coalesce that one?

The issue comes when I try and access an index of the array and I get an index out of bounds because the array isn’t ready yet, despite using coalesce

`coalesce(sortDataset({Starter Diagnostics.startTimes},0,0)[0,0],{[default]nowPlus365})`

---

<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:** [January 5, 2026, 4:33pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/13 "2026-01-05T16:33:17Z")

</div>

Use properties for the start and end timestamps. Using coalesce on a nested expression is almost always wrong.

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [January 5, 2026, 4:46pm UTC](https://forum.inductiveautomation.com/t/faulty-database-connection-idle-object/113024/14 "2026-01-05T16:46:12Z")

</div>

My start and end timestamps are bound to properties. Those properties get their values from other bindings. I think I got what I need now by combining `coalesce` and `try`. Coalesce because dates can return null and try because the array can be empty which throws an exception.

```python
try(coalesce(sortDataset({Starter Diagnostics.startTimes},0,0)[0,0],{[default]nowPlus365}),{[default]nowPlus365})

```

May be slightly better to call try inside of coalesce and just throw a null when the try fails so that there is only one reference to the failover value, but this still works.
