Recommender systems
Session-Based Recommendation
Build session-based recommenders from recent events, session boundaries, anonymous traffic, and rapidly changing intent.
By the end you can
- Explain session-based recommendation and the role of session boundaries
- Distinguish session-only, profile-only, and gated combination strategies
- Identify task transition, sequence shortcut, and reset failures
- Design chronological evaluation for sparse and conflicting sessions
Example
A shared account, and the 19% who got nothing relevant
One account can carry two purposes, and the recommender sees only one of them. Verstrepen and Goethals measured what that costs. In 2015 they formalised three shared-account failures — the dominance problem, the generality problem and the presentation problem — and stated the first in one sentence: “Now, it is likely that all recommendations will be based on the numerous household items and the recommender system will be essentially useless for the children.”
Dominance is not a rhetorical worry. They put a number on it. On the Yahoo!Music data, up to 19% of users received no relevant recommendation at all once their account was shared with one other person. In one configuration — two users, k=200 — their DAMIB-COVER method cut that fraction from 12% to 3%. The durable profile is not wrong about the account. It is describing a purpose the person at the keyboard does not have right now. The only evidence that the purpose has changed is sitting in the current session.
- Temporary task: The events of the last few minutes express a narrow, urgent need the account's history has never expressed.
- Profile conflict: This is the dominance problem Verstrepen and Goethals measured — up to 19% of users on the Yahoo!Music data received no relevant recommendation once the account was shared with one other person.
- Session boundary: A long gap plus a new query is what marks the new task. How long counts as long is a configured threshold, not a fact recorded in the log.
- Sparse sequence: Only a handful of events precede the decision. The RSC15 test set GRU4Rec was scored on held 15,324 sessions and 71,222 events.
- State decay: Influence has to fall away as the task moves on, and stop entirely when the task ends. The reference implementation does not decay its state at that point. It zeroes it.
Session models prioritize the local sequence of intent
A model can work from nothing but the recent actions inside a bounded interaction episode, often without a stable user ID. That absence is the condition the method was built for. Hidasi and colleagues published GRU4Rec in 2015. It was trained on roughly six months of RecSys Challenge 2015 data: 7,966,257 sessions, 31,637,239 clicks and 37,483 items. The unit counted there is the session, not the person.
Markov chains, co-occurrence, nearest sessions, recurrent models and attention models can all estimate likely next items or task-compatible candidates. But cutting the stream into sessions is itself a modeling decision. A time gap, a device change, a shift in the query, a checkout event, an explicit task boundary — each splits or merges episodes differently. Whichever one a team picks decides what the model ever sees as a session.
Settle the session boundary before choosing the model, because that rule decides what counts as intent and what the model never sees at all.
Case
GRU4Rec, and the neighbour schemes that were usually the winner
Session models were proposed for a specific absence: sites where long user histories simply do not exist. Recurrent models for those short episodes arrived in 2015, from Hidasi and colleagues, with a clear win over the obvious simple baseline. The item-KNN nearest-neighbour baseline scored Recall@20 0.5065 on RSC15. The best GRU variant reached 0.6322, a reported +24.82%. The framing has held for a decade: work presented at AAAI in 2021 still defines the task as predicting the next item without complete user profiles.
Then the comparison was widened, and the ordering changed. In 2018 Ludewig and Jannach ran GRU4Rec and factorized Markov models against session-based nearest-neighbour schemes across seven-plus datasets. Their summary: “For each of the datasets, one of the proposed neighborhood-based methods was usually the winner in terms of the hit rate and the MRR (except for RSC15(-S) and the MRR on ZALANDO).” On TMALL, sknn reached Recall@20 0.312 against gru4rec's 0.233. On ROCKET, sknn reached 0.478 against gru4rec's 0.400.
The same paper is where the session stops looking like something the data hands you. RSC15 and ZALANDO shipped with session IDs. RETAILR, NOWPLAYING, 30MUSIC and CLEF were cut at 30 minutes of idle time. TMALL was cut at one calendar day, because its timestamps were day-granular. Playlists were treated as whole sessions. Every Recall@20 above was computed over episodes somebody defined.
The pattern is not confined to session data. In 2019 Ferrari Dacrema and colleagues took 18 neural top-n recommendation algorithms published at top-tier venues and tried to reproduce them: “Only 7 of them could be reproduced with reasonable effort. For these methods, it however turned out that 6 of them can often be outperformed with comparably simple heuristic methods, e.g., based on nearest-neighbor or graph-based techniques.” The single survivor still failed to consistently beat a well-tuned non-neural linear ranking method. The neighbour scheme is the baseline a session model has to beat, not a legacy step to skip.
Example
Session-model failures
Boundary error and no state reset are the same question asked at the start and at the end. Where does this session begin, and what is allowed to survive when the task it served is finished?
- Boundary error: Unrelated tasks get merged, or one task gets split. Ludewig and Jannach cut some datasets at 30 minutes of idle time and TMALL at one calendar day, inside the same study.
- First-event overreaction: A noisy click defines the entire session, on a task where the whole sequence may be a few events long.
- Profile suppression: Useful durable constraints such as language or budget are discarded. Dominance is only one of the three shared-account failures Verstrepen and Goethals formalise; the generality problem and the presentation problem are the others. Throwing the profile away repairs none of them.
- Transition shortcut: The model memorizes page layout or funnel order rather than intent.
- No state reset: A completed task contaminates the next recommendation episode. GRU4Rec's answer was to zero the hidden state at the end of every session, and never split a session across the train/test boundary.
Visual
The session recommendation loop, and the line where GRU4Rec closes it
A session is defined before it is modeled, and whoever draws that boundary is making a product decision: an inactivity gap, a surface change, a task marker. Then the loop runs. Detect or define the session. Encode the recent actions, preserving order, event type, dwell, query and time gaps. Estimate current intent, weighting recent and diagnostic events more strongly. Retrieve and rank with next-item, co-occurrence, content and inventory-aware candidates. Then reset or carry state. The loop closes on that first decision seen from the other side — what survives a checkout, a login, or twenty idle minutes.
That last step is not aspirational, and it is not a matter of decay curves. The GRU4Rec paper states its rule in one line: “The hidden state of the GRU is reset to zero after a session finishes.” The same setup refuses to split sessions across the train/test boundary. The episode is indivisible on both sides of the loop. Nothing carries out of a finished session, and no session is half-learned and half-scored.
- 1
Detect or define a session
Use inactivity, surface transitions, task markers, or explicit boundaries.
- 2
Encode recent actions
Preserve order, event type, dwell, query, and time gaps.
- 3
Estimate current intent
Weight recent and diagnostic events more strongly.
- 4
Retrieve and rank
Use next-item, co-occurrence, content, and inventory-aware candidates.
- 5
Reset or carry state
Decide what survives checkout, inactivity, login, or task completion.
Steps
Design a session-state policy
Session boundaries are decided by the team, not discovered in the log, so the policy names its boundary evidence first. Event weights, time gaps and profile conflict follow. The reset behavior is validated last.
Step one is never a blank page. The analytics stack has already answered it, and the answer is a default. Google's GA4 documentation states: “By default, a session ends or times out after 30 minutes of user inactivity. There is no limit to how long a session can last.” The timeout is adjustable per data stream. Matomo starts a new visit when “A visitor performs an action more than 30 minutes after their last tracked interaction.” Adobe Analytics uses the same figure and fixes it as a ceiling: “Visit timeout for standard report suites cannot exceed 30 minutes, so you can only shorten it.” Three vendors, one number, arrived at independently and hard-coded.
Adobe then says out loud what the number costs: “A visit does not necessarily coincide with a browser session because of the above criteria. One of the most common differences is where a visitor navigates to your site, leaves the tab open for more than 30 minutes, then resumes browsing. While this action is technically part of the same browsing session, Adobe considers this action two separate visits.” The vendor's own documentation concedes that the unit it produces is not the user's session. That is the point. The boundary is a setting with a default. Your team either chooses it or inherits somebody else's choice.
The remaining steps follow from that one. Weight event semantics, separating search, view, add, remove, purchase and hide. Model time gaps, treating rapid sequences and long pauses differently. Test profile conflict: decide when session evidence should override durable history, and which durable constraints survive the override. Validate reset behavior by exercising checkout, task completion, device switch, and anonymous-to-login transitions.
1. Define boundary evidence
Compare inactivity, query, surface, and explicit task markers.
2. Weight event semantics
Separate search, view, add, remove, purchase, and hide actions.
3. Model time gaps
Treat rapid sequences and long pauses differently.
4. Test profile conflict
Evaluate when session evidence should override durable history.
5. Validate reset behavior
Exercise checkout, task completion, device switch, and anonymous-to-login transitions.
Evaluate on genuine future events within sessions
Use chronological next-event splits, not random event partitions. Report performance by session length, first-event state, anonymous status, task change and profile conflict.
The split is not a detail that washes out in the averages. In 2020 Meng and colleagues compared three common splitting strategies over seven state-of-the-art models on two datasets. They found rank swaps in all four dataset/metric scenarios. Scaled up to 230 models generated by hyperparameter variation, Kendall's tau between pairs of splitting strategies ran only from 0.5284 to 0.7630. Their conclusion: “Our results demonstrate that the splitting strategy employed is an important confounding variable that can markedly alter the ranking of state-of-the-art systems, making much of the currently published literature non-comparable, even when the same dataset and metrics are used.” They also name the mechanism: leave-one-last and temporal-user splits leak evidence from future interactions into training.
Offline next-item accuracy should be paired with product outcomes: task completion, reduced reformulation, fewer backtracks, appropriate session termination. The dataset that defined the field explains why. The YOOCHOOSE data behind RecSys Challenge 2015 is six months of European e-commerce activity — 33,040,175 click records and 1,177,769 buy records, forming 9,512,786 unique training sessions, plus a test file of 2,312,432 click sessions. And then: “It should be noted that approximately 95% of the sessions in the training set end without a buying event, a distribution was also maintained in the test set.” The challenge ran from 15 November 2014 to 15 June 2015. It drew 850 teams from 49 countries and 5,437 submissions, and the winning team scored 63,102 against a perfect-solution score of 135,176. Predicting another item is not always better than helping the task end. On the field's founding benchmark, ending without a purchase is what a session normally does.
Random partitions let a model read events it could never have seen, and next-item accuracy alone rewards a system that keeps a finished task open.
Key idea
Sessions are inferred, not stored in the log
A session is an inferred unit of activity, not a natural object stored in the log — and the threshold that produces it has been argued in print. In 2015 Halfaker and colleagues examined inter-activity times across video gaming, search, page views and volunteer contributions. The conventional 30-minute inactivity threshold is not the one the regularity in that data supports: “We describe a methodology for identifying clusters of user activity and argue that regularity with which these activity clusters appear implies a good rule-of-thumb inactivity threshold of about 1 hour.”
So the vendors ship 30 minutes, and a peer-reviewed measurement of the same kind of data argues for about 1 hour. Both are defensible. They carve different episodes out of one stream.
Two teams can read the same log and report different session counts, conversion rates, and model wins, so a session metric quoted without its boundary rule cannot be interpreted at all.
Key idea
The session gate
Use local intent only when the boundary and state-reset policy are explicit enough to avoid carrying one task into another. This lesson has shown what explicit looks like on both halves. On the boundary: a threshold you can name and defend — 30 minutes, because that is the GA4 default and the Adobe ceiling, or about 1 hour, because Halfaker and colleagues measured the inter-activity regularities and argued for it. On the reset: a rule as flat as GRU4Rec's, which zeroes the hidden state after a session finishes and never splits a session across the train/test boundary. Not a decay curve nobody can test at checkout.
The cost of leaving both implicit has been measured on shared accounts. Up to 19% of users in the Yahoo!Music data received no relevant recommendation at all once their account was shared with one other person.
Write the reset policy down as something the system enforces and tests, because the cost of skipping it lands on the user who finished one task and keeps being served it.
Key takeaways
- Users temporarily become someone their long-term profile cannot describe, and the effect has been measured. Verstrepen and Goethals report up to 19% of users in the Yahoo!Music data receiving no relevant recommendation once their account was shared with one other person.
- Session-based recommendation works from recent actions inside a bounded episode, often without a stable user ID. GRU4Rec was trained on roughly six months of RecSys Challenge 2015 data: 7,966,257 sessions, 31,637,239 clicks and 37,483 items.
- A session is an inferred unit of activity, not a natural object stored in the log. The conventional threshold is 30 minutes of inactivity; Halfaker and colleagues measured the inter-activity regularities and argued for about 1 hour.
- Defining the boundary is a configuration choice somebody has already made for you. GA4 defaults to 30 minutes of user inactivity and is adjustable per data stream, Matomo starts a new visit after 30 minutes, and Adobe's standard report suites can shorten that but cannot exceed it.
- Boundary error is a practical risk, not a hypothetical one. Before any model could be scored, Ludewig and Jannach had to cut RETAILR, NOWPLAYING, 30MUSIC and CLEF at 30 minutes of idle time, cut TMALL at one calendar day because its timestamps were day-granular, and treat playlists as whole sessions.
- Checkout, task completion, a device switch, and the move from anonymous to logged-in each have to be tested as session resets. GRU4Rec's stated rule was to reset the hidden state to zero after a session finishes and never split a session across the train/test boundary.