← Shopify Interview Insights

Shopify·Machine Learning Engineer·Onsite - System Design / Architecture·Senior

SeniorPrefer not to say
Jun 2026Remote

Summary

System design round at Shopify for an ML Engineer role, focused almost entirely on caching internals. Not what I expected going in, but it got pretty deep pretty fast.

Questions Asked (5)

Q1

Walk me through how a TTL cache works internally, including how expiration is handled per entry and the difference between lazy and eager eviction strategies.

System DesignTechnical Trade-offsAlgorithms & Data Structures
Author's notes

I knew the basics but stumbled on the lazy vs eager distinction when pushed on tradeoffs.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by defining a TTL cache and its core components (storage, TTL metadata, expiration mechanism). Then explain per-entry expiration handling, contrasting lazy and eager eviction strategies with their trade-offs, and finally relate it to ML engineering contexts like feature stores or model caching.

Pro tip: Mention that in practice, a hybrid approach (lazy eviction with periodic active sweeps) is often used to balance memory and latency, and tie it to ML systems where stale features can degrade model performance.

1. Define TTL Cache and Core Components

Explain that a TTL cache stores key-value pairs with an associated expiration timestamp, and typically includes a hash map for storage and a priority queue or heap for efficient expiration tracking.

2. Explain Per-Entry Expiration Handling

Describe how each entry gets a TTL (time-to-live) value, and how the cache checks the current time against the entry's expiration timestamp to determine validity.

3. Contrast Lazy vs. Eager Eviction

Lazy eviction removes expired entries only when accessed, saving CPU but potentially wasting memory; eager eviction proactively removes expired entries via a background thread or timer, freeing memory but adding overhead.

4. Discuss Trade-offs and Use Cases

Analyze when to use each strategy: lazy for read-heavy workloads with low memory pressure, eager for write-heavy or memory-constrained environments, and hybrid approaches for balanced performance.

5. Relate to ML Engineering at Shopify

Connect TTL caching to ML use cases like caching model predictions, feature store entries, or embeddings, emphasizing how expiration ensures freshness and consistency in production systems.

Key Points to Mention

  • TTL cache stores expiration timestamps alongside values, often using a min-heap or time wheel for efficient expiration tracking.
  • Lazy eviction checks expiration on access, leading to potential memory bloat but lower CPU overhead.
  • Eager eviction uses background processes to remove expired entries, ensuring memory is freed promptly but adding complexity and CPU cost.
  • Hybrid approaches combine lazy eviction with periodic active expiration sweeps to balance latency and memory.
  • In ML systems, TTL caches are crucial for feature freshness (e.g., user behavior features) and avoiding stale predictions.
  • Consider thread safety and concurrency when implementing TTL caches in high-throughput ML serving environments.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

How does a TTL cache differ from LRU and LFU caches, and when would you choose TTL-based eviction over the others?

System DesignTechnical Trade-offs
Author's notes

This one I felt okay about.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by defining each eviction policy (TTL, LRU, LFU) and their core mechanisms, then compare their trade-offs in terms of staleness, access patterns, and memory overhead. Finally, discuss scenarios where TTL is preferable, especially in ML systems with time-sensitive data, and how it can be combined with other policies.

Pro tip: Mention that TTL is often used alongside LRU or LFU (e.g., TTL to bound staleness and LRU to bound memory), and that in ML feature stores, TTL ensures model inputs reflect recent data, which is critical for online inference.

1. Define the policies

Briefly explain TTL (time-based expiration), LRU (evict least recently used), and LFU (evict least frequently used).

2. Compare eviction triggers

Contrast TTL's time-based eviction with LRU/LFU's access-based eviction, noting that TTL does not consider access patterns.

3. Analyze trade-offs

Discuss staleness, memory efficiency, and computational overhead: TTL prevents stale data but may evict hot items; LRU/LFU optimize hit rate but can serve stale data.

