Design a Photo Album App
RobinhoodFrontend Engineer · OnsiteLast updated
This question evaluates proficiency in frontend system design, specifically client-side component and data architecture, state management and normalization, real-time synchronization, and large-media upload flows; it sits in the System Design domain with a Frontend Engineer focus and tests practical application of these competencies.
Design a web-based photo album application for the browser (a frontend-focused system design).
The product has three main screens, each provided to you as a design mockup:
- Album list page — a grid/list of albums. Each album shows a cover photo and the album name.
- Album detail page — the photos inside a selected album. From here a user can upload new photos and rename the album.
- Photo info page — details for a single selected photo (e.g. location, capture time).
The core functional requirements are:
- View all albums.
- Open an album and view its photos.
- Rename an album.
- Upload one or more photos into an album.
- Changes propagate across the user's devices in near real time (e.g. renaming an album on a laptop updates an open tab on a phone within seconds).
- Photos (and albums) can be sorted by city.
- Sorting supports descending order.
This is a Frontend Engineer interview, so depth is expected on the client: component/data architecture, state management, normalization, the real-time sync mechanism, and the upload flow. Design the server and API only as far as needed to support the client. Be concrete about the client data model and where each piece of state lives — the interviewer will push on trade-offs at every step, and (per the original loop) will push especially hard on not keeping two sources of truth.
Constraints & Assumptions
State your assumptions; reasonable ones include:
- Single-user, multi-device is the primary scenario (a user with a laptop and a phone sees only their own albums). Design so shared/collaborative albums could be added later, but they're an extension, not the core.
- Album lists are modest (tens to low hundreds); a single album may hold a handful to thousands of photos, so the photo list must paginate.
- Photos are large binaries (single-digit MB each); metadata is small. Reads dominate writes.
- "Near real time" means seconds, not strict global ordering — eventual consistency with conflict resolution is acceptable.
cityis derived server-side from a photo's EXIF GPS via reverse geocoding at ingest, ornullwhen unavailable — not free-typed by the user.- The client is a modern SPA (e.g. React); binary photos live in object storage (S3 / GCS / equivalent) fronted by a CDN. Treat the API/transport as designable (REST, GraphQL, WebSocket, SSE) and justify the choice.
Clarifying Questions to Ask
- Is this single-user-multi-device, or do albums get shared/collaborated on? Does that change the sync and permission model?
- How large can an album get — do photo lists need pagination and virtualization?
- Does "sort by city" sort the photos within an album, the album list, or both? Must it sort the entire paginated set or only loaded photos?
- Where does
citycome from — server-side EXIF/geocoding or client-supplied? - How strict is "real time" — sub-second or a few seconds? Is offline / queued-while-offline editing in scope?
- Are photos private (signed URLs / auth-gated) or can the CDN serve them publicly? Is there an existing data-fetching library to use, or is that a free choice?
Hints
Hint 1
Where to start: Map each of the three screens to the data it needs, then ask the load-bearing question: is any album or photo object represented in **more than one place** (e.g. once in the album-list view and again inside the album-detail view)? That duplication question is the heart of the "state management and data normalization" discussion the interviewer cares most about.
Hint 2
Normalization — push on duplication: If the same album or photo can be edited from two screens, ask yourself: when a sorted-by-city list is shown, is that ordering something you *store* and have to keep in sync, or something you *recompute*? Notice the original loop's tell — the interviewer nudged toward `useMemo` and away from `useEffect`. What does that distinction imply about where a derived view should live?
Hint 3
Real-time + upload: For sync, don't jump to a transport — first characterize the traffic: which way do most messages flow, and what must happen when a device was disconnected while something changed? Let those two questions select among the options and decide whether you need a recovery path. For upload, trace where a multi-MB binary actually travels relative to your API tier, and enumerate the states a tile passes through between "user picked a file" and "fully processed."
Hint 4
Sorting & rendering: Where should the sort be authoritative once an album is large enough to paginate — and what breaks if you sort only the page you've loaded? City sort has an awkward case: some photos have no city yet. Decide how those should behave. Separately, a single album may hold thousands of tiles; ask what that does to the DOM and the browser.
Follow-up questions
- A user uploads 200 photos at once on a slow connection. How do you keep the UI responsive, bound concurrency, show per-file progress, and recover from partial failure?
- Two devices rename the same album within the same second. Walk through exactly what each device sees and what's persisted under your conflict strategy.
- Some photos have no city yet (still processing). How should they appear in a city-sorted, paginated list, and how does the order stabilize once processing completes?
- Your WebSocket drops for 30 seconds and a rename plus three uploads happen during the outage. How does the client end up consistent again without a full reload?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.