Title: Proposal: Version-qualified feature refs in get_historical_features (offline store versioning) · Issue #6389 · feast-dev/feast · GitHub
Open Graph Title: Proposal: Version-qualified feature refs in get_historical_features (offline store versioning) · Issue #6389 · feast-dev/feast
X Title: Proposal: Version-qualified feature refs in get_historical_features (offline store versioning) · Issue #6389 · feast-dev/feast
Description: Summary Feature view versioning (#6101) added @v
Open Graph Description: Summary Feature view versioning (#6101) added @v
X Description: Summary Feature view versioning (#6101) added @v<N> syntax for version-qualified online reads and feast materialize --version v<N> for writing to version-specific online tables. The off...
Opengraph URL: https://github.com/feast-dev/feast/issues/6389
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Proposal: Version-qualified feature refs in get_historical_features (offline store versioning)","articleBody":"## Summary\n\nFeature view versioning (#6101) added `@v\u003cN\u003e` syntax for version-qualified online reads and `feast materialize --version v\u003cN\u003e` for writing to version-specific online tables. The offline retrieval path (`get_historical_features`) has no equivalent: version qualifiers in feature refs are silently stripped during ibis prefix matching but never used to route to a different source table.\n\nThis means a team that pins their online serving to `driver_stats@v2` cannot generate training data from the same v2 schema — breaking training-serving consistency, which is one of the primary motivations for versioning.\n\n## The gap\n\n**Online store (works today):**\n```python\nstore.get_online_features(features=[\"driver_stats@v2:trips_today\"], ...)\n# → routes to version-specific table: {project}_driver_stats_v2\n```\n\n**Offline store (silently ignores version today):**\n```python\nstore.get_historical_features(entity_df=..., features=[\"driver_stats@v2:trips_today\"])\n# → routes to the same source table regardless of @v2\n# → version tag stripped in _parse_feature_ref / ibis prefix matching\n```\n\n## Design questions\n\nI'd like to get your input on the right approach before writing any code, since there are a few viable directions with different tradeoffs:\n\n**Option A — Version-specific source tables (mirrors online store pattern)**\nWhen `enable_online_feature_view_versioning` is enabled and a versioned ref is used, route to a version-suffixed offline source table (e.g. `{project}_driver_stats_v2`). Requires that versioned offline tables exist — either pre-created by an upstream pipeline or written by a future `feast materialize-offline --version v2`.\n\nPros: mirrors online store semantics exactly, strong training-serving consistency guarantee.\nCons: offline source data is usually externally managed; teams would need to maintain versioned source tables alongside their online tables, which may be impractical.\n\n**Option B — Schema-level version resolution (read from current table, project v\u003cN\u003e schema)**\nKeep reading from the same source table, but apply the schema of the pinned version when selecting columns. Useful when the underlying data hasn't changed but the feature view's field definitions have evolved.\n\nPros: no need to maintain separate offline tables, works with externally managed sources.\nCons: weaker guarantee — if the source data itself changed between versions, this doesn't help.\n\n**Option C — Raise `VersionedOfflineReadNotSupported` (explicit error instead of silent ignore)**\nAt minimum, detect `@v\u003cN\u003e` refs in `get_historical_features` and raise a clear error rather than silently stripping the version tag. This prevents silent training-serving skew today while the longer-term design is decided.\n\n## Questions for you\n\n1. Is offline store versioning on the roadmap for #2728, or is it intentionally out of scope?\n2. If in scope, does Option A or B better match the intended semantics?\n3. Would Option C (explicit error) be a useful interim step regardless?\n\nHappy to take this forward once there's a design direction. I've been working through the Snowflake online store versioning (#6380) and the type_map offline fixes (#6388) so I have reasonable familiarity with both sides of the retrieval path.","author":{"url":"https://github.com/Abhishek8108","@type":"Person","name":"Abhishek8108"},"datePublished":"2026-05-09T09:24:19.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/6389/feast/issues/6389"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:85992d42-43a6-2db3-75a1-e50c2d41e271 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E69E:16DD22:12BE8CF:19E6EFC:6A4DE568 |
| html-safe-nonce | cf9f2daeb609f790a427a74ba36c555b80c01011d8b1f7a3d7f6ce635106cc37 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFNjlFOjE2REQyMjoxMkJFOENGOjE5RTZFRkM6NkE0REU1NjgiLCJ2aXNpdG9yX2lkIjoiODk5NzQ3NzQzOTEzNjE5NTk0NCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | e5fd1f0adf609a8859c01090db1170ec219cd6d3b7a0c3e67968e440b8ea6191 |
| hovercard-subject-tag | issue:4412000868 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/feast-dev/feast/6389/issue_layout |
| twitter:image | https://opengraph.githubassets.com/9572821cd61e54dc53726258b3ab13fadd43d7186e5ee2b1b9435ec990d91664/feast-dev/feast/issues/6389 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/9572821cd61e54dc53726258b3ab13fadd43d7186e5ee2b1b9435ec990d91664/feast-dev/feast/issues/6389 |
| og:image:alt | Summary Feature view versioning (#6101) added @v |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | Abhishek8108 |
| hostname | github.com |
| expected-hostname | github.com |
| None | 06b8a6144231bf3a234f1c2e9993861e07ce98a905912b114aa386c2d7e84b33 |
| turbo-cache-control | no-preview |
| go-import | github.com/feast-dev/feast git https://github.com/feast-dev/feast.git |
| octolytics-dimension-user_id | 57027613 |
| octolytics-dimension-user_login | feast-dev |
| octolytics-dimension-repository_id | 161133770 |
| octolytics-dimension-repository_nwo | feast-dev/feast |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 161133770 |
| octolytics-dimension-repository_network_root_nwo | feast-dev/feast |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 1d344bdb7547fe6bca17a59bb2b8aac3dc9532a0 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width