Skip to main content

Increment & Decrement — counters

Use them when you need a running counter instead of a random value — a sequential id or row number (1, 2, 3…), an SKU series that climbs by a fixed step, or a countdown that falls to zero.

Both live inside a <sequence>: the sequence is computed once as an array, and each output row pulls the next value with ${{Name}} interpolation.

At a glance

AttributeApplies toDefaultWhat it does
valueincrement, decrement0Starting value
stepincrement, decrement1Amount to add or subtract each row

Both counters are position-based and deterministic: each row takes the next value in the run. They ignore the seed entirely (unlike the random generators), so the sequence is identical on every run — the outputs on this page are exact, not just illustrative.

increment — a rising counter

Each row is the previous value plus step. With the defaults (value="0", step="1") it counts up by one, but the common case is an id column that starts at 1.

<sequence name="Id"><gen type="increment" value="1"/></sequence>
./run demo.tdc (count=5)
1
2
3
4
5

Use it whenever you want a stable, gap-free id or row number — every row gets its own sequential value, and the whole column is reproducible across runs.

decrement — a falling counter

Each row is the previous value minus step. Same two attributes; only the direction flips.

<sequence name="Countdown"><gen type="decrement" value="100"/></sequence>
./run demo.tdc (count=5)
100
99
98
97
96

Reach for decrement when you need a countdown, a remaining-quantity column, or any reverse numbering that starts high and works its way down.

step — the stride

step sets how far the counter moves between rows. It defaults to 1. Give two counters the same start (value="1") and different steps, and the stride is the only difference — the left one counts by one, the right one by five:

<sequence name="ByOne"><gen type="increment" value="1"/></sequence>
<sequence name="ByFive"><gen type="increment" value="1" step="5"/></sequence>
...
<data>${{ByOne}} ${{ByFive}}</data>
./run demo.tdc (count=6)
step=1   step=5
1        1
2        6
3        11
4        16
5        21
6        26

step works the same on decrement — it controls how big each drop is:

<sequence name="Full"><gen type="decrement" value="1000"/></sequence>
<sequence name="ByHundred"><gen type="decrement" value="1000" step="100"/></sequence>
./run demo.tdc (count=5)
step=1   step=100
1000     1000
999      900
998      800
997      700
996      600

Use a custom step for series that don't move by one: SKUs spaced by 5, a price that falls by a fixed amount, a gauge that ticks in tens.

Fractional steps

step (and value) accept decimals, not just integers, which covers prices, percentages, or any measured quantity that moves in fractions:

<sequence name="Price"><gen type="decrement" value="9.99" step="0.50"/></sequence>
./run demo.tdc (count=5)
9.99
9.49
8.99
8.49
7.99

Deterministic by design

Counters never touch the random engine, so the same config produces the same run regardless of seed. Two runs with different seeds give byte-for-byte identical counter columns:

<gen type="increment" value="1" step="10"/>
./run demo.tdc — seed=alpha vs seed=omega (count=5)
seed=alpha   seed=omega
1            1
11           11
21           21
31           31
41           41

That makes counters the reliable spine of a dataset: id columns and row numbers stay put even when every random field around them changes.

Just need the row number?

If all you want is the current row number inside the output template, there's a built-in ${{_count}} — no sequence needed. It starts at 1 and rises by one per record.

Reach for an increment sequence instead when you need the counter as a named value — something to reuse in several places, format with a mask, start somewhere other than 1, or advance by a step other than 1.

See also

  • Sequences — the container both counters live in.
  • Built-ins_count, _first, _last, _total.
  • Determinism — why the same seed reproduces the same data (and why counters ignore it).