# Historical deadband in \`Percent\` mode appears to ignore the Engineering Range (8.1.49) — measured with the documented Analog slope formulas

**URL:** <https://forum.inductiveautomation.com/t/historical-deadband-in-percent-mode-appears-to-ignore-the-engineering-range-8-1-49-measured-with-the-documented-analog-slope-formulas/117082>\
**Category:** Ignition\
**Tags:** ignition81\
**Created:** [September 15, 2026, 12:58pm UTC](https://forum.inductiveautomation.com/t/historical-deadband-in-percent-mode-appears-to-ignore-the-engineering-range-8-1-49-measured-with-the-documented-analog-slope-formulas/117082 "2026-09-15T12:58:02Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![davi.soares](https://avatars.discourse-cdn.com/v4/letter/d/b9bd4f/32.png) [@davi.soares](https://forum.inductiveautomation.com/u/davi.soares)\
**Post date:** [September 15, 2026, 12:58pm UTC](https://forum.inductiveautomation.com/t/historical-deadband-in-percent-mode-appears-to-ignore-the-engineering-range-8-1-49-measured-with-the-documented-analog-slope-formulas/117082/1 "2026-09-15T12:58:02Z")

</div>

### Summary

On Ignition **8.1.49** , a tag configured with `Historical Deadband Mode = Percent` and `Historical Deadband Style = Analog` appears to use the configured number **as an engineering-unit value** , not as a percentage of the Engineering Range.

The effect is invisible on tags whose range happens to be 0–100 (where 1.5% of 100 equals the literal 1.5), and grows with the span everywhere else. On a 0–5000 tag the effective deadband ends up **50x tighter** than intended; on a 0–300,000 tag, **3000x**.

I would like to know whether this is expected behavior that I am misreading, or something others have run into.

### How I measured it

The manual gives the slope formulas for the Analog method:

```python
Upper Slope = ((NewValue + Deadband) - PreviousValue) / (NewTimestamp - PreviousTimestamp)
Lower Slope = ((NewValue - Deadband) - PreviousValue) / (NewTimestamp - PreviousTimestamp)

```

Writing `PreviousValue = 0` and then `NewValue = 1`, these become `(1 + D)/dt` and `(1 - D)/dt`. Adding and subtracting them:

```python
Upper + Lower = 2 / dt
Upper - Lower = 2D / dt

```

Dividing one by the other, **dt cancels out** :

```python
D = (Upper Slope - Lower Slope) / (Upper Slope + Lower Slope)

```

So the two slopes shown in Tag Diagnostics reveal the deadband the engine is actually using, independently of timing and of the signal value. That is what makes this reproducible on any gateway.

### Reproduction

Three **memory tags** , `Float8`, identical except where noted. History enabled, `Sample Mode = On Change`, `Historical Deadband Style = Analog`, **`Min Time = 0`** (important — a time gate would mask the deadband), `Max Time = 1 day`, `engLow = 0`.

| Tag | engHigh | Historical Deadband | Mode |
| --- | --- | --- | --- |
| `T1_Span100` | 100 | 10 | Percent |
| `T2_Span1000` | **1000** | 10 | Percent |
| `T3_Span1000_Absolute` | 1000 | 100 | **Absolute** |

`T1` and `T3` are controls. On `T1`, both interpretations agree (10% of 100 = 10 = the literal). `T3` is the unambiguous case.

Steps: write `0` to all three, wait ~20 s, write `1` to all three, then open Tag Diagnostics on each.

### Results

| Tag | Tolerance | Upper Slope | Lower Slope | **D computed** | D expected |
| --- | --- | --- | --- | --- | --- |
| `T1_Span100` | 10.0 | 6.558159E-4 | -5.3657667E-4 | **10.0000** | 10 |
| `T2_Span1000` | **10.0** | 5.687694E-4 | -4.6535677E-4 | **10.0000** | **100** |
| `T3_Span1000_Absolute` | 100.0 | 4.650092E-3 | -4.558011E-3 | **100.0000** | 100 |

`T2` and `T3` have the **same Engineering Range (0–1000)**. The only difference is the mode. In `Absolute` the effective deadband is 100. In `Percent`, 10% of a 1000-wide span yields **10** , not 100.

The `Tolerance` field in Diagnostics reports the same figure, which is consistent with the slopes.

### Sanity check on the readings

Since `dt = 2 / (Upper + Lower)`, the time of the initial stored point can be recovered from the slopes alone and compared against the `Last value` timestamp:

| Tag | dt derived | `Last value` (epoch ms) | Recovered t0 |
| --- | --- | --- | --- |
| `T1_Span100` | 16,773 ms | 1789475567410 | **1789475550637** |
| `T2_Span1000` | 19,340 ms | 1789475569977 | **1789475550637** |
| `T3_Span1000_Absolute` | 21,720 ms | 1789475572357 | **1789475550637** |

All three recover the same instant to the millisecond — which is when the three tags were written with `0`. The readings are internally consistent.

### Why it matters in practice

This was found while reducing a Tag Historian that was growing ~9 GB/month. Roughly 874 analog tags were configured `Percent` at 1.5%, across Engineering Ranges from 0–100 to 0–300,000. Because the effective deadband was stuck at 1.5 engineering units, the tags with wide ranges recorded almost continuously:

- A differential-pressure tag with range **0–5000 mbar** and a 1.5% deadband (expected threshold 75) recorded **458 points in 2.4 hours** while the signal moved a total of **32.7 mbar** over the whole window — less than half of its own intended threshold.
- Switching those tags to `Absolute` with the pre-computed value (`(engHigh - engLow) * pct / 100`) cut the historian rate by **41.8%** measured like-for-like, with no loss of resolution: the same tag now records 1–2 points, which is the correct behavior for a signal that never crosses its threshold.

### Questions

1. Is `Percent` supposed to be relative to the Engineering Range in the historical deadband, as it is for the value deadband? The manual describes the Analog formulas but does not state what `Deadband` resolves to in `Percent` mode.
2. Has anyone else measured this? It is easy to miss, because on 0–100 tags the two interpretations coincide, and on other tags it only shows up as "the historian writes more than I expected".
3. In our production tags the Engineering Range comes from **UDT parameter bindings** (`{EngHigh}` / `{EngLow}`), so my first suspicion was that the binding was not being resolved. But the memory tags above use **literal** values for `engHigh` and show the same behavior, which seems to rule that out. Has anyone tested both contexts?

Environment: Ignition **8.1.49** , PostgreSQL historian provider, Analog (swinging door) style, memory tags for the repro.

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![michael.flagler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/michael.flagler/32/26272_2.png) [@michael.flagler](https://forum.inductiveautomation.com/u/michael.flagler)\
**Post date:** [September 15, 2026, 1:21pm UTC](https://forum.inductiveautomation.com/t/historical-deadband-in-percent-mode-appears-to-ignore-the-engineering-range-8-1-49-measured-with-the-documented-analog-slope-formulas/117082/2 "2026-09-15T13:21:42Z")

</div>

Per the manual:

> Deadband Mode is set to Absolute by default. If changed to Percent, the deadband is calculated as a percentage of the tag’s engineering unit span.

I'm on mobile but on some of your first calculations you were dividing your upper and lower limits and I'm not sure why as that's not part of any of the calculations. The limit calculations using the given values generates 2 values that are then used to determine if the new value falls outside those limits.
