A dashboard made of several independent widgets isn't one system design problem — it's several small ones happening to share a page, and treating them as one shared blob is where most designs go wrong.
13 min read
Check your understanding
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A dashboard has a fast-updating order-count widget and a slow-moving weekly revenue widget. What's the strongest design for their update cadence?
Stuck? Ask the AI tutor
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Interview questions on Designing a Dashboard with Real-Time Widgets
What interviewers actually ask about this, and what a strong answer has to cover.
Design a dashboard made of five independent widgets, each updating at a different rate, some sourced from different backend services. Walk me through your architecture.
A strong answer covers
Explicitly separates fetching cadence per widget rather than proposing one unified real-time pipeline for the whole dashboard
Names per-widget graceful failure (an error boundary or equivalent) so one widget's failure doesn't affect the others, connecting it to the resilience concept
Addresses re-render scope — avoiding a single shared state object that causes unrelated widgets to re-render on every update
Considers whether sharing a transport (one connection) while keeping cadences independent is a reasonable optimization
Likely follow-ups
Would you recommend one shared WebSocket connection for all five widgets, or separate connections? What's the tradeoff?
A new widget needs to be added that updates once per day. Does your architecture need to change to support it?
"Design a dashboard made of several independent real-time widgets, each updating at different rates" sounds like it wants one unified real-time architecture. The stronger instinct is the opposite: each widget is its own small system with its own update cadence, its own failure mode, and its own re-render boundary, and the design question is how much they should actually share.
Per-widget data-fetching versus a shared centralized real-time layer. A widget showing order counts that update every few seconds and a widget showing a slow-moving weekly revenue trend have genuinely different needs — forcing them through one shared WebSocket connection with one unified update cadence means either the fast widget gets throttled to the slow widget's pace, or the slow widget gets far more frequent updates than it needs. A shared connection can still make sense (one connection is cheaper than five), but the fetching cadence per widget should stay independent even if the transport is shared.
Graceful per-widget failure. This is the canonical use case for the resilience patterns covered elsewhere in this track: if one widget's data source fails, that widget alone should show a contained fallback state, scoped with something like an error boundary, while every other widget keeps updating normally. A dashboard where one broken widget takes the whole page down is a design failure independent of whatever caused the original data-source problem.
Independent widget re-rendering as a state-architecture concern. This connects directly to the earlier state-architecture lesson: if all widgets' data lives in one shared store object, an update to one widget's data can trigger every widget to re-render, even the ones whose data didn't change. Scoping each widget's state independently — or using selective subscriptions if a shared store is used — is what keeps a fast-updating widget from causing wasted re-renders across the whole page.
See it in a real thing: an operations dashboard with five widgets
Live order count (updates every few seconds), server error rate (updates every few seconds), today's revenue (updates every minute), a weekly trend chart (updates hourly), and a system-status widget (updates on any status change, rare). A strong design fetches each on its own cadence — the fast widgets don't wait on the slow ones, and the slow ones aren't over-fetched. If the error-rate widget's data source goes down, it shows "unavailable" in its own card while order count, revenue, and the trend chart keep updating normally, because each is wrapped in its own failure boundary. And each widget's state is scoped so that the order count updating every few seconds doesn't cause the weekly trend chart — which hasn't actually changed — to re-render along with it.
What people usually miss
Watch out
Sharing a transport (one WebSocket connection) is a reasonable optimization; sharing an update cadence across all widgets is usually a mistake. These are two different decisions, and conflating them is the most common wrong turn on this prompt.
A dashboard's resilience story isn't abstract here — it's the concrete, canonical example of why per-unit error boundaries matter. Naming that connection explicitly, rather than treating resilience as a separate unrelated topic, is a stronger answer.
Putting every widget's data in one shared object is a natural first instinct that causes real, needless re-renders. The state-architecture lesson's local-vs-shared-vs-server classification applies per widget here, not once for the whole dashboard.
Not every widget needs to be "real-time" in the same sense. A weekly trend chart updating hourly is not meaningfully less real-time than one updating every second, given what it actually displays — matching update frequency to what the data represents is part of the design, not a compromise.
Why this matters in interviews
"Design a dashboard with several widgets" tests whether a candidate defaults to one unified system or correctly recognizes several smaller, independently-scoped problems sharing a page — the strongest answers explicitly separate fetching cadence, failure containment, and re-render scope per widget.