Large-Scale Semantic Search Platform for Food Delivery

uber · E-commerce · 2025 · source Agentic: no · promotional bias: low · source-backed · extracted with prompt 0.5.6 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Food-delivery semantic search and retrieval infrastructure

Uber Eats needed semantic search across stores, dishes, grocery, and retail items because lexical matching could not handle synonyms, typos, shorthand, multilingual queries, or ambiguous terms. The system had to serve a multi-billion document corpus with low latency, fresh data, global vertical coverage, strong recall, model/index version control, validation gates, rollback, and cost discipline.

Constraints:

Architecture

Uber Eats built a two-tower semantic-search platform using Qwen as the embedding backbone, fine-tuned on in-house Uber Eats data. Query embeddings are calculated online, while document embeddings are generated offline at feature granularity, stored in feature-store tables, joined back to billions of candidates, and indexed in Lucene Plus with HNSW graphs. Matryoshka Representation Learning provides multiple embedding dimensions from one model, quantization reduces serving cost, boolean pre-filters shrink candidate sets before ANN search, and a biweekly blue/green column refresh pipeline validates completeness, backward compatibility, correctness, and serving-time model/index compatibility.

Diagram confidence: reconstructed (reconstructed from prose).

flowchart LR
  train["Training infrastructure"] --> model["Two-tower embedding model"]
  train --> registry["Versioned artifact registry"]
  model --> online["Online query embedding service"]
  model --> offline["Offline document embedding service"]
  offline --> store["Feature store"]
  store --> index["Lucene Plus index"]
  online --> ann["ANN retrieval service"]
  index --> ann
  ann --> rankers["Downstream rankers"]
  refresh["Biweekly refresh workflow"] --> registry
  refresh --> offline
  refresh --> index
  refresh --> gates["Validation gates"]
  gates --> rollback["Rollback controller"]
  compat["Serving-time compatibility check"] --> rollback
  online --> compat
  index --> compat
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
Two-tower embedding model Qwen-backed query and document embedding model fine-tuned for Uber Eats semantic search. Online query embedding service, Offline document embedding service, Training infrastructure
Training infrastructure PyTorch, Hugging Face, Ray, DDP, DeepSpeed ZeRO-3, mixed precision, and gradient accumulation used to train the large Qwen-backed model. Two-tower embedding model, Versioned artifact registry
Versioned artifact registry Tracks query model IDs, document model IDs, and shared two-tower embedding IDs for reproducibility and deployment. Training infrastructure, Biweekly refresh workflow, Serving-time compatibility check
Offline document embedding service Embeds store or item features offline, stores vectors by entity ID, and feeds index building. Two-tower embedding model, Feature store, Lucene Plus index
Feature store Stable entity-keyed tables holding document embeddings for retrieval and ranking models. Offline document embedding service, Lucene Plus index
Lucene Plus index HNSW-backed search index with float and quantized vectors plus blue/green embedding columns. Feature store, ANN retrieval service, Validation gates, Serving-time compatibility check
Online query embedding service Computes query embeddings in real time using the active model version. Two-tower embedding model, ANN retrieval service, Serving-time compatibility check
ANN retrieval service Uses lexical fields, boolean pre-filters, HNSW ANN search, and optional micro-reranking to produce candidates. Online query embedding service, Lucene Plus index, Downstream rankers
Downstream rankers Ranking systems that consume the semantic retrieval cohort after ANN and optional micro-reranking. ANN retrieval service
Biweekly refresh workflow Scheduled workflow that trains or fetches a model, generates embeddings, and builds a new index snapshot. Versioned artifact registry, Offline document embedding service, Lucene Plus index, Validation gates
Validation gates Completeness, backward-compatibility, and correctness checks that block unsafe index deployments. Biweekly refresh workflow, Lucene Plus index, Rollback controller
Serving-time compatibility check Samples production requests to verify query-model IDs match active index-column metadata. Online query embedding service, Lucene Plus index, Rollback controller
Rollback controller Alerts and rolls model deployment back when compatibility errors remain non-zero. Validation gates, Serving-time compatibility check

Data flow

The system trains a two-tower embedding model with Qwen, MRL-based infoNCE loss, PyTorch, Ray, DDP, and DeepSpeed ZeRO-3. Offline inference embeds stores or items at feature level, writes entity-keyed vectors to feature-store tables, joins them to the full catalog, and builds Lucene Plus HNSW indexes with float and quantized vectors. At serving time, an online service computes query embeddings, structured filters reduce the search space, ANN retrieves candidates, optional micro-reranking refines results, and downstream rankers consume the retrieval cohort. Refresh jobs build new index snapshots, validate active and inactive columns, deploy non-prod correctness checks, and sample production requests for model/index ID compatibility.

