---
title: "Push sources and velocity features"
description: "How Feast PushSource and store.push() keep velocity features fresh in Aerospike."
---

# Push sources and velocity features

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

This page explains how `PushSource` and `store.push()` keep velocity features fresh, why aggregation happens outside Feast, and how to align TTL with your rolling window length.

## Write and read paths

Feast splits the work in two. A background process computes the rolling aggregates and writes them into Aerospike with `store.push()`. At scoring time, Feast reads back whatever value that process wrote most recently.

| Path | Who computes aggregates | Feast API |
| :-- | :-- | :-- |
| Write (freshness) | Your background process (a Kafka consumer, Flink job, or timed script) | `store.push()` |
| Read (scoring) | No aggregation. Reads stored values. | `get_online_features()` |

Feast performs no aggregation on the read path, which is what keeps scoring fast: the model pays for a stored-value read instead of a computation over the account’s recent transactions. In exchange, the background process owns freshness. Feast cannot tell whether the value it read was written a second ago or an hour ago, so every write carries an event timestamp recording when the velocity snapshot was computed. Scoring code and monitoring compare that timestamp against the maximum age the model accepts.

## TTL alignment

Stale velocity features can produce incorrect fraud scores without any pipeline error. Two separate settings limit how old a value can be. They live in different files and do different jobs.

| Setting | Where you set it | What it controls |
| :-- | :-- | :-- |
| `FeatureView.ttl` | The `ttl` argument on the `FeatureView` in `fraud_repo.py` | Materialization lookback and historical point-in-time retrieval. Standard Aerospike online reads do not use it to reject an old stored value. |
| `ttl_seconds` | The `online_store` block in `feature_store.yaml` | How long Aerospike keeps a record before expiring it. Aerospike applies it to the whole record on every Feast write. |

In this tutorial, `ttl_seconds` is ten minutes for a five-minute rolling window. The extra five minutes accommodates the interval between velocity snapshots. Choose the online-store TTL from your aggregation cadence and the maximum age your model accepts. For how expiration works in Aerospike, see [Expiration (time to live)](https://aerospike.com/docs/database/learn/policies#expiration-time-to-live).

## Collocation on push

Push feature views use the same record layout as materialized ones. Feature views that share an entity and resolve to the same namespace colocate on one Aerospike record, and each `store.push()` updates only the map entries belonging to the feature view it targets. For the layout itself, see [Namespace overrides and collocation](https://aerospike.com/docs/develop/feast-aerospike-online-store/step/2/part/0/entity-record-layout#namespace-overrides-and-collocation) and [How materialization writes work](https://aerospike.com/docs/develop/feast-aerospike-online-store/step/2/part/0/entity-record-layout#how-materialization-writes-work) in [Tutorial: Serve real-time Feast features with Aerospike](https://aerospike.com/docs/develop/feast-aerospike-online-store).

What collocation changes for push is expiry: views on one record share a single record-level TTL, so writing any one of them refreshes the expiry for all of them. The presence of a record therefore does not prove that every view stored on it is current.

## Production streaming pattern

The manual push in this tutorial verifies the data contract: define, push, read back. It does not verify event consumption, rolling-window state, retries, or recovery after the aggregator falls behind. Those are responsibilities of the production stream job.

A Kafka consumer, Apache Flink job, or Spark Structured Streaming job can maintain per-account rolling windows and call `store.push()` on a flush interval for accounts that received new transactions.

Because neither Feast nor Aerospike can detect that an aggregator has stalled, production deployments monitor each feature view’s event timestamp rather than relying on record presence. A stalled aggregator keeps serving its last written value until the record expires, and a colocated view refreshed by another push extends even that deadline.

On the next page, you define fraud velocity features and push a velocity snapshot.

::: undefined
-   I understand why `get_online_features` reads pre-computed push values and who keeps them fresh.
-   I understand how event timestamps and Aerospike record TTL help manage old velocity values.
:::

[Previous  
Install and connect](https://aerospike.com/docs/develop/feast-aerospike-fraud-velocity/step/1/part/1/install-and-connect) [Next  
Define features and push velocity data](https://aerospike.com/docs/develop/feast-aerospike-fraud-velocity/step/3/part/0/define-and-push)