Feature stores
After this lesson you will explain why machine-learning teams keep their features in a store of their own — one definition, an offline store for training, an online store for serving — and build a training set that never looks into the future.
In September 2017 Uber's engineering blog described Michelangelo, the platform behind the company's machine-learning models. One of its parts, a feature store, held about 10,000 features — the input columns of the models — computed every day, shared across teams by name and kept in two systems: a Hive/HDFS data lake for training and Cassandra for online predictions. The History slide of the lecture starts right there: "First Experience in Uber, with Michelangelo platform" (p. 739). Its timeline adds Airbnb, Gojek, Tecton, AWS, Databricks and Google by 2021.
Here is the puzzle. A feature such as "what this customer spent in the last 30 days" is one short query. Why did so many companies build a whole system — two stores, a catalog, monitoring — around numbers that one query computes?
Because a one-line feature can go wrong in two ways that no query will ever report: it gets computed twice, and it gets read at the wrong moment. By the end of the lesson you will name both, watch each one break a model in a widget, and know why Uber's "store" was not a new database at all.
Features and the MLOps loop
Start with the usage example of p. 738, a credit-scoring application. To decide on a loan, a model reads a few numbers about each customer: "Customer demographics (age, income, etc.)", "Historical credit behavior (loan repayments, defaults)" and "Real-time transaction data (recent purchases, account balance changes)". Each of these numbers is a feature.
Feature — "the input variables or attributes that describe (data) objects used by machine learning models to make predictions, such as customer age, transaction history, or weather conditions" (p. 720).
Feature store — "a centralized repository used to store, manage, and serve features for machine learning (ML) tasks". Its goal: "to streamline the process of creating, sharing, and using these features across various ML models" (p. 720).
In the notation of statistics a feature is a column of the design matrix \(X\); a feature store keeps those columns — named, dated and shared — outside any single model.
The same slide says where the store belongs: "It's a key asset in ML-Ops". MLOps (Machine Learning Operations) is "a set of practices and tools that aim to streamline the development, deployment, and maintenance of machine learning (ML) models in production environments"; it "extends the principles of DevOps (Development and Operations) to the ML domain" and "brings together data scientists, machine learning engineers, and operations teams" (p. 722). Page 723 draws it as a loop with no end.
Page 724 tells the same loop in five phases, each with what MLOps promises for it:
- Development — experiments with "models, algorithms, and feature sets"; code, models and datasets are versioned.
- Training and Validation — the model is trained and "validated using a test dataset", in a way that "can be reproduced".
- Deployment — automated with CI/CD practices.
- Monitoring — "real-time insights into how the model is performing, and whether data or concept drift is affecting its accuracy".
- Retraining — "When the model's performance drops or when new data becomes available".
Page 725, titled "ML-Ops – focus on data and features", draws the same lifecycle as four interlocking rings — Data, ML, Dev and Ops — and the first ring is pure data work: collect, curate, transform, validate. That ring is where a feature store works.
Fix the two drifts of phase 4 now; the slides use them without defining them. Data drift: the distribution of the inputs changes — this year's applicants are younger. Concept drift: the relation between inputs and target changes — the same spending pattern no longer means the same risk. In statistical terms \(P(X)\) moves, or \(P(Y \mid X)\) moves.
Pages 726–728 list eight components of MLOps: version control for models and data ("datasets, features, models, and hyperparameters"); CI/CD for ML; model training and retraining; monitoring and model performance tracking ("accuracy, precision, recall, and business-specific KPIs"); data and feature management; automation and orchestration ("Kubernetes, Airflow, or Kubeflow"); collaboration between teams; model governance and compliance. Page 729 adds five benefits: faster time to market, improved collaboration, increased model reliability, reusability "of code, pipelines, and features", better model governance.
The fifth component is the door to this lesson: "MLOps integrates with feature stores to ensure that the same data transformations applied during training are applied in production, avoiding issues like 'training-serving skew.'" (p. 727).
MLOps is a loop, and the features are needed at two of its stations: training and inference.
The biggest problem: one feature, computed twice
Page 743 is titled "The biggest problem to face": "Features for a machine learning model are required in both the modelling and production (deployment) phases of the lifecycle. This implies duplication of code and risk of inconsistency".
Here is what that looks like. A data scientist writes spend_l30d, a customer's spending over the last 30 days, in a notebook: purchases minus refunds, computed over the history to build the training set. The model goes live, and an engineer rewrites the same feature inside the production service — another language, a deadline, and no refunds. On 14 June customer C2, who returned an item of 220.00 the day before, has 275.00 in the training data and 495.00 in production. Both programs run without a single error.
Training-serving skew — the situation "where a model performs poorly because the features used in production differ from the ones used during training" (p. 734). Page 743 calls it "online/offline skew".
Before: two programs, two values
After: one definition, one value
The fix is to stop having two programs. On p. 742 the feature store is "An interface between the raw data and the models. It takes raw data and then transforms it into features subsequently used for model training and inference", and it "ensures that the features used across both models (and possibly many models) are consistent". The same slide calls it "a centralised repository that stores curated features" and "a data management layer that allows data scientists, machine learning engineers, and data engineers to collaborate, share, and discover features".
"Skew is just another word for drift." No. Skew happens while the world stands still: one raw input, two computations. Drift is the world changing, with one computation. A feature store removes skew by construction; drift it can only detect, by monitoring the features (p. 736) — the cure for drift is retraining.
What a feature store "grants", in the words of p. 743: "Consistency between model training and inference leads to better model accuracy", "eliminating online/offline skew", "Share and reuse features across models and teams, ensuring faster model development", "Provide feature versioning, lineage, provenance, and regulatory compliance". Page 737 sums it up in four benefits: Consistency (the same transformations in training and production), Efficiency (no redundant feature engineering), Scalability (batch and real-time features at large scale) and Version Control (models trained on older versions of features "can still be reproduced").
Two benefit lists sit a few pages apart and a closed question can mix them. MLOps (p. 729): faster time to market, improved collaboration, increased model reliability, reusability, better model governance. Feature store (p. 737): consistency, efficiency, scalability, version control.
Page 733 shows who talks to the store, and when. Data engineers, data scientists and ML engineers "Define and iterate on new features" and "Load feature data for training" and "for testing"; the prediction service in production receives the feature values computed for inference and writes back to the store ("Log served features, prediction, outcomes", "Track feature stats to identify issues"); the engineers read those back to "Monitor for drift & quality issues". Every phase of the loop reads from the store or writes to it.
Is it always worth it? Feature stores "are a must-have when working on a project where the intention is to deploy models at scale and in production"; "However, if you are working within a small team and on a small project or a POC, you may not need it" (p. 744). A proof of concept has one model and no production: nothing is computed twice.
A feature store replaces two programs that compute the same feature with one definition that feeds both training and serving.
Two stores: the history for training, the latest value for serving
One definition does not mean one database. Back to the credit score of p. 738: "For training, the offline store would provide historical data, while for real-time predictions, the online store would supply the latest transaction data." Two stores, because training and serving ask two different questions.
The offline store "Contains batch features used for model training. These are typically updated at regular intervals (e.g., daily or weekly) and stored in large-scale data storage systems like Hadoop or cloud-based data lakes" (p. 735). It keeps "months' or years' worth of feature data", "often stored in data warehouses or data lakes like S3, BigQuery, Snowflake, Redshift" (p. 765). Its question is a scan: every customer's value on every day of the last two years. That is the workload of a warehouse (lesson 23).
The online store "Contains real-time features used for serving live predictions. These features need to be served with low latency for real-time inference and are typically stored in low-latency databases like Redis" (p. 735). It persists "feature values for low-latency lookup during inference", and "They typically only store the latest feature values for each entity" (p. 765). Its question is a lookup: the current values of customer C2, now, in milliseconds — a GET on a key, exactly what Redis is built for (lesson 17).
Page 765 adds: "Online stores are usually eventually consistent." Why is that acceptable? The article the slides follow explains that most ML uses have no strict consistency requirement: a fraud check computed on a balance a few seconds old is still a sensible check, while a check that arrives after the payment has gone through is useless. Latency and availability win — the BASE side of the trade-off of lesson 5.
"Cassandra is a key-value store: p. 765 says so." Read the sentence again: "They are usually implemented with key-value stores like DynamoDB, Redis, or Cassandra" describes how an online store uses Cassandra — one lookup by partition key. As a family, the course files Cassandra under columnar databases: the exam-guideline deck lists "Key-value DB (Redis)" and "columnar DB (Cassandra)", and the course notes call it "a columnar database with some key-value features" (lesson 20). Asked for Cassandra's family, answer columnar.
Serving: one API, two answers
Reading from the two stores is the task the slides call Serving: "An easy and canonical way to access all features in a company consistently across all environments" (p. 764). Offline, "feature values are commonly accessed through notebook-friendly feature store SDKs"; online, "a feature store delivers a single vector of features at a time made up of the freshest feature values, through a high-performance API backed by a low-latency database". The figure of p. 764 asks for the same three features both ways (l7d and l30d mean "last 7 days" and "last 30 days"):
"Request feature vector for inference", answered through a REST API:
.get_feature_vector (
features=["item_clicks_l7d",
"item_price",
"user_spend_l30d"],
entities={"user_id":3,
"item_id":62}
)
The answer, "Feature Vector (latest values, low-latency)":
{
"item_clicks_l7d":6,
"item_price":"$25.12",
"user_spend_l30d":"$12.10"
}
"Request training data", answered through the Python SDK:
.get_training_data (
features=["item_clicks_l7d",
"item_price",
"user_spend_l30d"],
entities=entities_df
)
The answer, "Training Dataframe (historical values)":
user_id item_id time item_clicks_l7d item_price user_spend_l30d
1 54 7485 6 $23.2 $0
2 35 46854 5 $41.54 $8.41
The same three names, two very different answers: one vector of the latest values for one key, or one row per (entity, time) with the values as they were then. That time column comes back in section 5.
"get_feature_vector is Feast's API." No: pp. 763–769 reproduce a general article on feature stores (the Tecton article of the resources below), and the method names of p. 764 belong to that article's illustration, not to Feast. Feast's real calls are the ones of p. 762, get_historical_features and get_online_features — quote those when a question names Feast.
| Use case | Example | API |
|---|---|---|
| Training data generation | Fetching user and item features for (user, item) pairs when training a production recommendation model | get_historical_features |
| Offline feature retrieval for batch predictions | Predicting user churn for all users on a daily basis | get_historical_features |
| Online feature retrieval for real-time model predictions | Fetching pre-computed features to predict whether a real-time credit card transaction is fraudulent | get_online_features |
How do values reach the online store? Page 757, about Feast: "For offline use cases that only rely on batch data, Feast does not need to ingest data and can query your existing data", while "For online use cases, Feast supports ingesting features from batch sources to make them available online (through a process called materialization), and pushing streaming features to make them available both offline / online". The offline store can be the warehouse you already have, queried in place; materialization copies the latest value of each key into the online store; a stream pushes to both.
The widget puts the two stores, and the two programs of section 2, side by side. Its one insight: skew is silent — it appears, hides and reappears with the data and the calendar, and only one shared definition removes it.
The offline store answers "what was the value then?" for training; the online store answers "what is the value now?" for one key, in milliseconds.
Inside the box: five tasks
Page 763 opens the box (Fig. 3). Data enter from a stream source and a batch source and leave towards model serving and model training. Three tasks sit on the data path — transform, storage, serving, with an on-demand transform inside serving — and two span all of them: operational monitoring above, the registry below. The slides number them 1 Serving, 2 Storage, 3 Transform, 4 Monitoring, 5 Registry; you have met the first two.
Transform: where feature engineering runs
Page 741 defines what the transform task runs. Feature engineering: "DEF: a machine learning approach that extracts features from a raw dataset, resulting in new features". It "ranges from basic transformations such as aggregations to more advanced feature transformations such as word embeddings produced by machine learning algorithms", and its goal is "to essentially create a better dataset to improve the performance of machine learning algorithms". Page 734 names the everyday steps: "aggregations, normalization, one-hot encoding".
The jobs "are executed on data processing engines (e.g. Spark or Pandas) to which the feature store is connected" (p. 766): the store orchestrates them, it does not replace Spark (lesson 38). Page 767 sorts them into three kinds, by when their input exists:
| Feature type | Definition | Common input data source | Example |
|---|---|---|---|
| Batch Transform | Transformations that are applied only to data at rest | Data warehouse, data lake, database | User country, product category |
| Streaming Transform | Transformations that are applied to streaming sources | Kafka, Kinesis, PubSub | # of clicks per vertical per user in last 30 minutes, # of views per listing in past hour |
| On-demand transform | Transformations that are used to produce features based on data that is only available at the time of the prediction. These features cannot be pre-computed. | User-facing application | Is the user currently in a supported location? Similarity score between listing and search query |
The vector served on p. 766 mixes all three, colour-coded on the slide: "item_clicks_last_5_mins":6 comes from a stream transform, "user_spend_last_30_days":"$1.10" from a batch transform, and "user_current_location":"US_NY" from an on-demand transform fed with the request's application data, {user_ip: "x.x.x.x"}. Why can't the third be precomputed? Its input — where the user is right now — exists only when the request arrives.
Monitoring and the registry
Monitoring (p. 768) tracks "operational metrics relating to core functionality": for storage "availability, capacity, utilization, staleness", for serving "throughput, latency, error rates". Keep it apart from the key component "Monitoring and Validation" (p. 736), which checks the feature values themselves so that "data drifts or anomalies are detected early". One watches the machine, the other the data.
The registry "is a central interface for user interactions with the feature store. Teams use the registry as a common catalog to explore, develop, collaborate on, and publish new definitions. The registry allows for important metadata to be attached to feature definitions" (p. 769). It holds definitions, not values. It is what makes reuse real: the "catalog or search functionality" of p. 736 lets the next data scientist find spend_l30d instead of writing it a third time.
Pages 734–736 list eight "Key Components". Each lives in one of the five tasks (the mapping is ours):
| Key component | In the slide's words | Task |
|---|---|---|
| 1 Feature Storage | "historical features (used for training models) and real-time features (used for serving live predictions)" | Storage |
| 2 Feature Engineering Pipeline | "aggregations, normalization, one-hot encoding" | Transform |
| 3 Feature Versioning | "critical in avoiding 'training-serving skew'" | Registry |
| 4 Online and Offline Stores | batch features for training; real-time features "with low latency" | Storage |
| 5 Feature Serving | "training environments (batch mode) and production environments (real-time)" | Serving |
| 6 Data Governance & Access Control | "who can create, access, or update certain features" | Registry |
| 7 Feature Discoverability and Reusability | "a catalog or search functionality" | Registry |
| 8 Monitoring and Validation | "data drifts or anomalies are detected early" | Monitoring |
Three tasks on the data path — transform, storage, serving — and two over all of them: monitoring and the registry.
Feast: entities, feature views and the point-in-time join
The deck ends with one technology in detail: Feast, "Feature Store for Machine Learning", "Type: Open-source" (p. 746). It was born at the ride-hailing company Gojek with Google Cloud and announced in January 2019 (Google Cloud blog) — the "Go-jek 2019" dot of p. 739. Its objects form a small tree (Fig. 4).
driver_stats, rating and driver_id are the example of the next table.Project — "Projects provide complete isolation of feature stores at the infrastructure level. This is accomplished through resource namespacing" (p. 757).
Entity — "a collection of semantically related features. Users define entities to map to the domain of their use case" (p. 758): a driver, a customer.
Feature view — "a collection of features" (p. 758), bound to its entities and to one data source.
Data source — "raw underlying data that users own (e.g. in a table in BigQuery). Feast does not manage any of the raw underlying data" (p. 759).
Registry — "Feast uses a registry to store all applied Feast objects (e.g. Feature views, entities, etc). The registry exposes methods to apply, list, retrieve and delete these objects" (p. 759).
A feature view maps to "0 or more entities" (p. 758): zero for a global feature ("num_daily_global_transactions"), one for a user feature ("user_age or last_5_bought_items"), several — "aka a composite key" — for a feature of a pair ("num_user_purchases_in_merchant_category", a user and a merchant category). "A collection of entities for a feature view is called an entity key", and "Entities should be reused across feature views", so that features about the same thing are found, and joined, on the same key.
Then the sentence the rest of this section unpacks: "Feast uses a time-series data model to represent data. This data model is used to interpret feature data in data sources in order to build training datasets or materialize features into an online store" (p. 759). Pages 760–761 show what its rows look like:
customer_id.)| row | timestamp | customer_id | driver_id | trips_today | rating |
|---|---|---|---|---|---|
| timestamp | entity | entity | feature | feature | |
| 1 | 5/22/2021 0:00:00 | customer_A | driver_1001 | 5 | 4.8 |
| 2 | 5/22/2021 0:00:00 | customer_B | driver_1002 | 0 | 4.2 |
| 3 | 5/22/2021 0:00:00 | customer_C | driver_1003 | 8 | 4.5 |
| 4 | 5/22/2021 0:00:00 | customer_D | driver_1004 | 3 | 4.2 |
The slides use "entity key" in two senses: the set of entities of a feature view (p. 758), and the pair of values that identifies one row, (customer_A, driver_1001) in the red frame of p. 761. Both are Feast's usage. In Feast's Python SDK the driver view of p. 760 is declared like this (adapted from the Feast documentation; not on the slides):
# a feature view: two features of the entity "driver",
# read from a BigQuery table
from datetime import timedelta
from feast import BigQuerySource, Entity, FeatureView, Field
from feast.types import Float32, Int64
driver = Entity(name="driver", join_keys=["driver_id"])
driver_stats = FeatureView(
name="driver_stats",
entities=[driver],
ttl=timedelta(days=1),
schema=[
Field(name="trips_today", dtype=Int64),
Field(name="rating", dtype=Float32),
],
source=BigQuerySource(table="my-project.rides.driver_stats"),
)
Why the timestamp matters: the point-in-time join
Why insist on time? Build a training set for "will this trip end in a complaint?". The labels arrive as rows — driver, time of the trip, complaint yes or no — called the entity dataframe. To each row you must attach the driver's rating. A plain join on driver_id with today's table gives every row today's rating, including ratings computed after the trip, perhaps because of that very complaint. The model trains on information it will never have in production: data leakage. Its symptom is an offline score far better than anything production delivers.
Feast's documentation names the cure — the slides do not: "Feast performs a point-in-time join (also called a 'last known good value' temporal join): for each entity row, it retrieves the latest feature values with a timestamp at or before the entity row's event_timestamp." Without that rule, "features generated after the prediction time could leak into training data — effectively letting the model 'see the future'". In symbols:
- \(k,\ t\)
- the entity key and the timestamp of one training row
- \(\tau_i\)
- the timestamps of the feature rows with the same key \(k\)
- \(v(k, \tau)\)
- the feature value of the row with key \(k\) and timestamp \(\tau\)
- ttl
- time to live of the feature view: how old a value may be and still count
Take one row of the entity dataframe: key
driver_1001, timestamp 5/22 10:00.Keep the feature rows with the same key: 4.6 (5/20), 4.7 (5/21), 4.8 (5/22), 4.9 (5/23), 4.9 (5/24), all at 0:00.
Drop every row dated after 10:00 on 5/22: the two values 4.9 did not exist yet when the trip took place.
Take the latest of what remains: \(\tau^{*}\) = 5/22 0:00, value 4.8 — the rating p. 760 prints for that day.
Check its age against the ttl: 10 hours, inside a ttl of one day, so 4.8 is joined. Older than the ttl, the feature would be null — and null too if no rating were dated at or before 10:00.
The same rule explains the online store: materialization is the point-in-time join evaluated at "now" for every key — "the latest feature values for each entity" (p. 765). The widget builds the training set both ways. Its one insight: a training row may only see the past of its own timestamp, and a plain join quietly hands it the future.
In Feast the whole join is one call, and the online lookup another (Feast documentation; store is the FeatureStore of your project):
# the training set: one row per labelled trip,
# each row joined point-in-time
import pandas as pd
entity_df = pd.DataFrame({
"driver_id": ["driver_1001", "driver_1002"],
"event_timestamp": pd.to_datetime(
["2021-05-22 10:00", "2021-05-22 20:00"]),
"complaint": [0, 1],
})
training_df = store.get_historical_features(
entity_df=entity_df,
features=["driver_stats:rating", "driver_stats:trips_today"],
).to_df()
# one vector of the latest values for one key, for a prediction now
features = store.get_online_features(
features=["driver_stats:rating", "driver_stats:trips_today"],
entity_rows=[{"driver_id": "driver_1001"}],
).to_dict()
A training row may only see feature values dated at or before its own timestamp; the online store is the same join, taken at "now".
Nine products, one history, five dimensions
Page 739 says where it all began: "First Experience in Uber, with Michelangelo platform." Fig. 5 redraws its timeline.
Pages 746–754 review nine products in one template, "Type" plus "Key Characteristics". Most traits repeat on every slide ("Online and Offline Stores", versioning, "real-time and batch"); what tells them apart is the type and one or two traits:
| System | Type | What sets it apart on its slide |
|---|---|---|
| 1 Feast (p. 746) | Open-source | cloud-agnostic or on-premise; "Simple Design: Focuses on feature serving"; "Good for Startups/SMEs" |
| 2 Hopsworks (p. 747) | Open-source (with enterprise version) | Spark, TensorFlow, Kubernetes; stores "backed by distributed systems like Apache Hive and MySQL"; RBAC and GDPR |
| 3 Tecton (p. 748) | Commercial | "Built specifically for real-time machine learning"; automated batch and streaming pipelines; drift monitoring |
| 4 AWS SageMaker Feature Store (p. 749) | Proprietary (part of AWS SageMaker) | S3, Redshift, Glue; IAM for access control |
| 5 Databricks Feature Store (p. 750) | Proprietary (part of Databricks) | "Unified with Delta Lake"; feature lineage; native Spark |
| 6 Google Vertex AI Feature Store (p. 751) | Proprietary (part of Google Cloud) | fully managed; BigQuery, Dataflow; drift and anomaly monitoring |
| 7 Azure ML Feature Store (p. 752) | Proprietary (part of Microsoft Azure) | Data Lake, Azure Synapse; Azure Active Directory |
| 8 Scribble Data Enrich (p. 753) | Proprietary | customizable enrichment pipelines; cloud-agnostic; "SME Focus" |
| 9 Featureform (p. 754) | Open-source | "Declarative Feature Definitions"; multi-cloud; "Lightweight Design" |
The course covers every family of systems "along 5 dimensions" (intro deck, slide 6). The feature-store slides do not fill them in; here is the profile their pages imply (ours):
| Dimension | Feature store |
|---|---|
| (1) data model | an entity-keyed time series: rows of entity key, timestamp and feature values, grouped into feature views and described in a registry (pp. 758–761) |
| (2) (declarative vs. imperative) query languages | declarative feature definitions (Feast's Python objects; Featureform's "Declarative Feature Definitions"), read through two SDK calls, get_historical_features and get_online_features (p. 762): lookups by key and point-in-time joins, no general query language |
| (3) data distribution | the offline store on a distributed warehouse or lake (S3, BigQuery, Snowflake, Redshift, Hadoop), the online store on a distributed key-value store (Redis, DynamoDB); materialization and push move data between them (pp. 735, 757, 765) |
| (4) non-functional aspects | low latency and freshness online, volume and history offline; online stores usually eventually consistent; operational metrics for storage and serving (pp. 765, 768) |
| (5) architectural solutions | five tasks: transform (batch, streaming, on-demand), storage (offline and online), serving, monitoring, registry (p. 763) |
So where does a feature store sit among the systems of this course? Above them:
| System | What it holds | How you read it | Its place in a feature store |
|---|---|---|---|
| Data warehouse or lake (lesson 23) | historical tables | scans and aggregations over years | the offline store |
| Key-value store such as Redis (lesson 17) | one value per key | a GET by key, in milliseconds | the online store |
| Vector database (lessons 27–28) | embeddings and an index over them | nearest neighbours by similarity | an embedding can be a feature, but the store looks it up by entity key, not by similarity |
| Stream processing (lesson 33) | events as they arrive | continuous transforms | the source of streaming features, pushed to both stores |
Back to Uber. Michelangelo's shared features lived in HDFS/Hive for training and in Cassandra for online predictions, and the transformations each model applied to them were written in a small language whose "expressions are part of the model configuration and the same expressions are applied at training time and at prediction time" (Uber Engineering blog, 2017). One definition, so a feature is not computed twice; two stores, one for the history and one for the latest values, read by key. The second danger of the hook, reading a value at the wrong moment, is what the timestamps of the time-series model and the point-in-time join are for. That is why the "store" was never a new database: it is a layer of definitions over a data lake and a low-latency store. The deck's last sentence says the same: "a feature store acts as the backbone of the feature lifecycle in machine learning systems, enabling teams to efficiently manage and serve high-quality features across different stages of the ML pipeline, from model development to deployment" (p. 771).
A feature store is a layer — a registry of definitions over a warehouse for the history and a key-value store for the latest values — not a new kind of database.
Exam-style questions
Feature stores have appeared in no past paper, and the practical part of 2026/27 covers Neo4j, MongoDB, Elasticsearch, Redis and SparkQL: this lesson belongs to the theory part. Its questions come in the forms the readme of the past papers names — open-ended, multiple-choice, true or false — and wrong answers may carry a penalty, announced just before the exam.
Define training-serving skew as presented in the lecture. Explain why it arises in machine-learning systems, how a feature store prevents it, and how it differs from data drift.
Show model answer
Training-serving skew, also called online/offline skew, is the situation in which a model performs poorly because the features used in production differ from the ones used during training. It arises because features are required both in the modelling phase and in the production (deployment) phase of the lifecycle: when each phase has its own feature code, the code is duplicated and the two implementations can silently diverge, for example in the time window, in the handling of refunds or in the default for missing values. A feature store prevents it by keeping one registered and versioned definition per feature and one transformation pipeline, whose results are stored in an offline store, which provides historical values for training, and in an online store, which provides the latest values with low latency for inference, both accessed through one serving API. In this way the same feature transformations are applied in training and in production. Data drift is different: the distribution of the input data changes over time while the computation stays the same; a feature store can detect drift by monitoring the features, but the remedy is retraining.
A complete answer has three parts: the definition in the slide's words (p. 734, with the synonym of p. 743), the cause — two code paths for one feature (p. 743) — and the mechanism: one definition, two stores. The contrast with drift shows understanding rather than memory.
In a feature store, which component typically stores only the latest feature values for each entity and is usually eventually consistent?
Show model answer
The online store. It persists the latest feature value of each entity for low-latency lookups during inference, usually in a key-value store such as Redis or DynamoDB, and it is usually eventually consistent. The offline store keeps months or years of history for training.
Every distractor is another component of the same architecture; the two properties in the question are the ones p. 765 gives the online store.
True or false: in Feast, for offline use cases that rely only on batch data, the data must first be ingested into the feature store.
Show model answer
False. For offline use cases that rely only on batch data, Feast does not need to ingest data and queries the existing data in place. Data are ingested only for online use cases: batch features are materialized into the online store, and streaming features are pushed to make them available both offline and online.
A true/false item is easy to build by flipping one slide sentence. With a possible penalty for wrong answers, answer only what the sentence of p. 757 supports.
In Feast, what are an entity, a feature view and an entity key? Give an example of a feature view with zero entities, one with one entity and one with several entities, and explain why Feast uses a time-series data model.
Show model answer
An entity is a collection of semantically related features, defined by the users to map to the domain of their use case, for example a driver or a customer. A feature view is a collection of features, bound to its entities and to a data source; it maps to zero or more entities. A collection of entities for a feature view is called an entity key; in the data, the entity key of a row is the tuple of its entity values, for example (customer_A, driver_1001). Zero entities: a global feature such as num_daily_global_transactions. One entity: a user feature such as user_age or last_5_bought_items. Several entities, a composite key: num_user_purchases_in_merchant_category, for a user and a merchant category. Feast uses a time-series data model, in which every row carries a timestamp, the entity values and the feature values, in order to build training datasets and to materialize features into an online store: the timestamps let a training row receive the latest feature values at or before its own time, without values from the future, and they tell materialization which value is the latest.
The definitions are p. 758 almost word for word, the examples too; the composite key is the part that is easiest to forget. The last sentence goes beyond the slides (point-in-time correctness is in the Feast documentation): it shows why p. 759 insists on time.
Which of the following features can only be produced by an on-demand transformation? Select all that apply.
Show model answer
The third and the fourth. On-demand transformations produce features from data that is only available at the time of the prediction, coming from the user-facing application, so they cannot be pre-computed. User country and product category come from batch transformations of data at rest; views per listing in the past hour come from a streaming transformation.
The examples are p. 767's own, so a question can use them verbatim. The test to apply: does the input exist before the request arrives? If it does, the feature can be precomputed.
Consider the ER scenario of the exam of 12 Sep 2025, tracking farmers and their sales at local markets: People (Personal ID, Name, Surname, Age, Address, State) Buy Products (Product ID, Name, Quantity, Expiration Date), with a Buy Date and an Amount; Products are sold at Markets (Name, Location, Opening Time, Closing Time, Size).
A cooperative wants two models: (a) every night, predict for each product the amount that will be bought the next day; (b) at the moment a person pays, decide whether the purchase is fraudulent. Using a feature store, propose for each model its entity key and features of the three transformation types where they fit, say which store serves each prediction, and which Feast retrieval method is used for training and for prediction.
Show model answer
(a) Entity Product, entity key Product ID. Batch features computed from the history of Buy: the total Amount bought in the last 7 days, the number of days to the Expiration Date. Training: get_historical_features with an entity dataframe of (Product ID, date) rows labelled with the amount of the next day, so that each row is joined with the feature values at or before its date. The nightly prediction for all products is a batch prediction: it also uses get_historical_features on the offline store; no low latency is needed.
(b) Entity Person, entity key Personal ID. Batch feature: Age. Streaming feature: the number of purchases of this person in the last 10 minutes, computed from the stream of Buy events and pushed to both stores. On-demand feature: whether the market of the payment is open at the time of the payment, computed at request time from the request data and the market's Opening Time and Closing Time; it cannot be precomputed. Training: get_historical_features on past purchases labelled fraudulent or not. Prediction: get_online_features for the Personal ID, served by the online store with the latest values and low latency, plus the on-demand transformation at request time.
Ours, not a past-paper exercise: the scenario is borrowed to practise the vocabulary in context. The trap is (a): a nightly prediction is offline, exactly as "Predicting user churn for all users on a daily basis" on p. 762, so it uses get_historical_features, not the online store.
According to the lecture, which of these feature stores are open-source? Select all that apply.
Show model answer
Feast, Hopsworks and Featureform. Tecton is commercial; AWS SageMaker, Databricks, Google Vertex AI and Azure ML feature stores are proprietary parts of their platforms, and Scribble Data Enrich is proprietary too.
Pure recall of pp. 746–754: three open-source, one commercial, five proprietary. Hopsworks is the one to hesitate on — the slide types it as open-source with an enterprise version.
Check yourself
A fraud model scores very well on its offline test set and clearly worse in production from its first day. Nothing in the world has changed. What is the most likely cause?
driver_1001 has ratings 4.6 (5/20 0:00), 4.7 (5/21 0:00), 4.8 (5/22 0:00) and 4.9 (5/23 0:00). A training row is dated 5/22 10:00. Which rating does a point-in-time join attach?
Which statements about the offline store are true? Select all that apply.
History and scans offline, the latest value and lookups online: the two stores answer two different questions.
Why can an online store afford to be only eventually consistent?
A Feast feature view computes num_user_purchases_in_merchant_category. What is its entity key?
What does materialization do in Feast?
A data scientist is about to write spend_l30d from scratch, although a colleague wrote it last year. Which task of the feature store should have stopped her?
Key take-aways
- A feature is an input variable of a model; a feature store is "a centralized repository used to store, manage, and serve features for machine learning (ML) tasks" (p. 720) and "a key asset in ML-Ops", the practices that run the loop of development, training and validation, deployment, monitoring and retraining.
- The biggest problem (p. 743): features are needed both in modelling and in production, so two programs compute them and drift apart — training-serving skew, or online/offline skew. A feature store replaces them with one definition. Skew is not drift: drift is the world changing.
- The offline store keeps months or years of history in warehouses and lakes, refreshed daily or weekly, for training; the online store keeps only the latest value of each entity in a low-latency key-value store, usually eventually consistent, for inference. Materialization fills the online store; streams push to both.
- Inside the box (p. 763): 1 Serving, 2 Storage, 3 Transform (batch, streaming, on-demand), 4 Monitoring (operational metrics), 5 Registry (the catalog of definitions).
- Feast: projects, feature views, features, entities, entity keys (composite when several), data sources it does not manage, a registry, a time-series data model;
get_historical_featuresfor training and batch predictions,get_online_featuresfor real-time predictions. - Point-in-time correctness: each training row is joined with the latest feature value at or before its own timestamp, null beyond the ttl; a plain join leaks the future and inflates offline scores.
- Nine products (pp. 746–754): open-source Feast, Hopsworks and Featureform, commercial Tecton, five proprietary. A feature store is a layer over storage you already have — a warehouse or lake for the history, a low-latency store for the latest values; the first was Uber's Michelangelo in 2017 (p. 739).
What to watch and read
-
Meet Michelangelo: Uber's Machine Learning Platform
Jeremy Hermann and Mike Del Balso, Uber Engineering, 2017
The first public feature store, the "First Experience in Uber" of p. 739: about 10,000 shared features, kept in HDFS/Hive for training and in Cassandra for online predictions, with transformation expressions applied the same way at training and at prediction time.
-
Point-in-time joins
Feast documentation
The timeline picture behind section 5 and its widget: each row of the entity dataframe looks back, within the ttl, for the latest feature value.
-
What is a Feature Store?
Tecton article, now hosted by Databricks
The source of pp. 763–769: serving, storage, transform, monitoring and registry in the authors' own words, with the reasons behind the online store's eventual consistency.
-
Rules of Machine Learning
Martin Zinkevich, Google
The section on training-serving skew: re-use code between training and serving, beware of joining tables that change, measure the skew — the practices a feature store builds in.
-
Feature Stores: A Hierarchy of Needs
Eugene Yan
The key components of pp. 734–737 as a ladder — access, serving, integrity, convenience, autopilot — with real feature stores compared, and the same caveat as p. 744.