---
title: "A feature store that brings its own events | Snowplow Signals"
description: "A feature store expects a clean stream. Signals brings the collection and the streaming engine with it, and computes in the serving layer itself."
source: https://signals.snowplow.io/lp/real-time-feature-store
---

Real-time feature store

# A feature store expects a stream. Signals brings one. 

Signals brings the collection and the streaming engine with it, and computes the feature where it serves it, so a value is current <1s after the event and readable in 6ms.

* **6ms** p50 read, in-region
* **<1s** event to feature current
* **Free** tier, no card

## Start free

5M events a month · unlimited attributes · no card 

Work email Continue

A work address, please. We cannot provision on a personal domain.

Or [talk to an engineer](https://signals.snowplow.io/start?intent=engineer&lp=real-time-feature-store).

[ Try it on yourself ↓ ](#live-panel) 

Below is your own visit to this page, computed by Signals as you read.

### Signals, about you 

connecting 

See live events firing as you browse this page on the left; what Signals computed about you on the right, refreshed every few seconds.

Implement this

this page · events 0 writes 

Product Solutions Developers Pricing Start free 

Start free Engineer 

this panel

the rest of the page

nothing sent yet

write 

attribute store · your session no read yet 

reading\_now 

pages\_last\_5\_min 

seconds\_since\_last\_action 

sections\_read 

seconds\_engaged 

pricing\_views 

menus\_explored 

features\_wanted 

cta\_clicks 

arrived\_from 

waiting for the first computed value… 

Your first events are in flight through a real Snowplow pipeline. Attributes appear as the stream computes them, usually within a few seconds.

hand it to your agent one prompt 

Add the Signals MCP server to Claude Code, Cursor or any MCP client, then run this. The agent adds the SDK, defines the attribute and wires the read into your own app.

$ npx plugins add snowplow/skills

> Use the Snowplow MCP server and Signals skill, then help me plan and implement a use case. Make sure everything is tested and works as intended.

Copy the prompt[How to connect the MCP server](https://docs.snowplow.io/docs/llms-support/snowplow-mcp/) 

or 

write it yourself three steps 

01 Track the event once, in your app 

trackPageView(); // browser tracker, already on this page

02 Define the attribute once, in Signals 

Attribute(name="pages_last_5_min", events=["page_view"],
  aggregation="category_count", property="page_urlpath",
  period=timedelta(minutes=5))

03 Read it back every request 

await signals.getServiceAttributes({
  name: "signals_site_session_service",
  attribute_key: "domain_sessionid",
  identifier: "…", // your session id, once set
});

Where it stalls

## The store was never the hard part. The stream feeding it was. 

Before 

### A store waiting on a pipeline

The online store is provisioned and empty. Two quarters later the project is still upstream, building collection, schemas and the streaming jobs that were supposed to fill it.

`features_served = 0` 

With Signals 

### Collection and computation in one product

An SDK in your application, and one definition that computes inside the serving layer: a streaming engine for now, a batch engine for warehouse history. No job of yours in between.

`sessions_since_purchase = 3` 

Result 

### Production reads what training saw

The same definition serves the request path and builds the point-in-time correct training set, so the lift you measured offline is the lift you get online.

`one definition, both paths` 

Why it matters

## What changes when the events and the serving layer are the same product. 

An online store is only as current as the pipeline somebody keeps running into it. Here the compute is the serving layer, so a feature is current <1s after the event that moved it.

### Train on history you have not computed yet

Attributes are computed on demand from the events you already collected, so a feature defined this morning can train on your whole history this afternoon rather than waiting for a backfill to accumulate.

`time to first feature` 

### No train and serve skew to chase

One definition feeds both paths, which removes the quarter usually spent tracing why the online numbers disagree with the notebook.

`offline-to-online lift gap` 

### Key on things that are not users

Baskets, listings, stores, sessions, accounts. The entity does not have to exist in modeled warehouse data before you can aggregate over it.

`entities per model` 

### Application engineers read it too

One call returns a whole service inside a render budget, so the storefront and the service desk read the same values the model server does.

`consumers per definition` 

How it works

## One definition. Live and against history. 

The streaming engine keeps the value current, the batch engine fills it from warehouse history, and both come from the definition you wrote once.

1. 01 **Collect.** Add a Snowplow SDK to your application and behavioral events start flowing in. No stream to stand up first.
2. 02 **Define.** Say what you want to know about the customer, in the console or in code, versioned through CI/CD.
3. 03 **Serve.** The streaming engine keeps the value current within <1s of the event. Your model server and your application read it at 6ms p50.

Signals → your app 6ms p50 

sessions\_last\_7d 4 

categories\_viewed\_10m 3 

seconds\_since\_last\_event 12 

failed\_searches\_session 2 

basket\_value 184.00 

Trigger churn\_risk\_high delivered to your model server 

Questions

## Before you sign up

### Is this a feature store?

It overlaps on serving and on definition parity. It differs in bringing the collection and the compute with it, rather than assuming a stream and a job you already run, and in being aimed at application engineers as much as at ML teams. We file it as real-time customer context, because what it serves is behavior rather than any feature you care to define.

### Can we keep the feature store we already run?

Yes. The common pattern is Signals for the application path and the existing store for model training and serving. Or build the training set with Signals from behavior and keep the store for everything else.

### What about point-in-time correctness?

The dataset builder computes each attribute from only the events before the moment you are predicting from, with the same definitions the live surface reads. Nothing that happened afterwards can leak into training.

### Do I need an event stream already?

No. Collection is part of Signals, and it is usually the half of a feature store project that takes the longest. Add a Snowplow SDK to your web, mobile or server application and events start flowing in. If you already run Snowplow, Signals reads the pipeline you have.

### What does the free tier include?

The full product against your own traffic, up to 5 million events a month, with no card and no sales call. You should see an attribute updating against your own traffic in the first session.

## Define one feature and read it from your own traffic today.

Add the SDK, write one definition, then click around your own product and watch the value move, the same way the panel at the top of this page moved for you.

[Start free](https://signals.snowplow.io/start?lp=real-time-feature-store) [Talk to an engineer](https://signals.snowplow.io/start?intent=engineer&lp=real-time-feature-store) 

The real engine · no card · no sales call 

Or hand it to your coding agent 

$ `npx plugins add snowplow/skills` Copy Copied 

Then: Let's add Snowplow Signals to this app. Understand the app first, then define a behavioral feature for session engagement and read it back before the model scores.
