Skip to content
SDB
MLOps & AI Engineering

Chapter 04 · intermediate · 24 min

Feature Stores

Feast, Tecton, and Hopsworks for online/offline serving and point-in-time correctness

Subhendu Datta BhowmikAI Tutorials

The Feature Store Problem

In a mature ML platform, features are computed by many teams for many models. Without a shared infrastructure:

  • Duplication: every team recomputes the same features (customer lifetime value, 7-day transaction count)
  • Training-serving skew: the feature logic in training notebooks differs subtly from production code
  • Leakage: joining features to labels without respecting event timestamps contaminates training data
  • Latency: complex aggregations computed at request time blow through latency budgets

A feature store solves all four problems with a centralized layer that serves pre-computed features both for training (offline) and prediction (online).

Core Concepts

Offline vs. Online Serving

LayerStorageUse CaseLatency
Offline storeData warehouse (BigQuery, Snowflake, Parquet)Training data retrievalSeconds–minutes
Online storeKey-value store (Redis, DynamoDB, Bigtable)Real-time prediction servingMilliseconds

The offline store holds the full history. The online store holds the latest feature values for each entity (user_id, product_id, etc.) for low-latency inference.

Point-in-Time Correctness — A Concrete Example

Suppose you're training a fraud model. Each training example is a transaction labeled fraud/not-fraud. You want to attach the user's "number of transactions in the past 7 days" feature.

Incorrect join (leakage):

transaction_date  |  user_7day_count (computed today)
2024-01-10        |  42  ← uses data from after Jan 10!

Point-in-time correct join:

transaction_date  |  user_7day_count (as of Jan 10)
2024-01-10        |  5   ← only uses data available on Jan 10

A feature store handles this join correctly by design.

Feast

Feast (Feature Store) is the most popular open-source feature store. It is backend-agnostic and supports many offline/online storage combinations.

Key Abstractions

  • Entity: the primary key (e.g., user_id, driver_id)
  • FeatureView: a set of features computed from a data source, associated with an entity
  • FeatureService: a named collection of features served together to a model
  • DataSource: where raw data lives (BigQuery table, Parquet file, Kafka stream)
Feast Feature Definitionspython
from datetime import timedelta
from feast import Entity, FeatureView, Field, FileSource
from feast.types import Float32, Int64

# Define entities
user = Entity(name="user_id", description="User identifier")

# Define data source (could also be BigQuery, Snowflake, etc.)
transactions_source = FileSource(
    path="data/features/user_stats.parquet",
    timestamp_field="event_timestamp",
    created_timestamp_column="created",
)

# Define feature view
user_stats_fv = FeatureView(
    name="user_stats",
    entities=[user],
    ttl=timedelta(days=1),
    schema=[
        Field(name="transaction_count_7d", dtype=Int64),
        Field(name="avg_amount_7d", dtype=Float32),
        Field(name="distinct_merchants_7d", dtype=Int64),
    ],
    online=True,
    source=transactions_source,
)
Feast: Materializing and Retrieving Featurespython
from feast import FeatureStore
import pandas as pd
from datetime import datetime

store = FeatureStore(repo_path="feature_repo/")

# Materialize features into the online store (run before serving)
store.materialize_incremental(end_date=datetime.utcnow())

# --- Offline: point-in-time correct training dataset ---
entity_df = pd.DataFrame({
    "user_id": [1001, 1002, 1003],
    "event_timestamp": [
        datetime(2024, 1, 10),
        datetime(2024, 1, 11),
        datetime(2024, 1, 12),
    ],
    "label": [0, 1, 0],
})

training_df = store.get_historical_features(
    entity_df=entity_df,
    features=["user_stats:transaction_count_7d", "user_stats:avg_amount_7d"],
).to_df()

# --- Online: real-time feature retrieval for inference ---
online_features = store.get_online_features(
    features=["user_stats:transaction_count_7d", "user_stats:avg_amount_7d"],
    entity_rows=[{"user_id": 1001}, {"user_id": 1002}],
).to_dict()

Tecton

Tecton is the enterprise, fully managed feature platform. It extends the feature store concept with:

  • Streaming features: real-time feature computation from Kafka/Kinesis with guaranteed freshness
  • On-demand features: computed at request time from request payload (no pre-materialization)
  • Feature monitoring: automatic drift detection and freshness alerts
  • Git-based feature management: features defined in Python, versioned in Git, deployed via CI/CD

Best for: large organizations that need real-time streaming features and enterprise SLAs. Requires Databricks or Snowflake.

Tecton Streaming Feature Viewpython
import tecton
from tecton import stream_feature_view, Aggregate
from tecton.types import Float64, Int64
from datetime import timedelta

# Streaming feature: real-time 1-hour transaction count
@stream_feature_view(
    source=kafka_transactions,  # Kafka/Kinesis stream source
    entities=[user],
    mode="spark",
    aggregation_interval=timedelta(minutes=1),
    features=[
        Aggregate(input_column="amount", function="count",
                  time_window=timedelta(hours=1)),
        Aggregate(input_column="amount", function="sum",
                  time_window=timedelta(hours=1)),
    ],
    online=True,
    offline=True,
    ttl=timedelta(days=7),
)
def user_transaction_metrics(transactions):
    return transactions.select("user_id", "amount", "timestamp")

Hopsworks

Hopsworks is an open-source, full-stack ML platform with a feature store at its core. It includes:

  • Feature Store (HSFS): online/offline feature serving with Spark-based transformations
  • MLflow integration: experiment tracking built in
  • Model Registry: model versioning with deployment to KServe
  • Jupyter notebooks + Jobs: development and scheduled pipeline execution

Best for: teams that want a single self-hosted platform covering feature store, model registry, and serving.

Hopsworks Feature Grouppython
import hopsworks
import pandas as pd

project = hopsworks.login()
fs = project.get_feature_store()

# Create a feature group
user_stats_fg = fs.get_or_create_feature_group(
    name="user_transaction_stats",
    version=1,
    description="7-day aggregated user transaction features",
    primary_key=["user_id"],
    event_time="event_timestamp",
    online_enabled=True,
)

# Insert data (batch or streaming)
user_stats_fg.insert(user_stats_df)

# Create a feature view for training
feature_view = fs.create_feature_view(
    name="fraud_features",
    version=1,
    query=user_stats_fg.select(["transaction_count_7d", "avg_amount_7d"]),
    labels=["is_fraud"],
)

# Generate training dataset with point-in-time correctness
X_train, X_test, y_train, y_test = feature_view.train_test_split(test_size=0.2)

Comparison

CriterionFeastTectonHopsworks
LicenseOpen source (Apache 2)Enterprise SaaSOpen source + Enterprise
Streaming featuresLimitedNative, real-timeVia Spark Streaming
Managed serviceNo (self-hosted)YesOptional
Platform scopeFeature store onlyFeature store + monitoringFull ML platform
Best forOpen-source, flexible backendsReal-time, enterprise scaleSelf-hosted full platform

Knowledge check

Why is point-in-time correct feature retrieval critical for training data construction?

Summary

  1. A feature store provides centralized, versioned, reusable features with online/offline serving
  2. The offline store (data warehouse) serves training data; the online store (key-value) serves real-time predictions
  3. Point-in-time correct joins prevent training data leakage — features are retrieved as of the label event timestamp
  4. Feast is the most flexible open-source option; Tecton adds real-time streaming; Hopsworks provides a full ML platform
  5. Materialization moves computed features from the offline store into the online store for low-latency serving

Next: model serving and inference with FastAPI, TorchServe, Triton, and ONNX.

MLOps & AI Engineering