Engineering Blog
ML Infrastructure Nadia Petrov

Incremental Computation 101: What It Is and Why ML Teams Need It

Incremental computation updates results based on what changed, not the full dataset. For ML feature pipelines, this means second-level rather than hour-level freshness.

Incremental Computation 101: What It Is and Why ML Teams Need It

If you have worked with data pipelines, you have likely seen this problem: a SQL job that once ran in five minutes now takes forty-five because its source table has grown by an order of magnitude. The query logic is unchanged, and the computation itself is no more difficult. Yet the engine starts over on every run, scanning every row to produce a result that differs from the previous one by only a fraction of a percent.

That is the reverse of incremental computation. Batch recompute is O(history): its cost grows with everything ever written. Incremental computation is O(delta): its cost grows with what has just changed. For feature pipelines receiving continuous events and keeping aggregates current, this cost difference directly affects feature freshness and the compute budget required to maintain it.

A concrete definition

Incremental computation means maintaining a function f so that, given an input change delta_x to x, the new output f(x + delta_x) can be calculated from f(x) and delta_x without recomputing from x. The work is proportional to |delta_x| rather than |x|.

For SQL operations, the meaning varies by operator. A COUNT(*) with a GROUP BY is easy to incrementalize: when a row enters group G, increase G's count by one. Counts for other groups remain unchanged. A sort or window rank is more difficult because a row inserted anywhere in the order can change the ranks of many other rows. A query's incrementalizability depends on its plan operators and whether they support efficient delta propagation.

Feldera compiles SQL queries into operator graphs made up of incremental operators. When a source receives a row, a delta moves through the graph. Only nodes whose state is affected perform work, while unaffected nodes remain idle. Per input event, total work is proportional to the number of affected output groups, not the output's total size.

Why batch feature pipelines hit the wall

Batch feature pipelines carry a hidden compound cost that no single job runtime captures. Take a 30-day rolling window feature over a user events table. On day one, the job reads 1 day of data. On day 30, it reads 30 days. On day 365, it still computes over the full 30 days, but after 365 runs, the table holds a full year of events that must be scanned to find the rows inside the window.

SQL
-- Batch approach: full table scan every run
-- Cost: O(all_events) per run, run every hour
SELECT
  user_id,
  COUNT(*) AS events_30d,
  SUM(value) AS total_value_30d
FROM events
WHERE ts >= CURRENT_TIMESTAMP - INTERVAL '30 days'
GROUP BY user_id;

-- Incremental approach: Feldera materializes this view
-- Cost: O(new_events) per tick, runs continuously
CREATE MATERIALIZED VIEW user_features_30d AS
SELECT
  user_id,
  COUNT(*) AS events_30d,
  SUM(value) AS total_value_30d
FROM events
WHERE ts >= NOW() - INTERVAL '30 days'
GROUP BY user_id;
-- Each new event: one group updated. All others unchanged.

The incremental form of the same query has constant cost per tick while new-event arrival remains constant. One hundred thousand new events per hour produce one hundred thousand delta operations per hour, whether the underlying history covers one week or three years. The batch cost follows the scan: each hour, the entire retention window must be read to determine its contents.

What incremental computation changes for ML teams

The clearest change is feature freshness. A batch job running hourly creates features that can be up to 59 minutes stale when the next run begins. An incremental pipeline creates features as fresh as its most recently processed event, typically seconds to sub-minute depending on source latency. For fraud detection and real-time personalization, that can separate a useful signal from an irrelevant one.

The subtler change is the cost structure of the feature library. In a batch system, a new feature requires another batch job or another step in an existing job, raising hourly compute costs in proportion to the history scanned. In an incremental system, a new feature is a new materialized view that processes incoming events at the same per-event cost as existing features. Its marginal cost follows event rate, not total history size.

This alters experimentation economics. When a new feature requires reprocessing months of data every hour, teams have reason to keep the feature library small. When a new feature is essentially free at steady state, teams can test feature hypotheses more quickly.

Where it fits in the existing stack

Incremental computation does not replace every batch workload. Backfills, one-time historical analyses, and training data generation from large static datasets remain batch jobs. The incremental layer sits before the feature store and maintains the online feature values models read during serving. Batch pipelines remain suitable for offline training data preparation when freshness is not the constraint.

For most ML teams, the practical division is offline training features from batch pipelines and online serving features from incremental pipelines. The incremental layer must produce the same values the batch layer would produce from the same data, requiring careful treatment of windowing semantics and event time versus processing time. Aligning those results is the main engineering investment when moving to incremental serving.

The hard part: what does not incrementalize well

SQL operations are not equally suitable for incremental maintenance. Operations with O(1) delta cost per input event include simple aggregations such as COUNT, SUM, and AVG, filter pushdown, and equi-joins with an indexed join key. Higher-cost operations include multi-way self-joins, full outer joins with non-equality join conditions, and some window functions that must re-rank many rows after each update.

In practice, review feature definitions for incrementalizability before adding them to a live pipeline. A seemingly simple SQL feature can have quadratic delta cost when it uses a correlated subquery over a large base table. Feldera's query compiler warns about patterns with high incremental cost, helping identify them before they cause operational problems. The core tradeoff remains: incrementalizability belongs to the computation, not only the engine, and some computations are inherently non-incremental.

Continue reading

Incremental SQL: Computing Aggregations Without Reprocessing History The Case for Incremental Computation in Modern ML Stacks Kafka to Feature Store: Bridging the Stream-Batch Gap

Try Feldera

Build your first incremental pipeline today

Feldera is free to start. Connect your data source, write a SQL view, and watch features update in milliseconds as events arrive.

Read the quickstart Create free account