Design Auto-Complete
Real-time typeahead query suggestion system generating dynamic matches under high write/read traffic.
1. System Requirements
- Provide top 5 search query suggestions based on historical popularity matching the typed prefix.
- Suggestions must update dynamically as the user types.
- Must support custom query blacklisting.
- Extremely low-latency updates: suggestions must appear in < 100ms.
- High availability and scalability to process 100,000 queries/sec.
2. Scale & Resource Estimates
Throughput: 100 Million daily active users. Assuming 10 search queries/day and 5 keystrokes per query = 5 Billion typeahead requests/day = ~58,000 requests/sec average.
Storage & RAM: 10M unique queries * 15 bytes = 150 MB database storage. Extremely lightweight, allowing complete in-memory storage.
3. System API Endpoints
GET /api/v1/search/suggest?q=sys
Response: { suggestions: ["system design", "system metrics", "system software", "sys log", "sysctl"] }
4. Database Schema Design
Table: query_frequencies (MySQL - for MapReduce batch updates)
- query (VARCHAR - Primary Key)
- frequency (BIGINT)
Trie Cache (Redis Cache - Key-Value)
- Key: prefix:{char_sequence}
- Value: Sorted Set of suggestions (Score: frequency)
5. Interactive High-Level Architecture
6. Scalability Deep Dive & Bottlenecks
Stores prefix suggestions inside an in-memory Trie (Prefix Tree) cache. To optimize lookup speed, each Trie node contains a list of its top 5 hot queries, reducing retrieval time from $O(L + K \log K)$ to $O(L)$ where $L$ is query length. A nightly MapReduce offline pipeline aggregates raw search log queries, calculates frequencies, and refreshes the Trie structure in Redis.
7. Production Scaling Strategies
Trie Sharding by Prefix: Partition the Trie across 26+ Redis nodes by first character of the query. 'a-c' on node 1, 'd-f' on node 2, etc. Each node holds ~50M prefix entries. Hot prefixes (e.g., 'how to') are replicated to 3+ nodes for read scaling.
MapReduce Refresh Pipeline: Nightly Hadoop job processes ~10B daily search logs. Aggregate query frequencies, apply time-decay weighting (recent queries weighted 2×). Build a fresh Trie snapshot and atomically swap it into Redis via keyspace rename. Zero-downtime refresh.
Regional Edge Caching: Cache the top 10K most popular prefixes at CDN edge PoPs. Queries for 'weather', 'news', 'amazon' resolve in <5ms from edge without hitting origin. Reduces origin Trie lookups by 60%.
Query Log Sampling: At 100K queries/sec, storing every query is expensive. Sample 10% of queries for the MapReduce pipeline. Apply statistical estimation to extrapolate true frequencies. Keeps log storage under 1 TB/day while maintaining 95%+ accuracy.
Personalized Suggestions: Blend global Trie results with user-specific recent queries (stored in Redis per user_id, last 100 queries). Weight personal results 1.5× higher than global. Falls back to global-only for new users.
Latency Budget: Total autocomplete response must be <50ms (P99). Budget: 5ms network, 10ms Trie lookup, 5ms ranking, 10ms serialization. If Trie lookup exceeds 15ms, fall back to cached top-10 results for that prefix.
8. Runnable Production Starter Code
Scaffold