•CASE STUDY

Personal Finance Dashboard from Multiple Providers

4 min read·603 words·Intermediate

Asked at

1 candidate report in Feb 2026

How to use this case study

SDE-2 / Mid

  • Explain connecting to banks
  • Brokers and crypto exchanges through adapters
  • Storing normalized data
  • Showing balances and portfolio value

SDE-3 / Senior

  • Go deeper on refresh scheduling within provider rate limits
  • Staleness indicators
  • Derived metrics
  • Handling provider outages
  • Secure token storage

Staff / Principal

  • Discuss data correctness (different update frequencies, currencies)
  • Scaling to millions of users
  • Privacy and compliance

Problem RestatementProblem

Amazon asked: design a financial dashboard that shows a user's bank account balances, stock holdings, cryptocurrency holdings, and derived portfolio metrics (total net worth, allocation by asset type, daily change). Data comes from multiple external providers (banks via aggregators like Plaid, brokers, crypto exchanges, price feeds), each with different formats, update frequencies, rate limits and reliability.

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["User"] --> API["Dashboard API"]
    API --> DB[("Normalized holdings + balances")]
    API --> DER["Derived metrics service"]
    DER --> PR[("Price cache - stocks, crypto, FX")]
    SCH["Refresh scheduler"] --> AD["Provider adapters"]
    AD --> P1["Bank aggregator"]
    AD --> P2["Broker API"]
    AD --> P3["Crypto exchange API"]
    AD --> DB
    PF["Market price feeds"] --> PR
    VAULT[("Token vault - encrypted credentials")] --> AD

Deep Dive — Keeping a portfolio value freshDeep dive

The dashboard shows total net worth across banks, brokerages and crypto exchanges. What counts as "fresh" is different for each part of that number.

Weak

Store the value each provider reports

Fetch the portfolio value from each provider and add them up.

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
  P1["Brokerage - portfolio value at 09:31"] --> SUM["Total stored"]
  P2["Exchange - value at 09:28"] --> SUM
  SUM --> SHOW["Dashboard shows a stale total all day"]
  REF["To update, re-fetch every provider"] --> RL["Provider rate limits - refreshes are expensive and slow"]
  RL --> MIX["Different parts of the total are from different times"]

The total is a mixture of values captured at different moments, and the only way to refresh any of it is a provider call — so freshness is bounded by the slowest, most rate-limited integration.

Good

Refresh from providers more often

Poll each connection on a schedule and after user activity.

Values get fresher and the cost scales badly: each user's each connection is a metered API call, and crypto prices move by the second regardless of how often you poll. Aggressive polling hits provider limits and still shows stale prices between refreshes.

Best

Separate what changes rarely from what changes constantly

A holding is a quantity; its value is that quantity times a price. Those two facts have completely different refresh needs:

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
  PROV["Provider adapters"] --> QTY[("Quantities - 12 AAPL, 0.4 BTC, balances")]
  QTY --> NOTE["Change only when the user trades - refresh per connection, on a schedule"]
  FEED["One market price feed - shared by all users"] --> PX[("Price cache")]
  PX --> LIVE["Prices update continuously, for everyone at once"]
  QTY --> CALC["value = quantity x latest price"]
  PX --> CALC
  CALC --> DASH["Total updates live without touching any provider"]
  • One price feed serves every user. AAPL's price is not per-user data, so fetching it per connection is the mistake that makes the whole design expensive. One feed, cached, and every portfolio revalues for free.
  • Quantities are refreshed per connection, on a schedule and when the user opens the app — because they only change when someone trades or transfers.
  • Bank balances are the exception: they are a value, not a quantity times a price, so they follow the connection's refresh cadence and should be shown with an as_of timestamp.

Label every number with what it is as-of. A dashboard that silently mixes a live crypto price with a bank balance from four hours ago is not wrong, but it is misleading unless it says so — and once the timestamps are visible, the refresh strategy stops being something users have to guess at.

Reliability and Security

  • Provider outages: circuit breakers per provider, retries with backoff, and "reconnect required" states when tokens expire (the user must re-authorize).
  • Security: provider credentials and OAuth tokens are encrypted in a vault (never in logs), with read-only scopes where possible. MFA for the app, and encryption at rest.
  • Idempotent upserts of balances and holdings keyed by (user, provider, account/asset), with events for changes (alerts like "large deposit").

ScaleScale

  • Millions of users × several connections each. The refresh workload is the main cost, so prioritize active users, lower the frequency for inactive ones, and use provider webhooks where offered (push instead of poll).
  • Price computations are shared: 10K distinct assets priced once, then applied to millions of holdings.

Wrap-UpWrap-up

Connect each provider through an adapter that normalizes accounts and holdings into one model, refreshed by a rate-limited, jittered scheduler (and on app open) with secrets kept in a vault. Keep quantities per user but prices in a shared market cache, compute net worth, allocation and daily change with FX conversion, and snapshot daily history. Always show "as of" freshness and last-known values with warnings when providers fail.

More Case Studies

Frequently Asked Questions

What is the Personal Finance Dashboard from Multiple Providers system design question?

Personal Finance Dashboard from Multiple Providers is a system design interview question asked at FAANG companies. It covers fintech, api design, caching, data pipelines 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 Personal Finance Dashboard from Multiple Providers question?

Amazon 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 Personal Finance Dashboard from Multiple Providers 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 Personal Finance Dashboard from Multiple Providers 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 →