Skip to content

Comments

feat: Add lazy initialization and feature service caching#5924

Merged
franciscojavierarceo merged 5 commits intomasterfrom
feat/performance-optimizations-lazy-loading-caching
Jan 30, 2026
Merged

feat: Add lazy initialization and feature service caching#5924
franciscojavierarceo merged 5 commits intomasterfrom
feat/performance-optimizations-lazy-loading-caching

Conversation

@franciscojavierarceo
Copy link
Member

@franciscojavierarceo franciscojavierarceo commented Jan 30, 2026

Implement performance optimizations for FeatureStore:

  • Lazy Initialization: Convert registry, provider, and OpenLineage emitter
    to lazy properties. Reduces cold start from 2.4s to 0.5s (5x improvement).

  • Feature Service Caching: Add caching layer for feature service resolution.
    Observed 19.6x speedup on cached calls during validation.

Co-Authored-By: Claude Sonnet 4 noreply@anthropic.com


Open with Devin

franciscojavierarceo and others added 2 commits January 29, 2026 23:31
Implement performance optimizations for FeatureStore:

- **Lazy Initialization**: Convert registry, provider, and OpenLineage emitter
  to lazy properties. Reduces cold start from 2.4s to 0.5s (5x improvement).

- **Feature Service Caching**: Add caching layer for feature service resolution.
  Observed 19.6x speedup on cached calls during validation.

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
@franciscojavierarceo franciscojavierarceo requested a review from a team as a code owner January 30, 2026 05:00
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

🔴 1 issue in files not directly in the diff

🔴 __repr__ triggers lazy initialization despite comment saying it shouldn't (sdk/python/feast/feature_store.py:194)

The __repr__ method accesses self.registry (the property) instead of self._registry (the private attribute), which triggers lazy initialization of the registry.

Click to expand

How the bug is triggered

The comment on line 193 says "Show lazy loading status without triggering initialization", but line 194 uses self.registry which is a property that initializes the registry if it's None:

# feature_store.py:192-194
def __repr__(self) -> str:
    # Show lazy loading status without triggering initialization
    registry_status = "not loaded" if self.registry is None else "loaded"

The registry property at feature_store.py:206-217 creates the registry when accessed:

@property
def registry(self) -> BaseRegistry:
    if self._registry is None:
        self._registry = self._create_registry()
        ...
    return self._registry

Actual vs Expected

  • Actual: Calling repr(feature_store) or print(feature_store) triggers registry initialization, negating lazy loading benefits
  • Expected: Should use self._registry to check status without triggering initialization

Impact

This defeats the purpose of lazy initialization (described as reducing cold start from 2.4s to 0.5s). Any code that prints or logs the FeatureStore object will trigger full initialization.

Recommendation: Change self.registry to self._registry on line 194

View issues and 5 additional flags in Devin Review.

Open in Devin Review

When refresh_registry() or plan() methods refresh the registry, the feature
service cache must be cleared to avoid serving stale cached results.

- Add _clear_feature_service_cache() helper method
- Clear cache in refresh_registry() and plan() methods
- Prevents data consistency issues with cached feature services
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

🔴 1 issue in files not directly in the diff

🔴 __repr__ triggers lazy initialization despite comment saying it shouldn't (sdk/python/feast/feature_store.py:194)

The __repr__ method accesses self.registry (the property) instead of self._registry (the private attribute), which triggers lazy initialization of the registry.

Click to expand

How the bug is triggered

The comment on line 193 says "Show lazy loading status without triggering initialization", but line 194 uses self.registry which is a property that initializes the registry if it's None:

# feature_store.py:192-194
def __repr__(self) -> str:
    # Show lazy loading status without triggering initialization
    registry_status = "not loaded" if self.registry is None else "loaded"

The registry property at feature_store.py:206-217 creates the registry when accessed:

@property
def registry(self) -> BaseRegistry:
    if self._registry is None:
        self._registry = self._create_registry()
        ...
    return self._registry

Actual vs Expected

  • Actual: Calling repr(feature_store) or print(feature_store) triggers registry initialization, negating lazy loading benefits
  • Expected: Should use self._registry to check status without triggering initialization

Impact

This defeats the purpose of lazy initialization (described as reducing cold start from 2.4s to 0.5s). Any code that prints or logs the FeatureStore object will trigger full initialization.

Recommendation: Change self.registry to self._registry on line 194

View issue and 6 additional flags in Devin Review.

Open in Devin Review

Fixes AttributeError where tests were directly accessing _registry before
lazy initialization. With lazy loading, _registry starts as None and must
be accessed through the registry property to trigger initialization.

- Replace ._registry. with .registry. in test files
- Add runtime error check in registry property for failed initialization
- Ensures backward compatibility with existing code patterns

