ML Feature Pipelines and Feature Stores Questions
Data infrastructure for machine learning: feature pipelines, feature stores, online/offline consistency, training-serving skew, and data preparation for models. Covers building reliable feature platforms and preventing leakage in the data path feeding models. The data-engineering-for-ML topic.
A model has started showing more false positives, and you suspect a mismatch between offline feature computation and online serving retrieval. Describe a plan to detect, reproduce, and fix issues caused by inconsistent feature computation (for example, a stale cache, missing keys, or a serialization difference), including the instrumentation and tests you would add to prevent recurrence.
Sample Answer
Direct answer: Detecting and reproducing a training-serving inconsistency starts by comparing the exact feature values the model saw at training time against what the online path currently returns for the same entities, narrowing down whether the divergence is a stale cache, a missing key, or a serialization mismatch, and closing the loop with instrumentation that would catch this class of bug automatically going forward.
Structured elaboration:
- Detect. Set up a systematic comparison: for a sample of entities, pull their feature values from the offline (training-time) computation and from the online serving path for the same point in time, and diff them; a consistently non-zero diff rate (not just occasional noise) confirms a real inconsistency rather than expected minor timing differences.
- Reproduce. Narrow to specific entities showing the largest divergence and trace each one's value through the pipeline: what did the offline computation produce, what does the online store currently hold, and when was the online value last updated, which starts distinguishing the candidate causes.
- Stale cache. If the online value's last-updated timestamp is old relative to when it should have refreshed, the online materialization pipeline itself may be lagging or failing silently for a subset of entities (worth checking if it correlates with a specific partition or shard); the fix here is addressing the materialization lag/failure, not the feature logic itself.
- Missing keys. If some entities have no online value at all (falling back to a default or null that the offline path would not have produced), trace whether those entities are newly created (a cold-start gap between when an entity is created and when it first gets materialized online) or whether a upstream join or filter is silently excluding them from the online materialization pipeline that the offline pipeline does not exclude them from.
- Serialization differences. If values exist on both sides but differ, check whether the offline and online computation paths are using genuinely the same transformation logic (a common root cause is the two paths having independently-implemented, subtly different logic, e.g. different rounding, different null-handling, or a unit mismatch) versus a serialization/deserialization bug (a type coercion, an encoding mismatch) that corrupts an otherwise-correct value on the way to or from the online store.
- Instrumentation and tests to prevent recurrence. Add an automated, continuously-running online/offline consistency check (not just a one-time investigation) that samples entities and alerts if the divergence rate exceeds a threshold; add a unit or integration test asserting the offline and online computation paths, when fed the same input, produce identical output, so a future code change that lets the two paths drift apart is caught in CI rather than in production months later.
Worked example: The investigation finds that entities with a specific upstream data source (say, a newer mobile client version) show the highest divergence; tracing one such entity reveals the online path's transformation logic was updated recently to handle a new field from that client version, but the corresponding offline (batch) transformation logic was never updated to match, meaning the two paths have silently diverged for exactly the population using the new client, which explains both the false-positive symptom (features computed differently for a subset of the population) and why it was not caught immediately (it only affected a growing but still partial slice of traffic).
Trade-offs & pitfalls: A common trap is fixing the specific instance of divergence found (patching the online or offline logic to match) without addressing why the two paths were able to drift apart in the first place; the durable fix is usually architectural, such as sharing the actual transformation code between the offline and online paths (a single source of truth for the logic, executed in both a batch and a streaming/serving context) rather than maintaining two independently-written implementations that have to be manually kept in sync, which is the root cause this class of bug keeps recurring from in practice.
You need to communicate a data contract for real-time feature serving to the engineering team, given this sample feature specification: feature_name | type | unit | cardinality | null_policy | freshness_seconds. Describe the required schema details, cardinality constraints, null handling, update frequency, and freshness SLA you would specify, and how you would manage a later schema change without breaking downstream models.
Sample Answer
Direct answer: Communicating a feature's data contract to engineering means being explicit and unambiguous about five things for every field: its type, its unit, its expected cardinality, how nulls are handled, and the freshness SLA (service-level agreement), since each of these is a place where an implicit assumption on either side commonly causes a production bug.
Structured elaboration:
- Type. State the exact type (int32 vs int64, float precision, string vs. categorical enum) since a mismatch here is a common source of silent truncation or serialization errors that only appear at scale.
- Unit. Explicitly state units for any numeric feature (seconds vs. milliseconds, dollars vs. cents, percent as 0-1 vs. 0-100), since unit mismatches between what a data scientist assumes and what engineering implements are a classic, easy-to-miss bug class that produces plausible-looking but wrong numbers.
- Cardinality constraints. For categorical features, state the expected set of values (an enum) or an approximate cardinality bound for high-cardinality fields, so engineering can make sane storage and indexing decisions and so an unexpected new value (a bug, or a legitimate new category that needs handling) can be detected rather than silently accepted.
- Null handling. State explicitly whether null is a valid value, what it means semantically if so (missing data vs. "not applicable" vs. "zero"), and what engineering should do if a null appears where the contract says it shouldn't (reject the record, substitute a default, alert).
- Update frequency and freshness SLA. State how often the feature is expected to update and the maximum acceptable staleness before it's considered a violation, which engineering needs to design the materialization cadence and monitoring thresholds around, and which also tells them what latency budget they have for the underlying computation.
Worked example: For the sample schema feature_name | type | unit | cardinality | null_policy | freshness_seconds, a row like avg_session_duration | float64 | seconds | continuous, 0-86400 range | null means no sessions in window, treat as 0 for scoring | 300 unambiguously tells engineering: store as a 64-bit float, values are in seconds and bounded to a sensible daily range (useful for a sanity-check validator), a null has a specific defined meaning with a specific handling rule (not an error condition), and the feature must be no more than 5 minutes stale, which directly informs how often the materialization job needs to run.
Managing a later schema change without breaking downstream models: treat any change to this contract the same way as the schema-evolution content elsewhere in this topic: introduce a new field or a new version rather than silently changing the existing field's meaning, communicate the change and a migration timeline to all known consumers, and only retire the old shape once consumers have confirmed migration, since a downstream model retrained on a silently-changed feature (same name, different meaning) can degrade in a way that is very hard to diagnose because nothing "broke" in an obviously visible way, the feature just quietly started meaning something different.
Trade-offs & pitfalls: Under-specifying the contract (skipping units or null semantics because "it's obvious") is the single most common way this communication fails in practice, since what is obvious to the person who defined the feature is frequently not obvious to the engineer implementing it, and the resulting bug (a unit mismatch, a mishandled null) is often subtle enough to pass initial testing and only surface once the feature is in wide production use. A contract that is written once and never revisited also drifts from reality as the feature's actual implementation evolves informally, so treating the contract as a living document that changes alongside the feature (not a one-time handoff artifact) keeps it trustworthy.
What is Change Data Capture (CDC)? Name at least two commonly used CDC tools and outline how you would integrate CDC events into a downstream feature pipeline while preserving low latency and correctness.
Sample Answer
Direct answer: Change Data Capture (CDC) is a technique for continuously capturing row-level insert, update, and delete events from a source database (typically by reading its transaction/write-ahead log) and streaming them to downstream consumers, rather than periodically polling or bulk-exporting the whole table.
Structured elaboration:
- Debezium: an open-source CDC platform that reads a database's write-ahead log (Postgres's logical replication slots, MySQL's binlog, etc.) and publishes row-level change events to Kafka; it is the most widely used open-source option and supports many source databases through connectors.
- AWS DMS (Database Migration Service): a managed AWS service that supports both one-time bulk migration and ongoing CDC replication from a source database to a target (which can be another database, S3, or a stream); convenient if you are already on AWS and want a managed CDC pipeline without operating Debezium/Kafka Connect yourself.
- Confluent's CDC connectors: source connectors within the Kafka Connect ecosystem (often built on Debezium under the hood) that integrate tightly with a Confluent-managed Kafka deployment.
Integrating CDC into a downstream feature pipeline: the CDC tool publishes a stream of change events (each carrying the changed row's before/after state and the operation type) to a message queue (typically Kafka); a stream processor consumes that change stream, applies any needed transformation (deriving a feature from the changed row, or simply passing through updated field values), and writes the result to the feature store's online and/or offline path. Because CDC captures changes as they commit to the source database's log, latency from a source-table write to a downstream feature update can be in the seconds range, much lower than a periodic batch export. To preserve correctness, the pipeline needs to process change events in the order they were committed per row (most CDC tools preserve per-key ordering) and apply idempotent writes downstream, since CDC connectors typically guarantee at-least-once delivery, not exactly-once.
Trade-offs & pitfalls: CDC adds an operational dependency on the source database's replication mechanism (a logical replication slot in Postgres, for example, must be actively consumed or it can cause the source database's write-ahead log to grow unbounded and eventually threaten the source database's own disk space); a CDC pipeline that falls behind or stops consuming is not just a downstream data-freshness problem, it can become a source-database incident. Schema changes on the source table (a column added or renamed) need to be handled by both the CDC connector and every downstream consumer, since CDC events reflect the source schema directly and a breaking change there propagates immediately to every consumer of the change stream.
You are alerted that a model's AUC fell 10% after an upstream schema change. Construct a step-by-step investigation and remediation plan: backtracking the schema change, running data-quality checks, analyzing distribution drift, deciding between retraining and rollback, and communicating with stakeholders.
Sample Answer
Direct answer: The investigation starts by pinpointing exactly what the schema change altered (backtracking it), checks whether that alteration introduced a data-quality problem or a genuine distribution shift, and only then decides between retraining and rolling back, communicating findings to stakeholders throughout rather than only at the end.
Structured elaboration:
- Backtrack the schema change. Identify precisely what changed (a field's type, a renamed column, a newly-nullable field, a changed encoding) and when it was deployed, correlating the timing against when the AUC (area under the curve) drop was first observed; a schema change that landed shortly before the AUC drop is the natural first hypothesis, but confirm the timing correlation before assuming causation.
- Data-quality checks. Check whether the schema change introduced obviously bad data: a spike in nulls for a field that used to rarely be null, values now out of an expected range, a field silently defaulting to zero or a placeholder because a type coercion failed quietly rather than erroring loudly. These checks are cheap and fast, and a very large fraction of real incidents like this one turn out to be a data-quality problem introduced by the schema change, not a genuine shift in the underlying real-world distribution.
- Distribution drift analysis. If data quality checks come back clean, compare the feature's distribution before and after the schema change (using the same kind of statistical tests covered elsewhere in ML-monitoring contexts, such as population stability index or a KS-test) to determine whether the schema change altered what values the feature can even take (for example, a previously-truncated field now reporting full precision, subtly shifting its distribution) versus the model simply seeing a population it was never trained on for an unrelated reason.
- Retraining vs. rollback decision. If the schema change is a genuine, intentional improvement (more accurate data, a fixed bug in the upstream source) and data quality is otherwise fine, the right fix is usually retraining the model on data reflecting the new, corrected schema, since rolling back would mean reverting a legitimate improvement. If the schema change introduced a data-quality regression (nulls, truncation, a broken join), the right fix is rolling back the schema change (or fixing it forward quickly) and NOT retraining on the bad data, since retraining on corrupted input would just teach the model the corruption rather than fix the underlying problem.
- Stakeholder communication. Communicate early and iteratively: an initial "we've identified a likely cause, investigating further" message once the schema-change correlation is found, rather than waiting until the full root cause and fix are confirmed, since stakeholders (including whoever depends on the model's predictions) need to know as soon as possible whether to trust recent predictions, even before the full resolution is ready.
Worked example: The AUC drop correlates with a schema change that made a previously-required last_login_days field nullable; a data-quality check finds the null rate on that field jumped from under 1% to 15% right after the change, tracing to an upstream service that started omitting the field for a subset of users under a specific new condition; this is a data-quality regression, not a genuine distribution shift, so the fix is coordinating with the upstream team to restore the field (or handling the null explicitly and correctly in the feature pipeline if the upstream omission is actually intentional going forward) rather than retraining the model to accept a 15% null rate as normal.
Trade-offs & pitfalls: Jumping straight to retraining without first distinguishing a data-quality regression from a genuine distribution shift is a common mistake that can mask the real problem: retraining on corrupted data (a spike in nulls treated as "the new normal") often recovers some AUC in the short term while baking in a systematic weakness that resurfaces later or degrades the model's behavior on the affected population specifically. Conversely, assuming every post-schema-change AUC drop must be a data-quality issue and rolling back reflexively, without checking, risks reverting a genuinely beneficial schema fix and leaving the original bug the schema change was meant to address back in place.
A website's click events arrive at 50,000 events per second. Analytics needs hourly aggregates, but an online recommender needs features fresher than 5 seconds. Compare batch and streaming ingestion architectures for this workload, discussing trade-offs in latency, cost, operational complexity, state management, and fault tolerance, and give a recommendation.
Sample Answer
Direct answer: At 50,000 click events per second with two very different downstream needs (hourly aggregates for analytics, sub-5-second freshness for a recommender), the right design runs both a streaming path and a batch path off the same ingested event log, rather than forcing one architecture to serve both needs.
Structured elaboration:
- Ingestion. All 50,000 events/sec land in a durable log (Kafka), decoupling ingestion rate from either downstream consumer's processing rate and giving replay capability for both paths.
- Streaming path (for the recommender). A stream processor consumes the log continuously, computing the near-real-time features (e.g. a short rolling window of recent activity) and writing them to a low-latency online store, meeting the sub-5-second freshness requirement.
- Batch path (for hourly analytics). The same log (or a copy of the raw events landed in object storage) is processed hourly by a batch job that computes the coarser aggregates, writing to the offline/analytics store; this path can be simpler and cheaper since it does not need to meet a tight latency bound.
- State management. The streaming path needs bounded, checkpointed state for its rolling windows (as covered in the windowing/watermarking sub-area of this topic); the batch path largely avoids persistent state since each run processes a complete, bounded chunk of data.
- Fault tolerance. The streaming path needs checkpointing and a fast-recovery story (a few seconds of downtime is tolerable, a few minutes may violate the freshness SLA (service-level agreement)); the batch path's fault tolerance is simpler (a failed run is retried from the last successful checkpoint or rerun entirely for that hour).
Worked example: At 50,000 events/sec, an hourly batch job processes roughly 180 million events per run; a well-provisioned Spark job on a modestly sized cluster comfortably aggregates that volume within a small fraction of the hour it has available, leaving generous headroom for retries. The streaming path processing the same 50,000 events/sec continuously needs enough parallelism (partitioned consumers) that no single task falls behind the source rate, which is a much tighter, always-on capacity requirement than the batch path's "finish comfortably within an hour" bar.
Trade-offs & pitfalls: Running both a streaming and a batch path off the same source (a lambda-architecture-style split) means the two paths' feature-computation logic can drift apart over time if not carefully shared or tested against each other, producing subtly different numbers for what is conceptually "the same" underlying metric at different time granularities; a common mitigation is sharing the core transformation logic between both paths where possible, and monitoring for large divergence between the streaming path's rolled-up hourly total and the batch path's independently-computed hourly total as a correctness check.
Unlock Full Question Bank
Get access to all 17 ML Feature Pipelines and Feature Stores interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.