# TIMELAG
URL: https://docs.valsight.ai/timelag/
Description: The TIMELAG function calculates time-lagged effects on a chosen time granularity, distributing each input value over future periods according to a lag profile.
**Category:** [Rollforward & time series](/rollforward-time-series/)

## Overview

The **TIMELAG** function **calculates time-lagged effects on a chosen time granularity.**
Each value from the input node is distributed over future periods according to a lag profile. Multiple contributions can overlap when several input values are lagged into the same period.

Use this function when an effect should show up gradually or with a delay across time periods, for example to model delayed investment effects or gradual impact curves.

## Syntax

`TIMELAG('ValueNode', 'TimeLagNode', "TimeLevel")`

**Example usage:** `TIMELAG('Investment', 'TimeLagNode', "Year")`

## Parameters

| Parameter        | Description                                                                                                                                                                                                                    | Type           | Required |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | -------- |
| **Value Node**   | Input node with the values that should be time-lagged. Must have the selected time level.                                                                                                                                      | Node reference | Yes      |
| **TimeLag Node** | Node containing values between `0` and `1` (= 100%) on the `Sequence` dimension, defining how the lag is applied. Sequence entry `0` refers to the impact in the base year. This node should not have the selected time level. | Node reference | Yes      |
| **Time Level**   | Name of the time level where one time-level step equals one sequence step, specified in double quotes (e.g.`"Year"`)                                                                                                           | Level name     | Yes      |

## Output shape

| Aspect         | Behavior                                                                                                                |
| -------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Dimensionality | Preserves the non-time levels of the Value Node. The time level is set as specified.                                    |
| Values         | Each input value is multiplied by the lag input and spread across future periods. Overlapping contributions are summed. |
| Row count      | Typically increases, as each input value generates multiple output rows across the lag window.                          |

## Watch out

* The Value Node must have a time level at least as fine-grained as specified in the function.
* The TimeLag Node must **not** contain any time level.
* The TimeLag Node cannot be more fine-grained than the Value Node on non-sequence levels.
* Beyond the last defined sequence entry, the **last lag value is repeated indefinitely**. If the last entry is `0.75`, the contribution permanently stays at 75%. It does not automatically reach 100%.
* Gaps in the sequence (e.g. entries at 0, 1, 2, 4 but not 3) are treated as **zero**.
* If the sequence does not start at `0`, position 0 defaults to zero.
* If the TimeLag Node has no matching lag profile for a given category, the output for that category is **zero** (not the original values).
* If the Value Node has data at a finer time level than the specified Time Level (e.g. monthly data with `"Year"`), values are automatically aggregated before the lag is applied.

## Examples

### Distributing a single value with a gradual ramp-up

This example shows how a single investment is gradually phased in over time. 20% of the effect is felt immediately, 50% after one year, and the full effect is reached after two years.

**Input node:** `'Cost'`

| Year | Cost |
| ---- | ---- |
| 2025 | 100  |

**Input node:** `'LagProfile'`

| Sequence | Effect |
| -------- | ------ |
| 0        | 0.2    |
| 1        | 0.5    |
| 2        | 1      |

**Formula:** `TIMELAG('Cost', 'LagProfile', "Year")`

| Year | Calculation | Result |
| ---- | ----------- | ------ |
| 2025 | 100 × 0.2   | 20     |
| 2026 | 100 × 0.5   | 50     |
| 2027 | 100 × 1     | 100    |

The effect ramps up from 20% to 100% over two years. From 2027 onward, the full value persists because the last sequence entry (`1`) repeats indefinitely.

### Overlapping contributions from multiple input periods

This example shows how investments are distributed over future years based on a lag profile. The lag profile gradually releases each investment amount over three sequence steps, so later years can contain overlapping contributions from multiple inputs.

**Input node:** `'Investment'`

| Year | Investment |
| ---- | ---------- |
| 2025 | 10         |
| 2026 | 0          |
| 2027 | 15         |
| 2028 | 0          |

