Library / Case Studies

Cross-Lingual End-to-End Product Search with Deep Learning at Zalando

How We Built the Next Generation Product Search from Scratch using a Deep Neural Network

By Zalando engineers · Zalando · Added 2026-10-12

Open original source

All content belongs to Zalando engineers / Zalando. We only link to it and give credit. Report a problem

Learn this case study

About 37 min left. Your work is saved as you go.

What you are about to study

Zalando explains a real system. You should know the basics: caching, queues and replication.

Ideas you will meet

Distributed Systems
Consensus, time, failure and the fundamentals of scale-out.
Search
Inverted indexes, relevance, autocomplete and search engines.
Machine Learning Systems
Recommendations, ranking, feature stores and serving models at scale.

What we already know about this

Our own lessons on these ideas. Read them here before you start, so it makes sense.

  • Search, Analytics and Geo · 10 minQuery understanding: from typed text to a search requestTurning what people type into something an index can answer: normalisation, tokenising, spelling, synonyms, intent and what to do when nothing matches.Read here

    Why the query needs work

    People type fast and loosely: "iphon 15 pro case blk", "restaurants near me", "python". An index can only match exact terms, so something has to translate the typed text into a request the index understands. That layer is query understanding, and it often matters more for result quality than the ranking formula.

    Figure SDA-SAG-03-1 · A query understanding pipeline · © forcsguy.com

    The steps

    • Normalise and tokenise. Whatever you do at index time you must do at query time, or terms will never match. Be careful with tokens that carry meaning: c++, .net, 3.5mm.
    • Spell correction. Compare against a dictionary and, better, against what other people searched and clicked. Suggest "did you mean" when unsure; auto-correct only when confident.
    • Synonyms and abbreviations. "tv" and "television", "nyc" and "new york". Store them as curated lists, applied at query time so you can change them without reindexing.
    • Intent and entities. "red nike running shoes size 10" contains a colour, brand, category and size. Mapping them to filters is more accurate than hoping words match.
    • Autocomplete and recent searches feed this layer with clean, popular queries; see the autocomplete lesson.

    Precision, recall and the empty page

    Every step moves a trade-off. Expanding synonyms finds more (higher recall) but can add junk (lower precision). Strict matching is precise but can return nothing. A robust pattern is tiered relaxation:

    Figure SDA-SAG-03-2 · Relax the query only when needed · © forcsguy.com

    Log and learn

    Log each query with what was shown and clicked (respecting privacy rules). Queries with no results, quick reformulations and low click rates show where the pipeline fails. They are also the data you need for better spelling suggestions, synonyms and evaluation, which the next lesson covers.

    Real-world reading

    Open this lesson with its quiz and exercise

  • Search, Analytics and Geo · 11 minSharding a search index: scatter, gather and mergeHow a search index is split across machines, why queries fan out to every shard, how top-k results are merged, and what goes wrong with deep paging and uneven shards.Read here

    Why shard

    One machine cannot hold or search a very large index within the latency budget. Sharding splits the index into pieces, each on its own machine, so storage and work are spread out. Replicas copy each shard for availability and extra read capacity.

    Before: one big index

    After: sharded, scatter and gather

    What changed

    • Storage and work are spread over machines
    • Each shard returns its own top results to be merged
    • The slowest shard decides how fast the query is

    Two ways to partition

    • Document-partitioned (local index): each shard indexes a subset of the documents and holds a complete inverted index for them. Writes touch one shard. Every query must visit every shard. This is what Elasticsearch and Solr do.
    • Term-partitioned (global index): each shard holds the postings for a subset of terms. A query touches only the shards for its terms, but a write touches many shards and long posting lists must be combined across machines. It is rare in practice.

    Figure SDA-SAG-05-1 · Scatter, gather and merge · © forcsguy.com

    Decisions that matter

    • Shard size and count. Too many tiny shards waste memory and add fan-out; too few huge shards recover slowly and cannot spread load. Many teams aim for tens of gigabytes per shard. The primary shard count is hard to change later, so plan for growth or use time-based indexes.
    • Routing. By default a document goes to a shard by hashing its id, which spreads data evenly. Routing by tenant or user keeps one customer's data together so queries can hit a single shard, at the risk of uneven shards.
    • Tail latency. A query is as slow as its slowest shard. Use replicas, timeouts, and hedged requests (send to a second replica if the first is slow).
    • Deep pagination. Page N needs the first N x pageSize results from every shard. Use cursors (search-after) instead of large offsets.
    • Scoring across shards. Each shard computes statistics such as IDF from its own documents. Even, large shards make the difference small; otherwise gather global statistics first.
    • Rebalancing and reindexing. Plan how to add capacity without downtime, usually by indexing into a new index and switching an alias.

    Figure SDA-SAG-05-2 · Time-based indexes · © forcsguy.com

    Keeping the index fresh

    Documents usually live in a primary database and are copied to the search index. Use a change stream or an outbox so updates are not lost, accept that search is eventually consistent, and keep a way to rebuild the whole index from the source of truth.

    Real-world reading

    Open this lesson with its quiz and exercise

  • Search, Analytics and Geo · 10 minNearby search with Redis GEOHow Redis stores locations in a sorted set using geohash scores, how GEOSEARCH finds nearby members, how to expire stale entries, and when to move to a spatial database.Read here

    The problem

    "Show the nearest available drivers", "stores within 3 km", "friends nearby". The data is a large set of points that change often, and the question is always about a small neighbourhood. You want a fast, in-memory structure.

    How Redis does it

    Redis stores locations in an ordinary sorted set. Each member (a driver id) has a score that is a 52-bit geohash of its longitude and latitude. Geohash interleaves the bits of the two coordinates so that nearby places have nearby scores. A search turns a radius into a few score ranges, reads those ranges, then filters by exact distance.

    Figure SDA-SAG-09-1 · A nearby query in Redis · © forcsguy.com

    Typical commands:

    GEOADD drivers:blr 77.5946 12.9716 driver:42
    GEOSEARCH drivers:blr FROMLONLAT 77.60 12.97 BYRADIUS 2 km ASC COUNT 20 WITHDIST
    

    Design details

    • Partition the key. One sorted set for the whole planet is a hot spot and slow to search. Use a key per city, region or grid cell so each set is small and local, and shard keys across nodes.
    • Updates are cheap. Moving a member is another GEOADD, about O(log n). 75,000 updates per second is manageable on a few nodes.
    • Freshness. Sorted set members have no individual expiry. Keep a second sorted set lastseen with the update time as score, and run a job that removes members older than, say, 30 seconds from both sets.
    • Availability filter. Store only drivers who are available, or look up status after the search; keep the hot set small.
    • Accuracy. Redis uses a spherical model of the Earth, so distances can be off by a fraction of a percent, and results near a cell boundary rely on the exact filter. That is fine for "within 2 km", not for surveying.
    • Durability. Treat Redis as a rebuildable copy. The system of record is a database, and clients re-send their location every few seconds anyway.

    Figure SDA-SAG-09-2 · Keeping the hot set fresh · © forcsguy.com

    When Redis GEO is not enough

    Move to a spatial database such as PostGIS, or a purpose-built index, when you need polygons and fences, joins with other tables, constraints (opening hours, vehicle type) together with distance, or durable queries over history. Many systems combine them: a database for rich queries and Redis for the live, hot position data.

    Other grid systems are covered in the geofencing lesson and in the real-world reading: H3 (hexagons, good for aggregation and neighbours) and S2 (cells on a sphere).

    Real-world reading

    Open this lesson with its quiz and exercise

Go deeper on this

A path through videos, articles, other case studies and code on the same ideas as Cross-Lingual End-to-End Product Search with Deep Learning at Zalando.

  1. Warm upGet the vocabulary first.

  2. WatchHow others solve the same problem, on video.

    Videos belong to their creators and play from YouTube. More on YouTube (opens in a new tab)

  3. ReadEngineers explain it in their own words.

  4. See it in another companyThe same ideas, a different system.

  5. Read the codeSee how it looks when it is real.

Keep learning

Loading community…