Fixes CI test failures in search API tests.
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

🔴 1 issue in files not directly in the diff

🔴 __repr__ triggers lazy initialization despite comment saying it shouldn't (sdk/python/feast/feature_store.py:194)

The __repr__ method accesses self.registry (the property) instead of self._registry (the private attribute), which triggers lazy initialization of the registry.

Click to expand

How the bug is triggered

The comment on line 193 says "Show lazy loading status without triggering initialization", but line 194 uses self.registry which is a property that initializes the registry if it's None:

# feature_store.py:192-194
def __repr__(self) -> str:
    # Show lazy loading status without triggering initialization
    registry_status = "not loaded" if self.registry is None else "loaded"

The registry property at feature_store.py:206-217 creates the registry when accessed:

@property
def registry(self) -> BaseRegistry:
    if self._registry is None:
        self._registry = self._create_registry()
        ...
    return self._registry

Actual vs Expected

  • Actual: Calling repr(feature_store) or print(feature_store) triggers registry initialization, negating lazy loading benefits
  • Expected: Should use self._registry to check status without triggering initialization

Impact

This defeats the purpose of lazy initialization (described as reducing cold start from 2.4s to 0.5s). Any code that prints or logs the FeatureStore object will trigger full initialization.

Recommendation: Change self.registry to self._registry on line 194

View issue and 8 additional flags in Devin Review.

Open in Devin Review

The __repr__ method was accidentally calling self.registry (property) instead of
self._registry (attribute), which would trigger lazy initialization whenever
the FeatureStore object was printed or logged.

This completely defeated the lazy loading optimization since any debugging,
logging, or repr() call would cause full initialization (negating the 2.4s
to 0.5s performance gain).

- Change self.registry to self._registry in __repr__ method
- Preserves lazy loading benefits for debugging/logging scenarios
- Maintains correct status reporting without side effects
@franciscojavierarceo franciscojavierarceo merged commit b37b7d0 into master Jan 30, 2026
22 of 25 checks passed
YassinNouh21 pushed a commit to YassinNouh21/feast that referenced this pull request Feb 7, 2026
…5924)

* feat: Add lazy initialization and feature service caching

Implement performance optimizations for FeatureStore:

- **Lazy Initialization**: Convert registry, provider, and OpenLineage emitter
  to lazy properties. Reduces cold start from 2.4s to 0.5s (5x improvement).

- **Feature Service Caching**: Add caching layer for feature service resolution.
  Observed 19.6x speedup on cached calls during validation.

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>

* fix: Add type annotations and formatting fixes for performance optimizations

* fix: Clear feature service cache on registry refresh

When refresh_registry() or plan() methods refresh the registry, the feature
service cache must be cleared to avoid serving stale cached results.

- Add _clear_feature_service_cache() helper method
- Clear cache in refresh_registry() and plan() methods
- Prevents data consistency issues with cached feature services

* fix: Replace direct _registry access with registry property

Fixes AttributeError where tests were directly accessing _registry before
lazy initialization. With lazy loading, _registry starts as None and must
be accessed through the registry property to trigger initialization.

- Replace ._registry. with .registry. in test files
- Add runtime error check in registry property for failed initialization
- Ensures backward compatibility with existing code patterns

Fixes CI test failures in search API tests.

* fix: Prevent __repr__ from triggering lazy initialization

The __repr__ method was accidentally calling self.registry (property) instead of
self._registry (attribute), which would trigger lazy initialization whenever
the FeatureStore object was printed or logged.

This completely defeated the lazy loading optimization since any debugging,
logging, or repr() call would cause full initialization (negating the 2.4s
to 0.5s performance gain).

- Change self.registry to self._registry in __repr__ method
- Preserves lazy loading benefits for debugging/logging scenarios
- Maintains correct status reporting without side effects

---------

Co-authored-by: Claude Sonnet 4 <noreply@anthropic.com>
Signed-off-by: yassinnouh21 <yassinnouh21@gmail.com>
YassinNouh21 pushed a commit to YassinNouh21/feast that referenced this pull request Feb 7, 2026
…5924)

* feat: Add lazy initialization and feature service caching

Implement performance optimizations for FeatureStore:

- **Lazy Initialization**: Convert registry, provider, and OpenLineage emitter
  to lazy properties. Reduces cold start from 2.4s to 0.5s (5x improvement).

- **Feature Service Caching**: Add caching layer for feature service resolution.
  Observed 19.6x speedup on cached calls during validation.

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>

* fix: Add type annotations and formatting fixes for performance optimizations

* fix: Clear feature service cache on registry refresh

When refresh_registry() or plan() methods refresh the registry, the feature
service cache must be cleared to avoid serving stale cached results.

