~/writing
Deep Dives

Why Feature Stores Matter in Quant ML

On point-in-time correctness, and why leakage is the silent killer of backtests.

#mlops#feature-store#finance

Every quant ML model I’ve seen fail in production has failed for the same underlying reason: the features it was trained on weren’t actually available at the time it needed to make a decision. This is leakage, and it’s insidious because it doesn’t show up as an error — it shows up as a backtest that looks great and a live model that quietly underperforms.

The core problem

A feature computed “as of” a given date needs to reflect only information that existed at that moment. Financial data is full of traps here: earnings figures get restated, index membership changes retroactively in some datasets, and a naive groupby().rolling() over a dataframe sorted by calendar date will happily let tomorrow’s information leak into today’s row if you’re not careful about how the data was assembled.

What a feature store actually buys you

A proper point-in-time feature store separates “when did this become true” from “when did we learn about it,” and only ever serves the second. That distinction is the whole game. Concretely, it means:

  • Every feature has an event timestamp and a knowledge timestamp, and joins are always done against the knowledge timestamp.
  • The same retrieval code path serves both training and live inference, so there’s no separate “training data prep” script that can drift from what production actually sees.
  • Backfills are versioned, so a restated earnings figure doesn’t silently rewrite history for models that already trained on the old value.

The payoff

Once this is in place, a huge class of “why does the backtest look so much better than production” bugs simply can’t happen anymore, because the same code path is responsible for both. It’s not a glamorous piece of infrastructure, but it’s the piece that determines whether you can actually trust anything built on top of it.