Size the cohort before designing for it
Work out how many users are in this state and how long they stay there, because the answer determines whether this is a fallback or a product surface.
Say you add 20,000 users a day and your collaborative model needs roughly ten interactions before its output beats a popularity list. Say the median new user reaches ten interactions across five sessions spread over about two weeks. Then the number of users sitting in the cold band at any moment is roughly two weeks of signups, around 280,000 people.
Now weigh that against when the retention decision happens. For most consumer products a large share of new users decide whether to come back during the first session, before they have generated any of the interactions your model wants. So the cold cohort is small as a share of your traffic and large as a share of your growth, and it is being served by whatever your code does in the else branch.
That is the argument for treating it as a deliberate serving path with its own model, its own metrics and its own owner, rather than as a fallback somebody wrote in an afternoon. Making that argument with the numbers attached is most of what an interviewer is looking for here.
A new user is not a user with no data
The framing error is treating cold start as an absence of information. You have plenty. What you lack is behavioural history, which is a much narrower claim.
At the moment of the first request you typically know the country and city from the address, the device and platform, the referring source or campaign, the entry page, the time of day and day of week, and the language the client asked for. Every one of those is predictive, and using them turns a global popularity list into a conditioned one.
The difference is not marginal. A user arriving from a running-shoe advertisement and a user arriving from a cooking blog share no history and should not see the same first screen, and you knew which was which before the page rendered. A global top-20 list serves both the same thing. It also wastes the strongest signal you will ever have about a stranger: what they were looking at immediately beforehand.
So the first tier is popularity, conditioned. Popularity within country, within device class, within referrer bucket, within time-of-day, with a fallback up the hierarchy when a cell is too sparse to be reliable. This is cheap to compute in batch and cheap to serve. Plenty of personalised models struggle to beat it on this cohort.
The session is the highest-leverage signal you have
Then use what the user does in the next thirty seconds. This is the part most often left out.
Two clicks are enough to re-rank a page. A model that predicts the next item given the sequence of items in this session requires no user identity, no stored profile and no history - which is exactly the property that makes it right for a cold user. The input is the sequence, the output is a ranking, and it works identically for a first-time visitor and for a logged-out one.
That is usually a second model, trained on sequences rather than on user-item pairs, and it gets skipped for organisational reasons rather than technical ones. It does not fit the pipeline the main recommender lives in. Naming it is the most useful thing you can say here, because it turns "we have no data" into "we have data that is three interactions old".
Choose an architecture that degrades rather than fails
Why a cold user breaks some recommenders and not others is structural, and stating it precisely separates an engineer from a user of libraries.
Matrix factorisation learns an embedding per user identifier. A new user has no row in that matrix, so the model has nothing to look up and cannot produce a score at all. The failure is total. It is also a property of the parameterisation rather than of the training data.
A two-tower retrieval model can be built so that this does not arise. The item tower is fed item content - text, category, attributes, images - so an item's representation is computed rather than looked up. The user tower is fed context features and in-session behaviour rather than a learned per-user vector. Now a request from an unknown user still produces a vector, because every input to the tower is present at request time. The recommendations are less sharp than for a user with history. They exist, which is the point.
The principle worth extracting: prefer features computed from what you observe over parameters indexed by identity. An identity-indexed parameter has no value for a new entity, and every cold-start problem reduces to that.
Exploration, or the first guess becomes permanent
A ranker that only exploits keeps a cold user inside whatever bucket the first guess put them in. It shows them what it believes they want, they interact with what is shown, and that interaction confirms the belief. The loop closes in one session and the user's profile is now an artefact of your initial ordering.
So reserve some slots for exploration, and prefer a bandit over a fixed percentage, because the amount of exploration you want is a function of how uncertain you are and should therefore fall as the user's history accumulates. That gives you the right behaviour without a hand-tuned constant: heavy exploration on the first screen, negligible after twenty interactions.
Item cold start deserves separating out, because it is the harsher version of the same problem. A new item has no interactions, so a behaviour-based model will not rank it, so it receives no impressions, so it acquires no interactions. Waiting does not fix it. Breaking that loop requires either content features that let a new item be scored on its attributes from the first minute, or a guaranteed impression allocation for new items, which is a deliberate cost paid out of short-term engagement to keep the catalogue alive.
Serve it as one path with a measured switch
Build one service that routes, not two products. The router decides, per request, how much signal exists: no identity at all, an identity with fewer than N interactions, or a full profile.
The interesting question is where N sits, and it has to be measured rather than assumed. Bucket your users by history length, evaluate both models within each bucket, and find the crossover where the personalised model overtakes the conditioned-popularity model. In practice that point is often lower than people expect, and it is not one number for ever - it moves when either model changes, so it belongs in a config rather than in a conditional.
Onboarding questions are the last resort. Three are acceptable if the answers visibly change the next screen, because the user sees a return on the effort. Twelve is a funnel with a drop-off you will not recover. And design for the skip: a meaningful share of users will decline, and they must land on the conditioned path rather than on something empty.
Your headline metric cannot see this problem
Here is the failure mode that keeps this bug alive for years, and it is a measurement one rather than a modelling one.
Offline evaluation uses held-out interactions. Users with no interactions generate no held-out interactions, so they contribute nothing to your test set. Your offline metric is therefore computed almost entirely on users with history - the users who are not the problem - and it will improve steadily while the cold experience stays useless. Nobody is lying and the number is not wrong. It answers a different question from the one you asked.
The fix is to segment every metric by history length and to publish the buckets rather than the average. Once the cold bucket has its own number on the same dashboard, the problem becomes visible, attributable and improvable. Until then you cannot tell whether any of the work above helped. Unmeasurable work does not get funded twice.
Online, the metric that matters for this cohort is not click-through on the first screen. It is whether they come back, so first-session engagement is a proxy and second-session return is the target. Optimising the proxy alone produces a first screen that is enticing and unrepresentative, and that trades retention for a metric.
A new user has no history and plenty of context, so serve popularity conditioned on what you know and re-rank on the first clicks of the session. And segment your offline metrics by history length, because an average over users with history is structurally blind to the users who have none.
© 2026 Preptima. Originally published at preptima.com (opens in a new tab).