•CASE STUDY

Daily Puzzle Platform (Wordle-style)

4 min read·618 words·Beginner

Asked at

1 candidate report in Apr 2026

How to use this case study

SDE-2 / Mid

  • Design the APIs and data model for daily puzzles
  • Attempts
  • Scoring and streaks
  • With server-side answer checking

SDE-3 / Senior

  • Handle the release spike (everyone plays at midnight)
  • Time zones
  • Anti-cheating (never send the answer)
  • Leaderboards

Staff / Principal

  • Discuss content scheduling
  • Statistics at scale
  • Extending to multiple puzzle types and competitive modes

Problem RestatementProblem

Design a platform for a daily puzzle (asked at Uber), like Wordle or a daily crossword. Every day, all users get the same new puzzle. They submit attempts, the server checks them and gives feedback, and a solved puzzle earns a score. Users keep streaks (days in a row solved), see statistics, and compare on leaderboards (global and friends).

RequirementsRequirements

  • Publish one puzzle per day (scheduled in advance).
  • Submit guesses and get feedback (e.g., which letters are right), with limited attempts.
  • Scoring (fewer attempts or faster = better), streaks and personal stats.
  • Leaderboards: daily global and friends.
  • Fair play: answers never leak to the client ahead of time.

1.1 Scale

  • 10M daily players, most within a few hours of release. Peak ~50K guesses/sec right after release.

APIs

GET  /v1/puzzles/today?tz=Asia/Kolkata     → { puzzle_id, date, type, board (no answer), max_attempts }
POST /v1/puzzles/{id}/guesses  { guess }    → { feedback, attempts_left, solved, score? }
GET  /v1/me/stats                            → { streak, max_streak, played, win_rate, distribution }
GET  /v1/puzzles/{id}/leaderboard?scope=global|friends&cursor=

ArchitectureArchitecture

Architecture diagram
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","classText":"#1e1e1e"}}}%%
flowchart LR
    U["Players"] --> CDN["CDN - puzzle metadata (no answers)"]
    U --> API["Game API - stateless"]
    API --> PZ[("Puzzle store - answers encrypted")]
    API --> AT[("Attempts - by user, puzzle")]
    API --> LB[("Redis sorted sets - leaderboards")]
    API --> K[("Events")]
    K --> ST["Stats + streak updater"]
    ST --> SDB[("User stats")]
    ADM["Editors"] --> SCH["Puzzle scheduler"]
    SCH --> PZ

Deep Dive — Keeping today's answer secretDeep dive

Everyone gets the same puzzle, which means one leaked answer spoils it for the entire user base at once.

Weak

Ship the answer to the client

The app downloads today's puzzle with its solution and checks guesses locally. It is fast, works offline, and costs the server nothing.

Architecture diagram
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","classText":"#1e1e1e"}}}%%
flowchart LR
  APP["Client downloads the puzzle"] --> ANS["...including the answer"]
  ANS --> DEV["Anyone opens dev tools or decompiles the app"]
  DEV --> LEAK["Answer posted publicly within minutes"]
  ANS --> CHEAT["Local check can be bypassed - unlimited attempts, fake scores"]

This is exactly how Wordle originally shipped, and the answer list was extracted immediately. Anything the client holds, the user holds. Local checking also means attempt limits and scores are whatever the client says they are, so the leaderboard is fiction.

Good

Send a hash of the answer

Ship sha256(answer) and have the client compare hashes.

The answer is no longer literally in the payload. But the candidate space for a puzzle answer is tiny — a five-letter word list is a few thousand entries — so the hash is brute-forced in milliseconds. And the attempt count is still enforced on the client, so scores remain unverifiable regardless.

Best

Check on the server, and make the attempt count authoritative

Architecture diagram
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","classText":"#1e1e1e"}}}%%
flowchart LR
  G["POST guess"] --> SRV["Server - holds the answer"]
  SRV --> INC{"Conditional update: attempts + 1 where attempts < max"}
  INC -->|"0 rows"| REJ["Rejected - out of attempts or a duplicate submit"]
  INC -->|"1 row"| CHK["Compare with the answer"]
  CHK --> FB["Return feedback only - never the answer"]
  CHK -->|"correct"| SCORE["Compute and store the score server-side"]
  PUB["Puzzle published"] --> WIN["Future puzzles never sent to clients early"]
  • The client never receives the answer, only per-guess feedback. That is the only version of this that holds.
  • The attempt increment is a conditional update on (user_id, puzzle_id), so a double-tap or two tabs cannot both consume the same attempt slot or race past the limit.
  • Scores are computed server-side when the puzzle is solved. Anything computed on the client is a suggestion.

Then decide what "today" means and say it once: release at the user's local midnight, or at a single global instant. Local midnight is usually better — it spreads the daily traffic spike across twenty-four hours instead of concentrating the entire user base into one minute — but it means a user changing time zone must not be able to replay or skip a day, so pin the puzzle date to the account's first-seen zone.

Handling the Spike

  • Puzzle metadata (without the answer) is cached at the CDN, since it's identical for everyone.
  • The game API is stateless and pre-scaled before release. Answers are cached in memory on API servers (loaded securely at release time).
  • Attempts are written to a partitioned store (by user), which spreads writes evenly.
  • Stats updates are asynchronous via events, so the guess path stays fast.

Wrap-UpWrap-up

Schedule puzzles in advance and serve today's puzzle (without the answer) from a CDN, check every guess on the server with enforced attempt limits stored per user and puzzle, and compute scores on solve. Update streaks and stats asynchronously with time-zone-aware day logic, keep leaderboards in Redis sorted sets (with friends' boards computed from small friend lists), and spread or pre-scale for release spikes.

More Case Studies

Frequently Asked Questions

What is the Daily Puzzle Platform (Wordle-style) system design question?

Daily Puzzle Platform (Wordle-style) is a system design interview question asked at FAANG companies. It covers api design, caching, databases, real-time and tests your ability to design scalable, production-ready systems. InterviewSkool's breakdown walks you through requirements, API design, architecture, and trade-offs.

Which companies ask the Daily Puzzle Platform (Wordle-style) question?

Uber have reportedly asked variations of this question in system design interviews. The exact wording may differ, but the core design challenges remain the same.

How should I prepare for the Daily Puzzle Platform (Wordle-style) interview question?

Start with the problem statement and scale estimates, then design the high-level architecture. Focus on the core components, data model, and API design. InterviewSkool's breakdown covers the full solution with mermaid diagrams and trade-off analysis to help you prep efficiently.

What level is the Daily Puzzle Platform (Wordle-style) question?

This question is suitable for SDE-2, SDE-3, and Staff engineer interviews. The level guidance on this page provides specific tips for each level — SDE-2 candidates should focus on core architecture, while Staff engineers should discuss trade-offs, monitoring, and incremental rollouts.

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with InterviewSkool's AI interviewer.

Start System Design Interview →