**Input node:** `'TimeLagNode'`

| Sequence | Effect |
| -------- | ------ |
| 0        | 0      |
| 1        | 0.25   |
| 2        | 0.5    |
| 3        | 1      |

**Formula:** `TIMELAG('Investment', 'TimeLagNode', "Year")`

| Year | Calculation        | Result |
| ---- | ------------------ | ------ |
| 2025 | 10 × 0             | 0      |
| 2026 | 10 × 0.25          | 2.5    |
| 2027 | 10 × 0.5           | 5      |
| 2028 | 10 × 1 + 15 × 0.25 | 13.75  |
| 2029 | 10 × 1 + 15 × 0.5  | 17.5   |
| 2030 | 10 × 1 + 15 × 1    | 25     |

From 2028 onward, both the 2025 investment (at full effect) and the 2027 investment (ramping up) contribute to the result.

### Different lag profiles per category

The TimeLag Node can include non-sequence dimensions to define separate lag curves per category. Here, Category A ramps up in one year while Category B ramps up over three years.

**Input node:** `'Investment'`

| Year | Category | Investment |
| ---- | -------- | ---------- |
| 2025 | A        | 100        |
| 2025 | B        | 100        |

**Input node:** `'LagProfile'`

| Sequence | Category | Effect |
| -------- | -------- | ------ |
| 0        | A        | 0.5    |
| 1        | A        | 1      |
| 0        | B        | 0      |
| 1        | B        | 0.25   |
| 2        | B        | 0.5    |
| 3        | B        | 1      |

**Formula:** `TIMELAG('Investment', 'LagProfile', "Year")`

| Year | Category | Calculation | Result |
| ---- | -------- | ----------- | ------ |
| 2025 | A        | 100 × 0.5   | 50     |
| 2026 | A        | 100 × 1     | 100    |
| 2025 | B        | 100 × 0     | 0      |
| 2026 | B        | 100 × 0.25  | 25     |
| 2027 | B        | 100 × 0.5   | 50     |
| 2028 | B        | 100 × 1     | 100    |

Category A reaches full effect after one year. Category B ramps up gradually over three years. The lag profile node can also use a coarser level than the Value Node (e.g. `Product Group` on the lag profile while the Value Node has `Product`). Child values inherit the parent's lag curve.

### Temporary effect with a zero-ending sequence

If the last sequence entry is `0`, the contribution decays to nothing permanently. This models impulse or temporary effects that fully disappear after a defined period.

**Input node:** `'Campaign'`

| Year | Campaign |
| ---- | -------- |
| 2025 | 100      |

**Input node:** `'LagProfile'`

| Sequence | Effect |
| -------- | ------ |
| 0        | 0      |
| 1        | 1      |
| 2        | 0.5    |
| 3        | 0      |

**Formula:** `TIMELAG('Campaign', 'LagProfile', "Year")`

| Year | Calculation | Result |
| ---- | ----------- | ------ |
| 2025 | 100 × 0     | 0      |
| 2026 | 100 × 1     | 100    |
| 2027 | 100 × 0.5   | 50     |
| 2028 | 100 × 0     | 0      |

The effect peaks in 2026, decays to half in 2027, and disappears completely from 2028 onward. Because the last sequence entry is `0`, the contribution stays at zero permanently.

## Related Functions

| Function                               | When to use instead                                                                                                                                |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| [STRETCH\_CURVE](/stretch-curve/)      | When you want to stretch or compress a defined profile along the axis instead of applying a delayed effect over time.                              |
| [SCHEDULEPROJECTS](/scheduleprojects/) | When you want to place project blueprints onto actual start periods instead of distributing an existing value with a lag profile.                  |
| [SHIFT](/shift/)                       | When you need to move existing values by a direct offset along a time level instead of distributing them with a lag profile over multiple periods. |
