System design scenarios cheat sheet

The 10 System design scenarios interview answers in 30 seconds each, plus quick facts. Printable, free.

One page per topic: print it or save it as PDF from your browser's print menu. Practise these questions

Designing an infinite-scroll social feed

Use cursor-based pagination from the server, a local cache (database) that the UI observes so the feed opens instantly and works offline, and a repository that merges fresh pages into it. Prefetch the next page before the end, load media through an image pipeline, update likes optimistically with rollback on failure, and show new posts with a 'new posts' pill rather than shifting the list.

A thread-safe LRU cache

Combine a dictionary from key to node with a doubly linked list ordered by recency, so lookups, inserts and evictions are O(1). On a hit, move the node to the front; on insert past capacity, remove the tail. Protect the state with a Mutex (iOS 18) or an actor, depending on whether callers are synchronous or async.

Offline-first architecture

Make the local database the source of truth: the UI reads from it and updates as it changes. User actions write locally first, then go into a persistent outbox of mutations with idempotency keys. A sync engine sends the outbox when the network is available, pulls server changes since the last sync token, and resolves conflicts with clear rules, such as the server winning for prices and stock, and merging for the cart.

A map with 10,000+ live pins

Never put every pin on the map. Query only drivers in the visible region (plus a margin), cluster them at low zoom, and update positions in batches a few times per second, diffing by driver id and animating moves. Receive updates over a WebSocket filtered by region on the server. For extreme density, draw dots in a custom overlay or Metal layer instead of annotation views.

Responding to a crash spike

First assess scope: which app version, OS, devices and screens, using Organizer, MetricKit or your crash reporter. Then mitigate quickly: pause the phased release, turn off the feature flag, or fall back on the server. Find the root cause from symbolicated stack traces and logs, fix it with a test, and ship an expedited update if needed. Finish with a blameless post-mortem and prevention steps.

An adaptive-bitrate player with Picture in Picture

Use AVPlayer with HLS: it switches bitrate automatically based on bandwidth. Show it with AVPlayerViewController (PiP and controls come free) or an AVPlayerLayer with AVPictureInPictureController for custom UI. Set the audio session category to playback and enable the background mode for audio, AirPlay and Picture in Picture. Observe status, buffering and errors, and persist the playback position.

A secure payment flow

Keep payment credentials out of the app where possible: use Apple Pay or the payment provider's tokenisation SDK. Protect any stored token in the Keychain with biometric access control, so Face ID releases it. Send requests over TLS with public key pinning and an idempotency key, let the server validate and charge, and show a clear result, retrying safely with the same key.

A 60 fps short-video feed

Use a paging collection view (or SwiftUI paging scroll view) with a small pool of reusable AVPlayers, perhaps three: current, next and previous. Preload the next items' assets and first segments, start playback only for the most visible cell, and pause and release the rest. Keep the main thread free by loading assets asynchronously and showing a thumbnail until the first frame renders.

A chat timeline that survives retries

Give each outgoing message a client-generated id and show it immediately as pending. The server stores it idempotently by that id and assigns a sequence number per conversation. Order the timeline by server sequence, place pending messages at the end, and on reconnect fetch everything after the last sequence you have. Deduplicate by id, so retries and echoes never create duplicates.

A release that causes data loss

Stop the spread first: pause the phased release, turn off any flags involved, and stop the server from accepting destructive changes if relevant. Protect what remains by shipping a hotfix that disables the faulty path. Reproduce with diagnostics to find the root cause, recover users' data from server copies or backups where possible, tell affected users honestly, and add regression tests and migration safeguards.

Quick facts

Idempotency key
A unique id sent with a request so the server performs it at most once, however many times it is retried.
Cursor pagination
The server returns an opaque cursor for the next page, stable under inserts and deletes.
Blast radius
How many users a failure reaches; phased releases and flags keep it small.