Skip to content

Materialize and read by tier

For the complete documentation index see: llms.txt

All documentation pages available in markdown.

With the tiered feature repository defined and registered, you now materialize both feature views into Aerospike and compare reads through the hot-only and full FeatureService objects.

Materialize both feature views

Copy the latest values from both Parquet files into Aerospike so get_online_features has data to read.

  1. Materialize into Aerospike:

    Copy both feature views from their Parquet files into Aerospike with feast materialize-incremental, using the current UTC time as the end timestamp. For what each output line means, see the register and materialize step in Tutorial: Serve real-time Feast features with Aerospike.

    Terminal window
    feast materialize-incremental $(date -u +"%Y-%m-%dT%H:%M:%S")
    Expected result
    Materializing 2 feature views to 2026-07-14 21:54:28+00:00 into the aerospike online store.
    scoring_velocity from 2026-07-14 20:54:31+00:00 to 2026-07-14 21:54:28+00:00:
    user_profile_wide from 2026-06-14 21:54:31+00:00 to 2026-07-14 21:54:28+00:00:

    Your timestamps differ from this example. On the first incremental materialization, Feast uses each feature view’s TTL to select its lookback window.

  2. Confirm materialization:

    • The summary reports Materializing 2 feature views.
    • Both scoring_velocity and user_profile_wide appear in the output.

Read through each FeatureService

Read features through hot_scoring_v1 and full_scoring_v1 separately to confirm that the hot-only service returns only velocity feature fields and the full service adds the wide profile feature fields.

  1. Create read_by_service.py:

    read_by_service.py
    from feast import FeatureStore
    store = FeatureStore(repo_path=".")
    entity_rows = [{"user_id": "user-1"}]
    hot = store.get_online_features(
    features=store.get_feature_service("hot_scoring_v1"),
    entity_rows=entity_rows,
    ).to_dict()
    full = store.get_online_features(
    features=store.get_feature_service("full_scoring_v1"),
    entity_rows=entity_rows,
    ).to_dict()
    print("hot_scoring_v1:", hot)
    print("full_scoring_v1:", full)

    store.get_feature_service("hot_scoring_v1") looks up the named FeatureService from the registry and returns the feature list it covers. The request does not enumerate individual features. Coordinate service-membership changes with the model’s expected schema and version the service when its contract changes.

    Two separate get_online_features calls demonstrate that hot_scoring_v1 and full_scoring_v1 are independent. In production, use one service or the other, not both for the same request.

  2. Run it:

    Terminal window
    python3 read_by_service.py
    Expected result
    hot_scoring_v1: {'user_id': ['user-1'], 'events_1h': [12], 'spend_1h': [240.0]}
    full_scoring_v1: {'user_id': ['user-1'], 'events_1h': [12], 'spend_1h': [240.0], 'lifetime_value': [1200.0], 'affinity_score': [0.82]}

    Verify that hot_scoring_v1 returns only velocity feature fields. full_scoring_v1 adds profile feature fields.

  3. Confirm the service split:

    • hot_scoring_v1 output includes events_1h and spend_1h only.
    • full_scoring_v1 output also includes lifetime_value and affinity_score.

    Feast issues one online_read per requested feature view. For this one-entity request, each online_read produces one batch_operate. With separate memory and flash namespaces in production, hot_scoring_v1 calls the memory tier once and full_scoring_v1 adds a flash-tier call for user_profile_wide. See Read behavior across tiers.