Accepted
When a feature view's schema changed in Feast, the old definition was silently overwritten. This created several problems:
- No audit trail: Teams couldn't answer "what did this feature view look like last week?" or "who changed the schema and when?"
- No safe rollback: If a schema change broke a downstream model, there was no way to revert without manually reconstructing the previous definition.
- No multi-version serving: During migrations, teams often need to serve both old and new schemas simultaneously (e.g., model A uses v1 features, model B uses v2 features). This required creating entirely separate feature views.
Add automatic version tracking to Feast feature views. Every time feast apply detects a schema or UDF change, a versioned snapshot is saved to the registry.
- Version number: Auto-incrementing integer (v0, v1, v2, ...) for each schema-significant change.
- Version snapshot: Serialized copy of the full feature view proto stored in the registry.
- Version pin: Setting
version="v2"on a feature view replaces the active definition with the v2 snapshot. - Version-qualified ref: The
@v<N>syntax (e.g.,driver_stats@v2:trips_today) for reading from a specific version.
Only schema and UDF changes create new versions:
- Adding, removing, or retyping feature columns.
- Changing entities or entity columns.
- Changing UDF code (StreamFeatureView, OnDemandFeatureView).
Metadata-only changes (description, tags, owner, TTL) update the active definition in place without creating a version.
Version history tracking is lightweight registry metadata (serialized proto snapshots). There is no performance cost to the online path. Every feast apply that changes a feature view will:
- Record a version snapshot.
- Support
feast feature-views list-versions <name>to list history. - Support
registry.list_feature_view_versions(name, project)programmatically. - Support
registry.get_feature_view_by_version(name, project, version_number).
Version-qualified reads from separate online store tables are gated behind a config flag:
registry:
path: data/registry.db
enable_online_feature_view_versioning: trueWhen enabled, driver_stats@v2:trips_today reads from a version-specific table (project_driver_stats_v2). When disabled (default), using @v<N> refs raises a clear error.
driver_stats = FeatureView(
name="driver_stats",
entities=[driver],
schema=[...],
source=my_source,
version="v2", # revert to v2's definition
)Safety: The user's definition (minus the version field) must match the currently active definition. If both schema and version pin are changed, feast apply raises FeatureViewPinConflict.
The --no-promote flag saves a version snapshot without updating the active definition, enabling phased rollouts:
# Stage the new version
feast apply --no-promote
# Populate the v2 online table
feast materialize --views driver_stats --version v2 ...
# Migrate consumers one at a time (using @v2 refs)
# Promote v2 as the default
feast applyEach version's data lives in its own online store table. By default, feast materialize targets the active version. A --version flag targets specific versions:
feast materialize --views driver_stats --version v1 2024-01-01T00:00:00 2024-01-15T00:00:00- SQL registry: Unique constraint on
(feature_view_name, project_id, version_number)with retry logic for auto-increment races. - File registry: Last-write-wins (pre-existing limitation).
- Online store coverage: Version-qualified reads are only on SQLite initially.
- Offline store versioning is out of scope.
- No mechanism to prune old versions.
- Cross-version joins in
get_historical_featuresare not supported.
- Full audit trail of schema changes for every feature view.
- Safe rollback capability through version pinning.
- Multi-version serving enables gradual migrations without creating duplicate feature views.
- Always-on history tracking with zero performance cost to the online path.
- Staged publishing supports safe, phased rollouts of breaking changes.
- Version-qualified online reads are initially limited to SQLite.
- Offline versioning is not supported, creating a gap for reproducing historical training data.
- No version pruning mechanism may lead to unbounded growth in long-lived feature views.
- Concurrency handling differs between SQL and file registries.
- Original RFC: Feature View Versioning
- Pull Request: #6101
- Implementation:
sdk/python/feast/feature_view.py(version fields),docs/adr/feature-view-versioning.md