Real-time search personalization

Rank on the last three searches, not the last three months.

Signals computes what this visitor has been searching, viewing and skipping, and serves it to your ranker in 6ms, inside the budget the query already has.

  • 6ms p50 read, in-region
  • <1s event to attribute current
  • Free tier, no card
Try it on yourself

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.

this page · events0 writes
nothing sent yet
write
attribute store · your sessionno 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.
Why the second search is no better

Your ranker sees the words they typed. Not the two searches before it.

Before

The query string and a nightly profile

Two failed searches a minute ago, the category they keep circling, the result they opened and bounced straight back from. None of it reaches the ranker in time to matter.

q = waterproof jacket
With Signals

Session context at query time

One call returns what this visitor has been doing in the last few minutes, current to the event, fast enough to sit inside a query that already has a latency budget.

failed_searches_session = 2
Result

The second search is better than the first

The ranker boosts the category they have been circling and demotes what they already rejected, while they are still typing.

same session, better results
What the ranker can do with it

Signals that only exist while the visitor is still searching.

A search session is short. Anything computed overnight arrives after the visitor has either found it or left.

Recover a failed search before they leave

Two queries with no results is the clearest intent signal you get, and it is worthless tomorrow. Rank the third query differently, or swap the zero-result page for something they might actually want.

null result rate · search exit rate

Rank on what they skipped

The results they scrolled past say as much as the ones they opened. Both are in the stream already, and neither survives a nightly aggregate.

search click-through · position of first click

Give an anonymous visitor a profile

Most searchers are not logged in. Keying on the session rather than the person means the ranker has context from the second query onward, with no identity to resolve first.

coverage of ranked sessions

One context for search, browse and the recommender

The same definitions feed the search ranker, the category pages and whatever recommends alongside them, so the three surfaces stop disagreeing about what the visitor wants.

surfaces per definition
How it works

One call, inside the query you already run.

Signals does the knowing. Your search engine keeps doing the ranking, with inputs that are seconds old instead of a day old.

  1. 01Collect. Add a Snowplow SDK to your application and search, view and click events start flowing in.
  2. 02Define. Say what the ranker should know about the session, in the console or in code.
  3. 03Serve. An event updates its attributes in <1s, and your ranker reads them at 6ms p50, on the way to the query.
Signals → your app6ms p50
failed_searches_session2
query_refinements4
categories_viewed_10m3
results_clicked_session0
seconds_since_last_query12
Trigger search_abandonmentdelivered to your app
Questions

Before you sign up

Does this replace my search engine?

No. Signals does the knowing. Elasticsearch, OpenSearch, Vespa, Algolia or the ranker you wrote yourself keeps doing the ranking, with inputs that are seconds old instead of a day old.

Will it fit inside my query budget?

6ms p50 and 10ms p95 for an in-region round trip, and one call returns a whole service rather than one attribute at a time. Whether that fits is your call, but it is a number with a boundary on it rather than a claim.

What about visitors who are not logged in?

Attributes can be keyed on the session rather than the person, so an anonymous searcher has context from their second query onward. Pair it with identity resolution later if you want the history to follow them.

Do I need an event stream already?

No. Collection is part of Signals. 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.

Search your own site and watch the context change.

Add the SDK, define one attribute, then run two searches on your own product and watch the second one arrive with the first one attached.

The real engine · no card · no sales call
Or hand it to your coding agent
npx plugins add snowplow/skills
Then: Let's add Snowplow Signals to this app. Understand the search flow first, then define an attribute for failed searches this session and read it back before the query runs.
Signals, about you
connecting...