4 supporting quotes
“The query embeddings are calculated via an online service in real time, while the document embeddings are calculated in a batch manner via offline scheduled services.”article, stated
“we embed documents at the feature level (for example, store or item) and then join these embeddings back to the full catalog of billions of candidates before indexing.”article, stated
“Beyond quantization and k tuning, our vector index is paired with locale-aware lexical fields and boolean pre-filters”article, stated
“On sampled requests, the service verifies that the model used to generate the query embedding matches the model ID recorded on the active index column.”article, stated

Why this architecture

Uber chose a two-tower architecture to decouple low-latency online query embedding from expensive offline document embedding. Qwen provided world knowledge and cross-lingual ability, while fine-tuning adapted the embedding space to Uber Eats. MRL, quantization, pre-filters, and micro-reranking let the system trade off recall, latency, and storage without retraining separate models for each use case. Blue/green columns and validation gates keep the biweekly refresh process safe without doubling index storage.

4 supporting quotes
“We adopted the classic two-tower structure so that the query and document embedding calculation can be decoupled.”article, stated
“The latest LLMs (QWEN®) are used as the backbone embedding layer inside two towers to leverage its world knowledge and cross-lingual abilities.”article, stated
“This gives us the flexibility to trade off speed versus quality at inference time, without retraining separate models.”article, stated
“We also considered maintaining two separate blue and green indexes instead of two columns within a single index.”article, stated

Models used: Qwen · two-tower deep neural network · Matryoshka Representation Learning · compact neural network micro-reranker · HNSW vector index

Scale

Alternatives considered (roads not taken)

Rely on lexical search alone

Rejected because: Lexical matching fails on synonyms, typos, shorthand, language mixing, and ambiguous terms because it sees strings rather than meaning.

“Traditional search stacks begin with lexical matching, which is fast and effective when queries exactly match document text.”article, stated
“Lexical methods see strings, not meaning, and aren’t suitable for such queries, producing bad search results.”article, stated

Compute all embeddings online

Rejected because: The architecture decouples query and document computation so only query embeddings are online while document embeddings are batch-generated.

“The query embeddings are calculated via an online service in real time, while the document embeddings are calculated in a batch manner via offline scheduled services.”article, stated

Embed every catalog document individually

Rejected because: Uber embeds at feature level and joins vectors back to the catalog to reduce redundant work at corpus scale.

“To manage costs, we embed documents at the feature level (for example, store or item)”article, stated
“then join these embeddings back to the full catalog of billions of candidates before indexing.”article, stated

Maintain two separate blue and green indexes

Rejected because: Separate indexes would simplify reliability but would significantly increase storage and maintenance costs.

“While that approach would simplify reliability—since we wouldn’t need to touch the production index during a refresh—it’d significantly increase storage and maintenance costs.”article, stated

Patterns

hybrid-search (retrieval)

Uber Eats combines semantic vector retrieval with locale-aware lexical fields and boolean pre-filters for production search across verticals and languages.

“Semantic search shifts from matching words to matching meaning. It encodes queries and documents into vectors in the same space”article, stated
“it delivers a search experience that better captures someone’s intent across verticals (stores, dishes, items) and languages.”article, stated

fine-tuning-adaptation (model-adaptation)

Uber fine-tuned the Qwen embedding backbone with proprietary Uber Eats data to adapt semantic space to delivery-search scenarios.

“We further finetuned them using Uber Eats in house data to adapt the embedding space to our application scenarios.”article, stated

latency-optimization (serving)

MRL enables smaller embedding cuts from one trained model so serving can trade quality for latency, storage, and retrieval cost.

“MRL solves this by training a single model whose embeddings can be cut at different lengths.”article, stated
“Shorter versions of the embedding capture coarse information quickly, while longer versions add finer details for higher accuracy.”article, stated

cost-aware-routing (operations)

Uber tunes shard k, quantization, embedding dimension, pre-filters, and feature-level embedding to reduce latency, CPU, and storage without materially degrading recall.

“we ran controlled experiments varying three key factors”article, stated
“Together, these optimizations significantly lowered the cost and latency of serving large-scale indexes without any significant compromising in retrieval quality.”article, stated

canary-rollout (deployment)

Uber refreshes blue/green index columns and rolls out model changes gradually, with rollback triggered by serving-time compatibility errors.

“we adopted a blue/green pattern at the index column level.”article, stated
“we deploy the new index to production, then roll out the model gradually.”article, stated

eval-driven-development (evaluation)

The refresh pipeline blocks deployment through completeness, backward-compatibility, and correctness checks before serving a new index.

“we gate with automated validations that run before any deployment”article, stated
“Concretely, our pipelines run three checks.”article, stated

observability-tracing (operations)

Uber samples production requests, emits compatibility-error metrics, logs context, alerts, and rolls back on sustained version mismatches.

“On any mismatch, we emit a compatibility-error metric and log full context.”article, stated
“If errors remain non-zero over a short window, an alert fires and we automatically roll back the model deployment to the previous version”article, stated

Tradeoffs

