Solutions/Use case

Serve the features you trained on.

A model trained on the notebook's version of a feature and served a production rewrite drifts without anyone noticing. Signals builds the training set and serves the live value from one definition, so what the model learned from is what it reads at inference.

The real engine · no card · no sales call
One Signals definition, card_attempts_session, branches into a point-in-time training set of past values and outcome labels and a live value of 4 for this session, and both feed the same fraud model.
One definition. training and serving read the same thing
Try it on yourself

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

Signals, about you

connecting
What Signals knows about your visit, right now

Signals is computing your first attributes from the events this page just sent.

Every highlighted part is an attribute Signals computed from the behavioral data your browser sent during this visit. Open the Product menu above and watch the sentence change.

Keyed on an anonymous session id. Signals drops these values a day after your last event.
Why it usually fails

Notebook features stall on the way to production.

Someone rewrites the feature for serving, the two drift apart, and the model degrades without anyone noticing.

Two versions of every featureThe notebook says one thing. Production says another.
Training data that peeks aheadComputed over the whole session, it leaks the outcome.
A ticket per featureEach new one waits in the data engineering queue.
What you build with it

Models that score this session, on the features they learned from.

Each of these needs the feature current to the last event at inference, and the same feature as it stood at each past moment for training.

Propensity

Higher model lift

The score runs on features from before the session. Signals serves the same features current to the last event, so the score can still change the outcome.

Ranking

Offline gains that hold online

The ranker trains on features production cannot reproduce. Signals builds both from one definition, so what you measured offline is what you get live.

Fraud and abuse

Lower losses before payout

Abuse is caught in the next review, after the money has moved. Signals serves this session's behavior to your model at request time, so it scores before the payout.

What you build

Define once. Train on history, serve on the stream.

01 · Collect

Add a Snowplow SDK

Web, mobile or server. Events arrive validated against your schemas, so every feature reads clean, typed properties.

02 · Define

Write the feature as an attribute

Signals calls each feature an attribute. Counts, recency and order over your events, keyed on user, session or listing.

03 · Train

Build the training set from the same definition

Name the outcome. The dataset builder labels your history and computes each attribute as it stood at that moment, into a table in Snowflake.

04 · Serve

Read it at inference from the streaming engine

One call returns every feature in the service, in 6ms p50, in-region.

One session_features attribute group, holding failed_searches_session, feeds both a point-in-time training set in Snowflake built by the dataset builder, with each row's value as of that moment and its outcome label, and the live value read from the ranker_features service with get_service_attributes and passed to model.predict.
Works with
  • Snowflake
  • Databricks
  • BigQuery
  • Vertex AI
  • Amazon Bedrock
The code

The same attribute group, in the training set and at inference.

The Python SDK builds a point-in-time correct training set from your attribute groups, then reads the live values from the service that holds those same groups.

First, give your agent the Signals skills
npx plugins add snowplow/skills
Write it yourself
from datetime import datetime, timezone
from snowplow_signals import AtomicProperty, Criteria, Criterion, Signals, TrainingSpan

sp_signals = Signals(api_url=api_url, api_key=api_key, api_key_id=api_key_id, org_id=org_id)

# Training: one row per labeled moment, features from only the events before it.
run = sp_signals.submit_dataset_run_with_session_anchors(
    attribute_groups=[session_features],
    goal_criteria=Criteria(all=[
        Criterion.eq(AtomicProperty(name="event"), "transaction"),
    ]),
    training_span=TrainingSpan(
        start_time=datetime(2026, 1, 1, tzinfo=timezone.utc),
        end_time=datetime(2026, 4, 1, tzinfo=timezone.utc),
    ),
)

# Inference: the same features, current to the last event.
features = sp_signals.get_service_attributes(
    name="ranker_features",
    attribute_key="domain_sessionid",
    identifier=session_id,
)
score = model.predict(features)
Or hand your agent this prompt
Add Snowplow Signals to this model's pipeline so training and serving use one feature definition. Rewrite the session features from our notebook as a Signals attribute group, build the training set with submit_dataset_run_with_session_anchors using our conversion event as the goal, and replace the serving path's feature code with get_service_attributes. Keep the model and its hyperparameters as they are, so the only thing that changes is where the features come from.

The dataset builder supports Snowflake today. You can run a managed build, or generate the SQL and run it yourself.

What changes

The model sees what it was trained on.

1 definition

Shared by the training set and live serving

0 copies

Second implementation of a feature for your team to maintain

6ms

Added at inference, p50 in-region

Questions

Before you move a feature over

Is this a feature store?

It does the serving half of one for behavioral features, and it builds the training set from the same definitions. It starts from the events, so it collects them too. If your features come from other sources, a general feature store may suit you better.

Do I have to replace the feature store I run?

No. A common pattern is Signals for behavioral features on the request path and your existing store for everything else.

How does it stop training data leaking the outcome?

The dataset builder computes each attribute from only the events before the moment you are predicting from, using the same definitions the live path reads. Nothing that happened afterwards reaches the training row.

Which warehouses does the dataset builder support?

Snowflake today. Attribute backfill, which fills history into the live store, also runs from BigQuery and Databricks.

Do I need an event stream already?

No. Collection is part of Signals. Add a Snowplow SDK and events start flowing. If you already run Snowplow, Signals reads the pipeline you have.

Where does it run?

Managed SaaS, or a private deployment in your own AWS or GCP account. Same architecture either way.

Move one feature out of the notebook.

Define one feature as an attribute, build a training set from it, then read the same value live for your own sessions. The free tier runs on the real engine: no card, no sales call.