RecomNext

Inferred interests

Preferences vs inferred chips, Admin Users filters, and plain-language examples.

11 - Inferred interests

Audience: PMs and growth using Admin → Users.
Examples: live tenant driffle-dev, scored with now = 2026-08-09 00:00 UTC.
Related: Glossary · Events & analytics · Worked examples · Playbook

Deep engineering (APIs, CronJob, code paths) lives in the engine docs. This guide explains what the chips mean, how strength is calculated, and how to read real users.


Why this exists

Personalization today mostly uses raw interaction history at recommend time. Inferred interests are a simpler, human-readable layer:

  • “This shopper currently leans game and giftcard.”
  • Visible in Admin next to declared Preferences.
  • Refreshed on a schedule (or via Run Inference), so CRM / growth can inspect cohorts without writing ClickHouse.

v1 scope: Admin display + ops. Ranking does not consume these chips yet.


Preferences vs inferred interests

Column in AdminMeaningSource
PreferencesWhat the site told us the user likesClient / SDK upsert (onboarding, account settings)
Inferred interestsWhat behavior suggests right nowNightly / manual job from last 30 days of interactions
  • Inference never overwrites preferences.
  • Many catalog users are stubs created from events — preferences empty, inferred chips may still fill in.
  • Use the InfoTips on the Users table headers if the two columns feel ambiguous.

What you’ll see in Admin

  1. Users → column Inferred interests (up to five category chips).
  2. Open a user → same chips + last refresh time.
  3. Run Inference → start a full refresh (button disables while a run is active).
  4. Inference runs → status, progress (% / users updated / tenants), history.

Blank inferred cell usually means one of:

  • No known-user activity in 30 days (or only anonymous sess_… traffic).
  • Activity exists, but every category scored below 2.0 (too weak or too old) — we do not write an empty list.
  • Catalog items missing a category (those events contribute nothing).

How strength is calculated (PM-readable)

Each interaction adds points to that item’s category:

points = event weight × type importance × recency fade

Type importance

Event typeMultiplierIntuition
purchase4Strongest intent
rating3Explicit taste
cart2Serious consideration
view (and other)1Browse / weak signal

Event weight is almost always 1 in driffle-dev.

Recency fade (7-day half-life)

Interest halves every 7 days of age:

Age of eventFade factorPlain English
0 days (today)1.00Full credit
~1 day~0.91Almost full
7 days0.50Half credit
14 days0.25Quarter credit
~28–30 days~0.05–0.06Nearly gone

Formula: fade = 0.5 ^ (age_days / 7).

What we keep

  1. Sum points per category (join each item → its catalog category).
  2. Drop categories with total < 2.0.
  3. Keep at most the top 5 remaining labels.
  4. Only known users (real ids, not sess_…) with ≥1 event in 30 days.
  5. If nothing clears 2.0 → leave the user unchanged (no empty stamp).

Filtering Users by activity (separate from chips)

On Users, Activity finds funnel cohorts in the last 30 days (current tenant):

FilterWho shows up
Purchases in last 30 days≥1 purchase
Cart but no purchase (30d)≥1 cart, 0 purchases
More than 3 views (30d)Strict view count > 3

Use filters to find people; use inferred chips to see which categories they lean toward.


Worked examples (driffle-dev)

All math below uses live ClickHouse events + Mongo item categories, with now = 2026-08-09 00:00 UTC.

Example A — User 4189506: three categories (step-by-step)

Recent (~1 day old) funnel on three SKUs. Fade at ~1.05 days ≈ 0.901.

Category game (item 9880032)

Events (weight 1)CalculationPoints
1× purchase1 × 4 × 0.9013.61
3× cart3 × (2 × 0.901)5.41
6× view6 × (1 × 0.901)5.41
Category total≈ 14.42

Category gift (item 9929073)

EventsCalculationPoints
1× purchase4 × 0.9013.61
3× cart3 × 2 × 0.9015.41
4× view4 × 0.9013.60
Category total≈ 12.62

Category giftcard (item 9972554) — just clears the bar

EventsCalculationPoints
1× cart2 × 0.9011.80
2× view2 × 0.9011.80
Category total≈ 3.60

Decision

CategoryScore≥ 2.0?Kept?
game14.42yesyes (#1)
gift12.62yesyes (#2)
giftcard3.60yesyes (#3)

Inferred interests: ["game", "gift", "giftcard"].

Growth read: multi-vertical shopper with fresh funnel activity — not a single-category buyer.


Example B — User 2139520: one dominant category

Almost all recent events are on gift-card SKUs (e.g. 9885466): 3 purchases + 22 carts + 44 views in the window.
Largest single contributions (age ≈ 1.17d, fade ≈ 0.89):

EventCalculationPoints (each)
purchase4 × 0.89≈ 3.56
cart2 × 0.89≈ 1.78
view1 × 0.89≈ 0.89

Summed across the giftcard category → ≈ 81.0. No other category clears 2.0.

Inferred interests: ["giftcard"].

Growth read: concentrated affinity; messaging around gift cards is safer than assuming “games” taste.


Example C — User 694956: two strong categories

CategoryRough makeup (30d)Total scoreKept?
game14 purchases + 8 carts + 16 views (mostly <1 day old)≈ 83.5yes
giftcard1 purchase + 3 carts + 5 views (~1.2 days old)≈ 12.8yes

Illustrative giftcard slice (item 9893126, fade ≈ 0.887):

EventCalculationPoints
1× purchase4 × 0.8873.55
3× cart3 × 2 × 0.8875.32
5× view5 × 0.8874.44
Subtotal≈ 13.3 (whole-user giftcard ≈ 12.8 after exact ages)

Inferred interests: ["game", "giftcard"].


Example D — User alice: history exists, chips stay empty

Events are mostly 24–30 days old. Fade at 29.5 days:

0.5 ^ (29.5 / 7) ≈ 0.054

So a purchase that would be worth 4 today is only worth:

4 × 0.054 ≈ 0.22
CategoryApprox. total≥ 2.0?
game≈ 1.47no
game point≈ 1.42no
account≈ 0.75no
dlc / gift / giftcard< 0.4 eachno

Result: candidate for the job (has 30d events), but no write — Admin shows blank inferred interests until fresher activity lifts a category over 2.0.

Growth read: “Interacted in the last month” ≠ “currently interested.” Recency matters as much as volume.


Mini checklist when a user looks “wrong”

  1. Are they a known id (not sess_…)?
  2. Any events in the last 30 days?
  3. Do touched items have a category in catalog?
  4. Is most activity older than ~2 weeks (fade crushing the score)?
  5. Did the last Inference run succeed?

What this is not (v1)

ExpectationReality
Drives recommend / search rankingNot yet
Replaces preferencesNo — parallel fields
Every active user gets chipsNo — below-threshold stays blank
Auto-expires chips for dormant usersNot yet

Handy questions for engineering

  • When did the last inference run finish?
  • For user X: inactive window, anonymous id, missing categories, or below 2.0?
  • Should activity filters be stamped onto users for faster lists? (issue #187)