4. Identify use cases

Describe when TTL is preferred: time-sensitive data (e.g., user sessions, real-time features), compliance requirements, or when data freshness is critical.

5. Relate to ML engineering

Connect to ML systems: TTL for feature stores to avoid stale features, LRU/LFU for model caching where access patterns matter.

Key Points to Mention

  • TTL evicts based on time-to-live, while LRU and LFU evict based on access patterns (recency and frequency).
  • TTL ensures data freshness but may evict frequently accessed items, reducing hit rate; LRU/LFU optimize hit rate but may serve stale data.
  • TTL is ideal for time-sensitive data like user sessions, real-time features, or cached API responses with expiration.
  • In ML, TTL is crucial for feature stores to prevent stale features from degrading model predictions.
  • TTL can be combined with LRU/LFU to bound both staleness and memory usage.
  • LFU is better for stable popularity distributions, while LRU adapts to changing access patterns; TTL is orthogonal and can complement both.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

What are some concrete production use cases where TTL caching makes sense? What data would you cache, what TTL would you pick, and how do you justify that TTL value?

System DesignProduct Analytics & Metrics
Author's notes

Went with ML feature caching as my example since it was relevant to the role.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying that TTL caching is about trading freshness for latency and cost, then walk through 2-3 concrete ML production use cases at Shopify (e.g., product recommendations, fraud detection, search ranking). For each, specify the data cached, a reasonable TTL, and justify it by balancing business impact, data volatility, and system constraints like model update frequency and traffic patterns.

Pro tip: Always tie the TTL to a measurable business metric (e.g., conversion rate, fraud loss) and mention that you'd A/B test or monitor cache hit rate and staleness to tune it—this shows you think like an owner, not just an engineer.

1. Clarify TTL caching and its trade-offs

Briefly define TTL caching as storing computed results for a fixed time to reduce latency and load, noting the trade-off between freshness and efficiency. Emphasize that TTL choice depends on data volatility and business tolerance for staleness.

2. Select relevant ML use cases

Choose 2-3 concrete ML production use cases at Shopify, such as product recommendations, fraud detection, or search ranking. For each, describe the cached data (e.g., user embeddings, model predictions, feature vectors).

3. Propose TTL values with justification

For each use case, state a specific TTL (e.g., 5 minutes, 1 hour, 24 hours) and justify it by considering data update frequency, model retraining cadence, and acceptable staleness. Reference business metrics like conversion or fraud rate.

4. Discuss monitoring and tuning

Explain how you would monitor cache hit rate, latency, and staleness, and how you might A/B test different TTLs to optimize for business outcomes. Mention fallback strategies if cache misses spike.

5. Summarize with a principle

Conclude with a general principle: TTL should be as long as possible without violating freshness requirements, and should be derived from data volatility and business impact, not arbitrary.

Key Points to Mention

  • Trade-off between latency/cost and data freshness
  • Concrete ML use cases: recommendations, fraud detection, search ranking
  • Data volatility: how often the underlying data or model changes
  • Business impact of staleness (e.g., showing out-of-stock items, missing fraud)
  • Monitoring cache hit rate and staleness metrics
  • A/B testing TTL values to optimize business metrics

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

What are the main pitfalls of TTL caches in production, specifically around thundering herd on expiration, stale reads, and memory growth from lazy eviction?

System DesignTechnical Trade-offsRoot Cause Analysis
Author's notes

Thundering herd is where I spent most of my time.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging that TTL caches are a common but nuanced component in ML systems, then systematically address each pitfall: thundering herd, stale reads, and memory growth. For each, explain the root cause, its impact in production (especially for ML feature stores or model caches), and mitigation strategies, tying back to Shopify's scale and reliability needs.

Pro tip: Emphasize that in ML systems, stale reads can silently degrade model performance, so monitoring cache hit rates and freshness is as critical as latency metrics. Also, mention that jittered TTLs and probabilistic early expiration are simple but effective fixes for thundering herd.

