TD(lambda) and Eligibility Traces
Imagine an agent learning to predict how long a commute will take. It updates its estimate after every intersection, rather than waiting until it arrives home. If it only updates using the very next step, learning is stable but slow. Information then propagates backward slowly. If it waits for the full trip, updates are unbiased but noisy. They also cannot happen online. n-Step Bootstrapping Methods showed that any fixed lookahead of steps interpolates between these extremes. But choosing a single best is awkward. Computing many -step returns separately is also wasteful. TD() resolves this by averaging over all -step returns at once. These are weighted geometrically by a parameter . This produces a single tunable knob. It spans one-step TD at to Monte Carlo at . The elegance of TD() is not just conceptual — it is computational. Naively averaging infinitely many -step returns would seem to require storing an entire episode. It would also require revisiting that episode later. Eligibility traces solve this problem differently. They introduce a compact, decaying memory trace over states (or features). This lets the same forward-looking average be computed differently. Instead, it uses a backward, fully incremental, per-step update. This backward view is mathematically equivalent to the forward -return under offline updates. It also generalizes cleanly to online learning and function approximation. This machinery matters in real systems for a clear reason. Most practical reinforcement learning cannot wait for episodes to end. It also cannot afford to store full trajectories. This is especially true with continuous or non-episodic tasks. It also applies to streaming sensor data or robotic control at high frequency. TD() with eligibility traces gives an -per-step algorithm. It captures much of the variance reduction of long-horizon returns. At the same time, it retains the low latency of one-step bootstrapping. This article builds the -return precisely. It derives the equivalence between the forward view and the backward view. The forward view looks ahead at compound returns. The backward view uses eligibility traces to propagate credit to the past. It gives working pseudocode for both linear function approximation and tabular prediction. It analyzes complexity and correctness. It also works a full numeric trace so the mechanics are unmistakable. It closes by connecting to the fully general machinery used in Semi-Gradient Methods with Function Approximation.
- TD() generalizes n-Step Bootstrapping Methods by averaging all -step returns with geometric weights .
- recovers one-step TD; recovers Monte Carlo; intermediate trades bias against variance, per Bootstrapping and the Bias-Variance Tradeoff.
- The forward view defines the -return explicitly using future rewards — conceptually clean but not implementable online.
- The backward view uses an eligibility trace vector that decays by each step and spikes on visited states/features, giving an equivalent -per-step update.
- Under offline (batch, end-of-episode) updating, forward and backward TD() produce mathematically identical weight changes.
- Eligibility traces plug directly into linear function approximation and set up the general recipe used later in Semi-Gradient Methods with Function Approximation.
TD() computes a geometrically-weighted average of all -step returns, and eligibility traces let you compute that average online in constant time per step without ever storing the trajectory.
The idea
Recall that the -step return is
truncating the real trajectory after steps and bootstrapping off the current value estimate thereafter. Different trade bias for variance: small bootstraps heavily (more bias, less variance), large approaches the Monte Carlo return (less bias, more variance). Rather than picking one , the -return averages over all of them, weighting the -step return by :
The weights form a proper probability distribution over (they sum to 1), decaying geometrically, so most of the weight sits on small when is small and spreads out toward larger as . For an episodic task ending at time , once the -step return becomes just the full Monte Carlo return , and the tail of the geometric series after termination is folded into a single term with weight :
Setting collapses the sum to just , the ordinary one-step TD target. Setting makes every finite--step term vanish (weight ) except the final Monte Carlo term, recovering the full return. This is the forward view: at each time , imagine looking ahead through the rest of the episode to compute , then update
It is a clean theoretical object but not implementable causally — it requires future rewards not yet observed. The backward view produces the same total updates (under offline, end-of-episode application) using only information available up to the present. It introduces an eligibility trace, a scalar per state (tabular case) or a vector per weight (function approximation case), that records how "eligible" each state/feature is for the current TD error. Every step, all traces decay by a factor , and the trace for the just-visited state (or the gradient of the value function at the current state, in the function-approximation case) is bumped up. The current one-step TD error is then broadcast to every state/feature in proportion to its trace, not just the current state. This mechanism is what "unifies" -step methods: it lets a single scalar per step implicitly account for corrections that would otherwise require -step lookahead for every simultaneously.
How it works
Tabular forward view (conceptual, offline). For each state visited at time in an episode, compute using the full (or truncated, in continuing tasks) reward sequence, then accumulate and apply all updates at the end of the episode. This is correct but requires storing the whole trajectory and is naively (an -step return for every and every ).
Tabular backward view with eligibility traces (online, incremental). This is the practical algorithm: ``` Algorithm: TD(lambda) with eligibility traces (tabular, state-value prediction) Input: policy π to evaluate, step size α ∈ (0,1], discount γ, trace decay λ ∈ [0,1] Initialize V(s) arbitrarily for all s (V(terminal) = 0) for each episode: initialize E(s) = 0 for all s # eligibility traces S ← initial state of episode while S is not terminal: A ← action given by π(S) take action A, observe reward R, next state S' δ ← R + γ V(S') - V(S) # one-step TD error E(S) ← E(S) + 1 # accumulating trace at current state for each state s: V(s) ← V(s) + α δ E(s) E(s) ← γ λ * E(s) S ← S' ``` Two design choices deserve names. The trace update `E(S) ← E(S) + 1` is the accumulating trace; an alternative, the replacing trace, instead sets `E(S) ← 1` on revisits (useful when a state can be revisited within an episode, preventing traces from exploding). The inner loop "for each state s" is what makes the tabular version look per step; in practice only states with nonzero trace need updating, and traces decay to numerical zero after steps, so a sparse active-trace list keeps this efficient.
Linear function approximation (the version that matters for scale). Replace the per-state trace with a trace vector matching the weight vector , and replace "visit state " with "accumulate the feature/gradient vector ": ``` Algorithm: Semi-gradient TD(lambda) (linear function approximation) Input: features x(s) ∈ R^d for all s, step size α, discount γ, trace decay λ Initialize weight vector w arbitrarily (e.g., w = 0) for each episode: e ← 0 # eligibility trace vector, e ∈ R^d S ← initial state while S is not terminal: A ← action given by policy take action A, observe reward R, next state S' v_hat_S ← w · x(S) v_hat_S' ← 0 if S' is terminal else w · x(S') δ ← R + γ v_hat_S' - v_hat_S e ← γ λ e + x(S) # decay, then accumulate gradient (= x(S) for linear) w ← w + α δ * e S ← S' ``` Here because is linear in ; with nonlinear function approximators the same recipe generalizes by accumulating the actual gradient into , which is exactly the bridge into Semi-Gradient Methods with Function Approximation. Note the update touches every component of each step through the trace, but if features are sparse (e.g., one-hot or tile coding) this is cheap since is sparse too.
Complexity & correctness
Time and space. The backward-view algorithm performs, per environment step, one TD-error computation and one pass over the eligibility trace (and value/weight vector). Tabular: worst case per step if traces are dense, but if only states currently have non-negligible trace, since traces decay geometrically as and can be dropped once below a numerical threshold — after steps a trace is negligible. Linear function approximation: per step where is the feature dimension, matching plain semi-gradient TD(0) in per-step cost, and space for the trace vector, an additive constant-factor overhead. Contrast this with a naive forward-view implementation that recomputes using -step returns for every up to episode length: that costs work per time step and per episode, plus space to store the trajectory. Eligibility traces reduce this to extra work per step (beyond ordinary TD) and space total — no trajectory storage at all. This constant-time-per-step property is exactly why traces make -averaging usable online, in continuing (non-episodic) tasks, and under strict memory budgets such as embedded control.
Correctness — equivalence of forward and backward views (offline case). The central claim is that, summed over an episode, the backward-view weight updates equal the forward-view weight updates, when updates are accumulated and applied only at the end of the episode (the "offline -return algorithm" matches "offline TD()"). Sketch of the argument for the tabular case: fix a state and expand the total backward-view update to over an episode,
more precisely, since the trace for after being set at some visit time decays by each subsequent step,
Swap the order of summation to instead group by : this says every TD error contributes to every earlier visited state () with weight . The classical algebraic identity underlying TD() is that a telescoping sum of discounted one-step TD errors reconstructs the -return exactly:
where are ordinary TD errors along the trajectory (assuming is held fixed during the episode, as in the offline setting). This identity is proved by induction on the horizon: expand via its recursive definition , subtract , and observe that the recursion telescopes into exactly the discounted sum of one-step errors above, matching term by term with the trace-weighted broadcast performed by the backward-view algorithm. Consequently, summing over all where (the offline forward-view total update to ) equals summing contributions collected by the eligibility trace — which is precisely above. This establishes the forward/backward equivalence exactly, not approximately, for offline updating.
Online updating and the approximation it introduces. In practice, the backward-view algorithm updates (or ) immediately at each step rather than waiting for episode end. This changes the effective target slightly, because later TD errors are computed against an already-updated , not the fixed used in the offline derivation. The online and offline versions therefore only coincide exactly as ; for finite step sizes they are close but not identical, a discrepancy resolved exactly by the more intricate true online TD() algorithm, which reproduces the online forward-view -return exactly using a modified ("dutch") trace update. Standard TD() with accumulating or replacing traces sacrifices this exact equivalence for simplicity, and in practice the difference is small for reasonable step sizes.
Convergence. For tabular prediction under a fixed policy, with standard step-size (Robbins–Monro) conditions , , TD() converges to the true value function with probability 1, for any , since it remains a stochastic approximation to a contraction mapping (the -weighted Bellman operator is a contraction in the same way the one-step Bellman operator is). With linear function approximation and on-policy sampling, semi-gradient TD() converges to a fixed point whose value error is bounded relative to the best representable approximation, with the bound tightening as (approaching the Monte Carlo/least-squares projection) at the cost of higher variance — the same bias–variance tension discussed under Bootstrapping and the Bias-Variance Tradeoff.
Worked example
Consider a tiny 4-state random walk: states , all transitions deterministic left-to-right, reward everywhere except entering the terminal state, . Initialize . One episode is observed: , rewards .
Step-by-step backward-view trace with , , (accumulating traces):
| Step | after decay+bump | Updates applied () | |||
|---|---|---|---|---|---|
| 1 | 0 | (others 0) | no change () | ||
| 2 | 0 | no change () | |||
| 3 | 0 | no change () | |||
| 4 | Term | 1 |
(Traces are shown after the decay-then-bump for the just-visited state; note only the final step has nonzero TD error here because all intermediate value estimates were already consistent at , deliberately chosen so the single informative error at termination is the only source of learning — this isolates how that one signal fans out backward.) Final values after this episode:
Cross-check against the forward view. The -return for (state ) with , using , , , (all intermediate -step returns bootstrap off except the full return which sees the actual terminal reward):
Using the episodic form with :
computing directly: . Then — this disagrees with the backward-view result above () because backward-view here is applied online (updates mid-episode change later 's implicitly through the trace mechanics as derived), while this forward computation assumed a fixed throughout (the offline setting). Re-deriving offline (freeze at throughout, apply forward-view updates only at episode end, matching the backward-view sum-of-TD-errors identity exactly) recovers agreement: summing over with all except gives , and — matching the backward-view update to found in the table. The apparent mismatch above came from mixing an online backward trace with a naively-recomputed forward return; the theorem guarantees equivalence specifically in the offline (frozen--during-episode) setting, exactly as the correctness argument states.
Common pitfalls & traps
| Pitfall | Why it happens | Fix |
|---|---|---|
| Confusing online and offline TD() | Assuming exact forward/backward equivalence holds for the online algorithm | Remember equivalence is exact only offline; use true online TD() if exact online equivalence is required |
| Trace explosion with revisited states | Accumulating traces add every visit, growing unboundedly in loopy environments | Use replacing traces, or clip/normalize, when states recur within an episode |
| Forgetting to decay traces before the bump | Order matters: decay-then-add vs. add-then-decay give different discounting of the current step | Follow the standard convention consistently: `e ← γλe`, then add current feature/visit |
| Treating λ=1 as "just Monte Carlo" without care | With function approximation and continuing (non-episodic) tasks, λ=1 traces can drift or diverge without episode resets | Reset traces at episode boundaries; be cautious with λ near 1 in continuing tasks |
| Dense trace updates on huge state/feature spaces | Naively updating all trace components every step is wasteful when most are ~0 | Maintain only the sparse set of active (non-negligible) trace entries |
| Ignoring the bias–variance shift as λ changes | Treating λ as a free hyperparameter without expecting variance to grow near 1 | Tune λ empirically; expect noisier but less biased updates as λ increases, cf. Bootstrapping and the Bias-Variance Tradeoff |
Pioneers & history
TD() and eligibility traces emerged from work connecting animal learning theory, dynamic programming, and stochastic approximation, culminating in the temporal-difference learning framework that underlies most of modern model-free reinforcement learning.
Origins · 1 minRichard S. Sutton and how this was discovered
Where this matters
Eligibility traces and TD()-style credit assignment appear wherever an agent must learn from delayed, sparse rewards without waiting for episodes to finish. Classic game-playing systems such as Tesauro's TD-Gammon used TD() with a neural network value function to reach superhuman backgammon play, one of the earliest large-scale demonstrations that bootstrapped, multi-step credit assignment scales. Actor-critic architectures used in robotics and simulated control (walking, manipulation, locomotion) routinely use eligibility-trace-style multi-step targets — including the closely related n-Step Bootstrapping Methods and GAE (generalized advantage estimation) in policy-gradient methods — as a direct descendant of the -return idea for variance reduction. Traces are especially valuable in continuing, non-episodic control tasks such as process control or continual robot operation, where there is no "end of episode" to wait for and only the -per-step backward view is feasible. The conceptual machinery here — a decaying memory of recent activity broadcasting a scalar error signal backward — is also the direct ancestor of the eligibility-trace ideas used in biologically-inspired learning rules and in extending value-based methods to deep networks, the topic taken up next under Semi-Gradient Methods with Function Approximation.
Ask the tutor: How does true online TD(λ) modify the eligibility trace update to make the online and offline views exactly equivalent?
Why is TD(λ) considered a "unification" of TD(0) and Monte Carlo methods?
Because the -return is a weighted average of every -step return, and its two extreme settings recover the two classic methods exactly. At , the geometric weighting puts all weight on , giving the ordinary one-step TD target. At , all finite- terms vanish and only the full Monte Carlo return survives. Values of strictly between 0 and 1 blend bias and variance continuously, so instead of manually choosing an -step method as in n-Step Bootstrapping Methods, you get an entire family accessible through one continuous parameter, with eligibility traces making every point in that family computable online in constant time per step.
What exactly does an eligibility trace represent intuitively?
It represents a decaying record of "how responsible" a state (or feature) is for the reward currently being observed, based on how recently and how strongly it was visited. If a state was visited one step ago, its trace is close to its maximum bump value; if it was visited many steps ago, the trace has decayed by for elapsed steps, so it receives a proportionally smaller share of the current TD error. This mirrors the biological idea of a "stimulus trace" in classical conditioning: a fading memory that lets a later, delayed reinforcement signal still adjust earlier stimuli, which is part of TD learning's original inspiration from animal learning theory.
Why doesn't the online version of TD(λ) exactly match the offline forward view?
The forward/backward equivalence proof assumes (or the weights) stay fixed throughout the episode while errors are computed, with all updates summed and applied only afterward. The practical online algorithm instead updates immediately after every step, so later TD errors are computed using an already-changed value function, not the frozen one assumed in the derivation. This introduces a small discrepancy proportional to the step size ; as the two coincide. True online TD(λ), introduced later, uses a modified "dutch trace" update to close this gap and match the online forward view exactly, at slightly higher implementation complexity.
How should I choose λ in practice?
Treat as a bias–variance knob, as covered generally in Bootstrapping and the Bias-Variance Tradeoff. Small (close to 0) gives low-variance but potentially high-bias updates that rely heavily on the current value estimates being accurate; large (close to 1) reduces bias by looking further into real observed returns but increases variance and, with function approximation, can be less stable in continuing tasks. Empirically, intermediate values (often – in practice, especially in policy-gradient variants like GAE) tend to perform best, and it is usually tuned as a hyperparameter alongside the step size rather than derived analytically.
What is the difference between accumulating and replacing eligibility traces?
An accumulating trace adds 1 (or the current feature vector) to the existing trace value every time a state is visited, so a state visited multiple times in quick succession within an episode can build up a trace larger than 1. A replacing trace instead resets the trace to exactly 1 (or clips it) on each visit, preventing unbounded growth in environments with frequent self-loops or revisits. Replacing traces were introduced specifically to fix instability observed with accumulating traces in such environments and are often preferred in tabular settings; for function approximation, variants like "replacing" or "dutch" traces exist but accumulating traces remain the more common default.
Does TD(λ) require storing the entire episode's history?
No — that is precisely the point of the backward view. The forward-view -return, taken literally, would require future rewards and hence a stored trajectory, giving space and time per episode if computed naively for every -step return. The backward-view eligibility-trace algorithm instead needs only the current trace vector (size for features, or tabular) and updates it incrementally, achieving time and space per step with no trajectory storage, which is what makes it usable in continuing, non-episodic, or memory-constrained settings.
How does TD(λ) relate to n-step methods I already know?
TD() is a strict generalization: instead of committing to a single lookahead length as in n-Step Bootstrapping Methods, it computes a geometrically-weighted average over every possible simultaneously via the -return. The eligibility trace mechanism is what makes this averaging computationally tractable, replacing what would otherwise require maintaining separate -step return computations for every with a single decaying trace vector updated in constant time per step, and yielding, under offline updating, exactly the same result you would get by explicitly averaging infinitely many -step returns.