A feature store is a data system with two layers — an offline store (Parquet/S3) for batch training and an online store (Redis) for low-latency inference. It guarantees models trained offline see the exact same feature values as models serving predictions in production, eliminating training-serving skew. Learn it hands-on at /learn/feature-stores or build a real one with /projects/predictflow-feature-store.
What is a feature store?
In machine learning, a feature is a numeric input to a model — things like days_since_last_login, transaction_amount_7d_avg, or user_churn_score. Computing these features consistently across training and serving is harder than it sounds. A feature store solves this with a unified platform that manages feature definitions, history, and retrieval.
The architecture is a dual store. The offline store holds historical feature values in Parquet on S3, used to generate training datasets via point-in-time joins. The online store holds the latest feature values in Redis, used at inference time for sub-10ms lookups.
Critically, both stores share one feature definition — a Python FeatureView checked into git. The same code that computes a feature for batch training also computes it for online serving, which is why training-serving skew disappears.
Master feature stores in 5 hours, hands-on.
From Feast FeatureView definitions to point-in-time joins, online materialization, and drift monitoring on a production-shaped dataset.
Why does a feature store matter?
- Eliminates training-serving skew — one definition for batch and online
- Point-in-time joins prevent the most common form of ML data leakage
- Feature reuse across churn, fraud, and personalization models
- Sub-10ms online lookup unlocks real-time inference at scale
- Audit trail of feature values at any historical timestamp (regulator-friendly)
- Decouples ML engineers (consume features) from data engineers (produce features)
How does a feature store work?
A feature store sits between your raw data warehouse and your models. Features flow through four stages — compute, store, serve, monitor.
- Compute — a scheduled job (Airflow, Spark, dbt) materializes feature values from raw events into the offline store
- Store — the offline store keeps historical values with event timestamps; the online store keeps the latest values per entity
- Serve — training jobs call
get_historical_features()for point-in-time correct joins; inference services callget_online_features()for sub-10ms lookups - Monitor — drift detection compares the distribution of online features against the offline training distribution
A FeatureView in Feast looks like this:
from feast import FeatureView, Entity, Field, FileSource
from feast.types import Float32, Int64
from datetime import timedelta
customer = Entity(name="customer_id", value_type=Int64)
customer_source = FileSource(
path="s3://my-bucket/customer_features.parquet",
event_timestamp_column="event_timestamp",
)
customer_features = FeatureView(
name="customer_features",
entities=[customer],
ttl=timedelta(days=7),
schema=[
Field(name="days_since_last_login", dtype=Float32),
Field(name="transaction_count_7d", dtype=Int64),
Field(name="avg_transaction_amount_7d", dtype=Float32),
],
source=customer_source,
)
The same definition powers both training (get_historical_features()) and inference (get_online_features()), so the computation can never drift.
Feature store vs raw warehouse
| Dimension | Raw Warehouse | Feature Store |
|---|---|---|
| Purpose | Analytics queries | Manage ML features |
| Storage | Columnar (BigQuery, Snowflake) | Parquet + Redis |
| Latency | Seconds to minutes | <10ms online lookup |
| Versioning | Time-partitioned tables | Point-in-time TTL |
| Primary consumer | Data analyst | ML engineer / model |
| Point-in-time joins | Manual SQL gymnastics | Built-in primitive |
Use the warehouse for business analytics. Use the feature store for ML inputs. The feature store often reads from the warehouse — a dbt mart of customer_metrics_7d becomes the source for a customer_features FeatureView.
Point-in-time correctness — the killer feature
Naive feature joins leak the future. If you join today's lifetime_revenue to a churn label from six months ago, the model learns from information it could not have seen at the label timestamp. Offline metrics look great; production metrics collapse.
Point-in-time joins fix this by joining features as of the label timestamp — only values that existed at or before that moment are visible. Feast handles this automatically:
entity_df = pd.DataFrame({
"customer_id": [1001, 1002, 1003],
"event_timestamp": pd.to_datetime(["2025-09-15", "2025-09-20", "2025-09-25"]),
"label": [1, 0, 1],
})
training_df = store.get_historical_features(
entity_df=entity_df,
features=["customer_features:days_since_last_login",
"customer_features:transaction_count_7d"],
).to_df()
Every row in training_df gets the feature values that existed at its own event_timestamp — no time travel into the future.
Build a real PredictFlow feature store with Feast.
Offline Parquet + online Redis, point-in-time training data, real-time scoring at sub-50ms, and drift monitoring with Evidently. Mentor-reviewed.
Common mistakes (and what to do instead)
- Computing features differently in notebooks vs production APIs — the #1 cause of "the model worked offline." Define every feature once in a FeatureView and reuse it for both paths.
- Skipping point-in-time correctness in training joins — leaks the future, inflates offline metrics. Use
get_historical_features()with aevent_timestampcolumn. - Not materializing to the online store before serving —
feast materializeis required before requests hit production, or every lookup falls back to slow recomputation. - Treating the feature store like a warehouse — storing raw business events instead of pre-computed ML-ready features. The warehouse stores facts; the feature store stores model inputs.
- Forgetting TTL on FeatureViews — without a TTL, stale features serve forever. Set it to the freshness window you can actually guarantee in materialization.
Who is a feature store for?
Feature stores serve ML engineers, MLOps platform teams, and the senior data engineers who build the upstream feature pipelines. The audience scales with the level:
- Junior ML engineer — learns to define FeatureViews and run
feast applyagainst an existing infrastructure - Senior data engineer — designs the feature pipelines from raw warehouse data through Airflow/Spark into materialized offline + online stores
- Staff / ML platform engineer — architects the full platform (feature store + model registry + serving), evaluates Feast vs Tecton vs Hopsworks, defines naming + TTL standards across teams
Teams that benefit most: real-time fraud scoring, churn prediction, personalization rankers, credit-risk models that need point-in-time audit, and any multi-model setup where one feature (user_embedding, transaction_velocity_7d) is reused across surfaces.
Frequently asked questions
Start shipping.
Three steps from a guide to a job-ready portfolio. Pick one and start now — the rest will follow.
Take the skill
Self-paced module with code, exercises, and a deliverable. Free preview, paid completion.
Start S0X · Feature Store →Ship the project
Production-grade build with starter kit + mentor code review. The artifact that gets you interviews.
Open P0X · Predictflow Feature Store →Pick a career path
The full progression — skills + projects + interview prep — for the role you actually want.
See paths →