Qm
Core

Streaming Feature Computation

Computing model features incrementally as new data arrives, rather than recomputing from scratch over a full history, so live inference gets fresh inputs within the latency budget a trading system needs.

Prerequisites: Point-in-Time Correctness in Feature Pipelines

A feature like "20-day rolling average volume" is easy to compute in a batch job: load 20 days of history, average it, done. But a live trading system needs that feature updated every time a new trade prints, potentially thousands of times a second, and recomputing a 20-day average from scratch on every tick is wasteful and eventually too slow. Streaming feature computation solves this by maintaining the feature incrementally: keep just enough state to update the value cheaply as each new data point arrives, without re-reading the whole window.

Incremental update, not full recompute

For a simple moving average of window length nn, the trick is to keep a running sum and drop the oldest point as each new one arrives:

St=St1+xtxtnS_t = S_{t-1} + x_t - x_{t-n}

In plain English: the new running total equals the old total, plus the newest value, minus the value that's now aged out of the window, an update that costs one addition and one subtraction regardless of how long the window is, instead of re-summing everything. Many common features have an equivalent incremental form: exponentially weighted moving averages update with a single blend of the old value and the new observation; running variance can be updated with Welford's algorithm; even more complex features like a rolling z-score can be built by combining a few incrementally maintained running statistics (sum, sum of squares, count).

Worked example

A market-making system tracks a 5-minute rolling average trade size to size its own quotes. Naively, on every new trade it could re-read the last 5 minutes of trade log and average it, at 200 trades per minute that's up to 1,000 rows re-averaged on every single new trade, an unnecessary O(n)O(n) cost per update. Instead the system keeps a running sum and count for the current window in a small ring buffer that drops trades older than 5 minutes as new ones arrive. Each new trade updates the sum and count in constant time regardless of window size, well within the 1-millisecond quoting latency budget. Benchmarked, the naive recompute took 40 microseconds per update at peak load; the incremental version took under 0.1 microseconds.

drop new 5-minute window (ring buffer) $S_t = S_{t-1} + x_t - x_{t-n}$ constant-time update, no re-scan of the window
Each new trade updates the running sum by addition and subtraction only, avoiding a full re-scan of the rolling window on every tick.

What this means in practice

Any feature meant to feed a low-latency system should be designed with its incremental update rule in mind from the start, not bolted on after a batch version is built, some features (like a rolling median) have no cheap incremental form and either need an approximation or a bounded-cost data structure. Streaming and batch versions of the same feature must also be checked for numerical agreement periodically, since incremental algorithms can accumulate floating-point drift over long runs that a batch recompute won't show.

Streaming feature computation maintains just enough running state, a sum, a count, an exponential blend, to update a feature in constant time as new data arrives, avoiding an expensive full recompute over the window on every tick. Not every feature has a cheap incremental form; check before committing to one for a low-latency path.

Incremental running sums drift over long periods due to floating-point rounding error accumulating update after update. Periodically resynchronize a long-running streaming feature against a fresh batch recomputation, or the live feature can silently diverge from what a batch job would report for the same window.

Discussion

Sign in to join the discussion · reading is open to everyone

💡 Discussion rules

  1. Ask and answer about this concept. Off-topic gets removed.
  2. No homework dumps. Show what you tried first.
  3. Corrections are welcome. Cite a source when you claim an error.

Loading discussion…

Related concepts

Practice in interviews

Further reading

  • Kleppmann, Designing Data-Intensive Applications, ch. 11
ShareTwitterLinkedIn