1. Define the context and stakes

Briefly explain why TTL caches are used in ML production (e.g., caching features, embeddings, or model predictions) and the consequences of failures at Shopify's scale.

2. Analyze thundering herd on expiration

Describe how simultaneous expiration of many keys can overwhelm backend services, and propose solutions like TTL jitter, staggered expiration, or request coalescing.

3. Address stale reads

Explain how stale data can lead to incorrect predictions or decisions, and discuss strategies like versioning, invalidation on writes, or using short TTLs with fallback to fresh data.

4. Discuss memory growth from lazy eviction

Explain that lazy eviction (only evicting on access) can cause memory bloat, and suggest proactive eviction policies (e.g., LRU, LFU) or background eviction threads.

5. Summarize trade-offs and best practices

Conclude with how to balance these pitfalls, e.g., using adaptive TTLs, monitoring, and choosing the right eviction policy for the workload.

Key Points to Mention

  • Thundering herd: causes and mitigations (jitter, early recomputation, request collapsing)
  • Stale reads: impact on ML model accuracy and strategies for freshness (versioning, write-through, invalidation)
  • Memory growth: lazy vs. proactive eviction, and choosing eviction policies (LRU, LFU, TTL-based)
  • Monitoring and observability: tracking hit rate, eviction rate, and staleness metrics
  • Trade-offs between TTL length, freshness, and backend load
  • Real-world examples from ML systems (e.g., feature stores, model serving caches)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

Can you compare common TTL cache implementations across different tools, such as Python's cachetools, Guava's CacheBuilder, and Redis EXPIRE?

System DesignAPI & IntegrationsTechnical Trade-offs
Author's notes

Knew cachetools reasonably well, used it before.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by categorizing the tools based on their architecture: in-process libraries (cachetools, Guava) versus distributed stores (Redis). Then compare them across dimensions like eviction policy, TTL granularity, concurrency, and scalability, and tie the trade-offs back to ML engineering use cases at Shopify, such as caching model predictions or feature lookups.

Pro tip: Emphasize that the choice depends on whether your cache is local to a single process or shared across a fleet; for ML serving, a hybrid approach (local TTL cache + Redis for cross-instance consistency) often balances latency and freshness.

1. Categorize the tools

Classify cachetools and Guava as in-process, library-level caches, and Redis EXPIRE as a distributed, server-side cache. This sets the stage for comparing their fundamental capabilities.

2. Compare TTL and eviction semantics

Discuss how TTL is implemented: cachetools uses per-item TTL with optional LRU eviction, Guava offers TTL and size-based eviction with refresh policies, and Redis EXPIRE provides per-key TTL with configurable eviction policies (e.g., allkeys-lru).

3. Evaluate concurrency and scalability

Highlight that in-process caches are limited to a single process and require thread-safety mechanisms, while Redis scales horizontally and supports atomic operations, but adds network latency and potential single point of failure.

4. Map to ML engineering use cases

Relate each tool to scenarios like caching model predictions, feature vectors, or API responses. For example, cachetools for per-worker memoization, Guava for JVM-based services, and Redis for shared feature stores across a cluster.

5. Summarize trade-offs and recommendation

Conclude with a balanced view: in-process caches are fast and simple but not shared; Redis is shared and scalable but adds latency and complexity. Suggest a hybrid or layered approach based on consistency and latency requirements.

Key Points to Mention

  • TTL granularity: per-item vs. per-cache vs. per-key expiration
  • Eviction policies: LRU, LFU, random, and how they interact with TTL
  • Concurrency: thread-safety in in-process caches vs. Redis atomicity
  • Scalability: single-process limitation vs. distributed cache with network overhead
  • Use cases in ML: caching predictions, features, embeddings, and API responses
  • Hybrid caching: combining local TTL caches with Redis for tiered freshness and performance

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.