- Add _clear_feature_service_cache() helper method
- Clear cache in refresh_registry() and plan() methods
- Prevents data consistency issues with cached feature services

* fix: Replace direct _registry access with registry property

Fixes AttributeError where tests were directly accessing _registry before
lazy initialization. With lazy loading, _registry starts as None and must
be accessed through the registry property to trigger initialization.

- Replace ._registry. with .registry. in test files
- Add runtime error check in registry property for failed initialization
- Ensures backward compatibility with existing code patterns

Fixes CI test failures in search API tests.

* fix: Prevent __repr__ from triggering lazy initialization

The __repr__ method was accidentally calling self.registry (property) instead of
self._registry (attribute), which would trigger lazy initialization whenever
the FeatureStore object was printed or logged.

This completely defeated the lazy loading optimization since any debugging,
logging, or repr() call would cause full initialization (negating the 2.4s
to 0.5s performance gain).

- Change self.registry to self._registry in __repr__ method
- Preserves lazy loading benefits for debugging/logging scenarios
- Maintains correct status reporting without side effects

---------

Co-authored-by: Claude Sonnet 4 <noreply@anthropic.com>
Signed-off-by: yassinnouh21 <yassinnouh21@gmail.com>
franciscojavierarceo pushed a commit that referenced this pull request Feb 17, 2026
# [0.60.0](v0.59.0...v0.60.0) (2026-02-17)

### Bug Fixes

