ML Systems Lab Open interactive version →
Advanced 22 min read two-towerembeddingsANNretrieval

Two-Tower Models

Encode separately, compare cheaply — the retrieval workhorse

The most accurate way to score a user against an item is to feed them into one model together so it can weigh every interaction. The problem is arithmetic: that means scoring *every* user against *every* item at query time. For 10M items at 1000 users/second, that's 10 billion joint forward passes per second — an overnight warehouse job, not real-time retrieval.


The two-tower trick: encode separately, compare with a dot product. A user tower and an item tower map into the same embedding space; similarity is a plain dot product. Because an item's embedding no longer depends on who's asking, you compute *all* item embeddings offline, once, and index them for approximate-nearest-neighbor (ANN) search. At query time you encode just the one user and look up neighbors — ~10ms across 100M items. Retrieval quality itself is measured as recall@K: the fraction of truly relevant items that land inside the top K candidates the tower hands to the ranker. A tower with recall@100 of 60% is failing to surface 40% of the relevant items before the ranker ever sees them — no ranker can recover items retrieval never returned.


What you give up, and who picks it up. Encoding the two sides apart means the model can't capture fine user×item feature interactions — exactly what the expensive joint model was good at. That job is handed downstream to the cross-attention *ranker*, which only has to look at the few hundred candidates retrieval already narrowed. Two-tower for recall, cross-encoder for precision: the same recall-then-precision split as the whole funnel, in miniature.

Key points

Takeaway

Two-tower breaks the user×item coupling so item embeddings can be precomputed and ANN-indexed — buying ~10ms retrieval over 100M items at the cost of fine feature interactions, which the downstream cross-encoder ranker restores over the few hundred survivors.

Recap

Check your understanding

Q1. Why does a cross-attention model that jointly encodes user and item fail at retrieval scale even though it's more accurate?

Q2. A two-tower model's recall@100 — the fraction of truly relevant items that make it into its top-100 candidates — is stuck at 60%. Which single change most directly attacks that low recall?

Q3. Your item catalog updates prices every few minutes, but the ANN index is rebuilt nightly. What's the failure mode and the right fix?

Try it interactively

ML Systems Lab is a free interview-prep platform for ML engineers — work through the full interactive module, quizzes, and drills.

Open ML Systems Lab →