Embedding architecture

Chose two-tower online/offline embedding separation over coupling query and document embedding calculation into one serving path.

Rationale: The split lets Uber compute query embeddings in real time while document embeddings are scheduled offline at corpus scale.

“We adopted the classic two-tower structure so that the query and document embedding calculation can be decoupled.”article, stated
“The query embeddings are calculated via an online service in real time, while the document embeddings are calculated in a batch manner”article, stated

Index-refresh topology

Chose one index with blue and green embedding columns over two fully separate blue and green indexes.

Rationale: The single-index approach avoids higher storage and maintenance costs but requires stronger validation to offset reliability risk.

“We also considered maintaining two separate blue and green indexes instead of two columns within a single index.”article, stated
“Given that trade-off, we built a mechanism that lets us safely operate with one index containing two columns.”article, stated

Embedding representation size

Chose MRL cut-down embeddings such as 256 dimensions over serving full-size embeddings for every use case.

Rationale: MRL lets downstream tasks trade quality for latency and storage while preserving strong retrieval quality in evaluated languages.

“downstream tasks could choose the optimal embedding dimension according to their own size versus quality tradeoffs.”article, stated
“256 dimensions) with almost no loss (< 0.3% for English and Spanish) in retrieval quality compared to full-size embeddings”article, stated

ANN cost tuning

Chose lower shard-level k and quantized vectors over higher k and fp32 vectors everywhere.

Rationale: Experiments showed large latency and CPU savings with negligible recall impact and recall above 0.95 under int7 quantization.

“Lowering shard-level k from 1,200 to around 200 yielded a 34% latency reduction and 17% CPU savings in our experiments”article, stated
“applying scalar quantization (int7) further cut compute costs, reducing latency by more than half compared to fp32 while maintaining recall above 0.95.”article, stated

Gotchas (what bit them)

Pure lexical search fails on real marketplace query language.

Root cause: User queries contain synonyms, typos, shorthand, language mixing, and ambiguous words that string matching cannot resolve.

Resolution: Encode queries and documents as vectors in a shared semantic space while retaining lexical and boolean filters for production constraints.

“real queries are challenging—synonyms (“soda” versus “soft drink”), typos (“mozzarela”), shorthand (“gf pizza”), language mix”article, stated
“Semantic search shifts from matching words to matching meaning. It encodes queries and documents into vectors in the same space”article, stated

Embedding every document independently would waste expensive inference.

Root cause: The document corpus is large enough that redundant embedding computation would dominate cost.

Resolution: Compute embeddings at feature level, store them by entity ID, and join them back to billions of candidates before indexing.

“Given the scale of our document corpus, offline inference is critical. To manage costs, we embed documents at the feature level”article, stated
“then join these embeddings back to the full catalog of billions of candidates before indexing.”article, stated

Refreshing a shared blue/green-column index can corrupt the currently serving column.

Root cause: The refresh build re-materializes both columns even when only the inactive column is intended to change.

Resolution: Block deployments with completeness, backward-compatibility, and correctness validations before switching traffic.

“Even though only the inactive column is intended to change, the build re-materializes the active column as well”article, stated
“we gate with automated validations that run before any deployment”article, stated

Model/index version mismatches can still happen after build-time checks.

Root cause: Human error or configuration bugs can map the wrong model to the active index column or build an index against an unexpected model.

Resolution: Store model IDs in index metadata, sample requests for compatibility, emit metrics, alert, and auto-rollback the model deployment.

“there’s still a risk of human error or bugs. For example, a wrong model-to-column mapping or an index built against a different-than-expected model.”article, stated
“the service verifies that the model used to generate the query embedding matches the model ID recorded on the active index column.”article, stated

Evaluation

Uber evaluates the platform through controlled cost/quality experiments, offline retrieval-quality comparisons, index-build validation gates, non-production query replay, production compatibility metrics, and rollback alerts.

Metrics: recall · latency reduction · CPU savings · storage reduction · document-count completeness · byte-for-byte backward compatibility · production compatibility-error metric

3 supporting quotes
“we explored several mechanisms to balance cost, latency, and performance. In particular, we ran controlled experiments varying three key factors:”article, stated
“deploy the newly built index to a non-prod environment, replay real queries at a controlled rate, and compare recall against the current production index.”article, stated
“On any mismatch, we emit a compatibility-error metric and log full context.”article, stated

Outcomes

The system targets all Uber Eats verticals and markets, trains on hundreds of millions of data points, indexes a multi-billion-document corpus, and refreshes model/index state biweekly.

3 supporting quotes
“We built a scalable, multilingual search system for Uber Eats that powers discovery across restaurants, grocery, and retail with speed and precision.”article, stated
“Lowering shard-level k from 1,200 to around 200 yielded a 34% latency reduction and 17% CPU savings in our experiments”article, stated
“automatically retrains, rebuilds, and refreshes search indexes every two weeks”article, stated