---
title: "Configure tiered feature store"
description: "Create a Feast repository with namespace_overrides, hot and cold feature views, and FeatureServices."
---

# Configure tiered feature store

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

The tiered layout follows the [Aerospike online store reference](https://github.com/feast-dev/feast/blob/master/docs/reference/online-stores/aerospike.md) and the [aerospike overrides example](https://github.com/feast-dev/feast/tree/master/examples/online_store/aerospike_overrides_and_hooks) in the feast-dev/feast repository.

On this page, you build and register a local tiering demo that mirrors the production YAML routing structure.

## Create the feature repository

Create the project directory, feature store configuration with namespace overrides, hot and cold feature view definitions, and synthetic data for both tiers.

1.  Create a project directory:
    
    Terminal window
    
    ```shell
    mkdir -p feast-tiered-demo/data
    
    cd feast-tiered-demo
    ```
    
2.  Create `feature_store.yaml` with a default namespace and a hot override:
    
    feature\_store.yaml
    
    ```yaml
    project: cost_tiered_features
    
    registry: data/registry.db
    
    provider: local
    
    online_store:
    
      type: aerospike
    
      hosts:
    
        - ["127.0.0.1", 3000]
    
      namespace: test
    
      namespace_overrides:
    
        scoring_velocity: test
    
      ttl_seconds: 2592000
    
      read_timeout_ms: 200
    
      write_timeout_ms: 500
    
    entity_key_serialization_version: 3
    ```
    
    `registry: data/registry.db` is Feast’s local metadata store for entities, feature views, and services. `ttl_seconds: 2592000` (30 days) is the record-level Aerospike TTL stamped on every write. It retains the cold view for 30 days, but it also gives hot records the same storage TTL. Standard online reads do not apply `FeatureView.ttl` as a separate Aerospike expiry. `read_timeout_ms` and `write_timeout_ms` cap how long the Aerospike client waits before returning an error. `provider: local`, `entity_key_serialization_version: 3`, and the `hosts` list format are explained in [Tutorial: Serve real-time Feast features with Aerospike](https://aerospike.com/docs/develop/feast-aerospike-online-store/step/3/part/0/define-and-materialize#create-the-feature-repository) on the Define and materialize page.
    
    Production clusters use separate namespaces, for example `namespace: feast_ssd` with `scoring_velocity: feast_ram`. The Aerospike CE Docker image ships only `test`, so this demo maps both tiers to `test` while preserving the override structure used in production.
    
3.  Create `tiered_repo.py` with hot and cold feature views plus two services:
    
    tiered\_repo.py
    
    ```python
    from datetime import timedelta
    
    from feast import Entity, FeatureService, FeatureView, Field, FileSource
    
    from feast.types import Float32, Float64, Int64
    
    from feast.value_type import ValueType
    
    user = Entity(
    
        name="user",
    
        join_keys=["user_id"],
    
        value_type=ValueType.STRING,
    
    )
    
    velocity_source = FileSource(
    
        name="scoring_velocity_source",
    
        path="data/scoring_velocity.parquet",
    
        timestamp_field="event_timestamp",
    
    )
    
    profile_source = FileSource(
    
        name="user_profile_source",
    
        path="data/user_profile.parquet",
    
        timestamp_field="event_timestamp",
    
    )
    
    scoring_velocity = FeatureView(
    
        name="scoring_velocity",
    
        entities=[user],
    
        ttl=timedelta(hours=1),
    
        schema=[
    
            Field(name="events_1h", dtype=Int64),
    
            Field(name="spend_1h", dtype=Float64),
    
        ],
    
        source=velocity_source,
    
        tags={"tier": "hot"},  # Descriptive only. Set namespace routing with namespace_overrides in feature_store.yaml.
    
    )
    
    user_profile_wide = FeatureView(
    
        name="user_profile_wide",
    
        entities=[user],
    
        ttl=timedelta(days=30),
    
        schema=[
    
            Field(name="lifetime_value", dtype=Float64),
    
            Field(name="affinity_score", dtype=Float32),
    
        ],
    
        source=profile_source,
    
        tags={"tier": "cold"},  # descriptive only
    
    )
    
    hot_scoring_service = FeatureService(
    
        name="hot_scoring_v1",
    
        features=[scoring_velocity],
    
    )
    
    full_scoring_service = FeatureService(
    
        name="full_scoring_v1",
    
        features=[scoring_velocity, user_profile_wide],
    
    )
    ```
    
    Both feature views share the same `user` entity. Feature views that resolve to the same namespace and set colocate on one Aerospike record per entity. Routing them to different namespaces stores each view on its own record. The namespace each view lands on is controlled by `namespace_overrides` in `feature_store.yaml`, not by the `tags` field. `tags` is metadata for your own tooling and has no effect on routing.
    
    `scoring_velocity` has a one-hour Feast TTL for materialization and historical retrieval. `user_profile_wide` uses 30 days. Those settings do not create separate online record TTLs. The `FeatureService` definitions decide which views a model requests. `namespace_overrides` independently decides where those views are stored.
    
4.  Create `generate_data.py`. Wrap generation code in `if __name__ == "__main__":` so `feast apply` does not run it when Feast imports project files.
    
    generate\_data.py
    
    ```python
    from datetime import timedelta
    
    import pandas as pd
    
    def main():
    
        user_ids = ["user-1", "user-2", "user-3"]
    
        event_timestamp = pd.Timestamp.now(tz="UTC").floor("s") - timedelta(minutes=10)
    
        pd.DataFrame({
    
            "user_id": user_ids,
    
            "event_timestamp": [event_timestamp] * len(user_ids),
    
            "events_1h": [12, 8, 20],
    
            "spend_1h": [240.0, 95.5, 410.0],
    
        }).to_parquet("data/scoring_velocity.parquet")
    
        pd.DataFrame({
    
            "user_id": user_ids,
    
            "event_timestamp": [event_timestamp] * len(user_ids),
    
            "lifetime_value": [1200.0, 800.0, 3500.0],
    
            "affinity_score": [0.82, 0.61, 0.94],
    
        }).to_parquet("data/user_profile.parquet")
    
        print("Wrote scoring_velocity and user_profile parquets")
    
    if __name__ == "__main__":
    
        main()
    ```
    
    Each `DataFrame` contains three synthetic users. The script sets `event_timestamp` ten minutes in the past, then writes one Parquet file for velocity counts and another for wide profile data. Parquet is the columnar format Feast uses for these local batch sources. In production, data warehouse tables or object storage paths replace the local files.
    
5.  Run it:
    
    Terminal window
    
    ```shell
    python3 generate_data.py
    ```
    
    Expected result
    
    ```plaintext
    Wrote scoring_velocity and user_profile parquets
    ```
    

## Register definitions

`feast apply` reads the Python definitions in your project directory and records them in the Feast registry at `data/registry.db`. From that point, commands and SDK calls know your entity, feature views, and services by name. It registers definitions only. It does not copy any feature values into Aerospike, which is what materialization does on the next page.

1.  Register entities, feature views, and services:
    
    Terminal window
    
    ```shell
    feast apply
    ```
    
    Expected result
    
    ```text
    No project found in the repository. Using project name cost_tiered_features defined in feature_store.yaml
    
    Applying changes for project cost_tiered_features
    
    Deploying infrastructure for scoring_velocity
    
    Deploying infrastructure for user_profile_wide
    ```
    
2.  Confirm registration:
    
    -   Output includes `Applying changes for project cost_tiered_features`.
    -   Output includes `Deploying infrastructure for scoring_velocity` and `Deploying infrastructure for user_profile_wide`.

On the next page, you materialize both tiers and read through each `FeatureService`.

::: undefined
-   I’ve created the tiered `feature_store.yaml` and feature definitions.
-   I’ve run `feast apply` successfully.
:::

[Previous  
Namespaces and tiering layout](https://aerospike.com/docs/develop/feast-aerospike-tiering/step/2/part/0/namespaces-and-tiering) [Next  
Materialize and read by tier](https://aerospike.com/docs/develop/feast-aerospike-tiering/step/3/part/1/materialize-and-read-hot-cold)