* Added a flag to correctly download the go binaries ([0f77135](0f77135))
* Adds mapping of date Trino's type into string Feast's type ([531e839](531e839))
* **ci:** Use uv run for pytest in master_only benchmark step ([#5957](#5957)) ([5096010](5096010))
* Disable materialized odfvs for historical retrieval ([#5880](#5880)) ([739d28a](739d28a))
* Fix linting and formatting issues ([#5907](#5907)) ([42ca14a](42ca14a))
* Make timestamp field handling  compatible with Athena V3 ([#5936](#5936)) ([e2bad34](e2bad34))
* Support pgvector under non-default schema ([#5970](#5970)) ([c636cd4](c636cd4))
* unit tests not running on main branch ([#5909](#5909)) ([62fe664](62fe664))
* Update java dep which blocking release ([#5903](#5903)) ([a5b8186](a5b8186))
* Update the dockerfile with golang 1.24.12. ([#5918](#5918)) ([be1b522](be1b522))
* Use context.Background() in client constructors ([#5897](#5897)) ([984f93a](984f93a))

### Features

* Add blog post for PyTorch ecosystem announcement ([#5906](#5906)) ([d2eb629](d2eb629))
* Add blog post on Feast dbt integration ([#5915](#5915)) ([b3c8138](b3c8138))
* Add DynamoDB in-place list update support for array-based features ([#5916](#5916)) ([aa5973f](aa5973f))
* Add HTTP connection pooling for remote online store client ([#5895](#5895)) ([e022bf8](e022bf8))
* Add integration tests for dbt import ([#5899](#5899)) ([a444692](a444692))
* Add lazy initialization and feature service caching ([#5924](#5924)) ([b37b7d0](b37b7d0))
* Add multiple entity support to dbt integration ([#5901](#5901)) ([05a4fb5](05a4fb5)), closes [#5872](#5872)
* Add PostgreSQL online store support for Go feature server ([#5963](#5963)) ([b8c6f3d](b8c6f3d))
* Add publish docker image of Go feature server. ([#5923](#5923)) ([759d8c6](759d8c6))
* Add Set as feature type ([#5888](#5888)) ([52458fc](52458fc))
* Added online server worker config support in operator ([#5926](#5926)) ([193c72a](193c72a))
* Added support for OpenLineage integration ([#5884](#5884)) ([df70d8d](df70d8d))
* Adjust ray offline store to support abfs(s) ADLS Azure Storage ([#5911](#5911)) ([d6c0b2d](d6c0b2d))
* Batch_engine config injection in feature_store.yaml through operator ([#5938](#5938)) ([455d56c](455d56c))
* Consolidate Python packaging - remove setup.py/setup.cfg, standardize on pyproject.toml and uv ([16696b8](16696b8))
* **go:** Add MySQL registry store support for Go feature server ([#5933](#5933)) ([19f9bb8](19f9bb8))
* Improve local dev experience with file-aware hooks and auto parallelization ([#5956](#5956)) ([839b79e](839b79e))
* Modernize precommit hooks and optimize test performance ([#5929](#5929)) ([ea7d4fa](ea7d4fa))
* Optimize container infrastructure for production ([#5881](#5881)) ([5ebdac8](5ebdac8))
* Optimize DynamoDB online store for improved latency ([#5889](#5889)) ([fcc8274](fcc8274))
soooojinlee pushed a commit to soooojinlee/feast that referenced this pull request Feb 18, 2026
# [0.60.0](feast-dev/feast@v0.59.0...v0.60.0) (2026-02-17)

### Bug Fixes

* Added a flag to correctly download the go binaries ([0f77135](feast-dev@0f77135))
* Adds mapping of date Trino's type into string Feast's type ([531e839](feast-dev@531e839))
* **ci:** Use uv run for pytest in master_only benchmark step ([feast-dev#5957](feast-dev#5957)) ([5096010](feast-dev@5096010))
* Disable materialized odfvs for historical retrieval ([feast-dev#5880](feast-dev#5880)) ([739d28a](feast-dev@739d28a))
* Fix linting and formatting issues ([feast-dev#5907](feast-dev#5907)) ([42ca14a](feast-dev@42ca14a))
* Make timestamp field handling  compatible with Athena V3 ([feast-dev#5936](feast-dev#5936)) ([e2bad34](feast-dev@e2bad34))
* Support pgvector under non-default schema ([feast-dev#5970](feast-dev#5970)) ([c636cd4](feast-dev@c636cd4))
* unit tests not running on main branch ([feast-dev#5909](feast-dev#5909)) ([62fe664](feast-dev@62fe664))
* Update java dep which blocking release ([feast-dev#5903](feast-dev#5903)) ([a5b8186](feast-dev@a5b8186))
* Update the dockerfile with golang 1.24.12. ([feast-dev#5918](feast-dev#5918)) ([be1b522](feast-dev@be1b522))
* Use context.Background() in client constructors ([feast-dev#5897](feast-dev#5897)) ([984f93a](feast-dev@984f93a))

### Features

* Add blog post for PyTorch ecosystem announcement ([feast-dev#5906](feast-dev#5906)) ([d2eb629](feast-dev@d2eb629))
* Add blog post on Feast dbt integration ([feast-dev#5915](feast-dev#5915)) ([b3c8138](feast-dev@b3c8138))
* Add DynamoDB in-place list update support for array-based features ([feast-dev#5916](feast-dev#5916)) ([aa5973f](feast-dev@aa5973f))
* Add HTTP connection pooling for remote online store client ([feast-dev#5895](feast-dev#5895)) ([e022bf8](feast-dev@e022bf8))
* Add integration tests for dbt import ([feast-dev#5899](feast-dev#5899)) ([a444692](feast-dev@a444692))
* Add lazy initialization and feature service caching ([feast-dev#5924](feast-dev#5924)) ([b37b7d0](feast-dev@b37b7d0))
* Add multiple entity support to dbt integration ([feast-dev#5901](feast-dev#5901)) ([05a4fb5](feast-dev@05a4fb5)), closes [feast-dev#5872](feast-dev#5872)
* Add PostgreSQL online store support for Go feature server ([feast-dev#5963](feast-dev#5963)) ([b8c6f3d](feast-dev@b8c6f3d))
* Add publish docker image of Go feature server. ([feast-dev#5923](feast-dev#5923)) ([759d8c6](feast-dev@759d8c6))
* Add Set as feature type ([feast-dev#5888](feast-dev#5888)) ([52458fc](feast-dev@52458fc))
* Added online server worker config support in operator ([feast-dev#5926](feast-dev#5926)) ([193c72a](feast-dev@193c72a))
* Added support for OpenLineage integration ([feast-dev#5884](feast-dev#5884)) ([df70d8d](feast-dev@df70d8d))
* Adjust ray offline store to support abfs(s) ADLS Azure Storage ([feast-dev#5911](feast-dev#5911)) ([d6c0b2d](feast-dev@d6c0b2d))
* Batch_engine config injection in feature_store.yaml through operator ([feast-dev#5938](feast-dev#5938)) ([455d56c](feast-dev@455d56c))
* Consolidate Python packaging - remove setup.py/setup.cfg, standardize on pyproject.toml and uv ([16696b8](feast-dev@16696b8))
* **go:** Add MySQL registry store support for Go feature server ([feast-dev#5933](feast-dev#5933)) ([19f9bb8](feast-dev@19f9bb8))
* Improve local dev experience with file-aware hooks and auto parallelization ([feast-dev#5956](feast-dev#5956)) ([839b79e](feast-dev@839b79e))
* Modernize precommit hooks and optimize test performance ([feast-dev#5929](feast-dev#5929)) ([ea7d4fa](feast-dev@ea7d4fa))
* Optimize container infrastructure for production ([feast-dev#5881](feast-dev#5881)) ([5ebdac8](feast-dev@5ebdac8))
* Optimize DynamoDB online store for improved latency ([feast-dev#5889](feast-dev#5889)) ([fcc8274](feast-dev@fcc8274))

Signed-off-by: soojin <soojin@dable.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant