Problem statement
Design the system that generates monthly account statements for every customer of a digital bank. For each account it gathers the period's transactions, computes opening and closing balances and summaries, renders a PDF (and machine-readable copy), stores it durably, and notifies the customer that it is ready. Statements are legal financial documents, so a statement, once issued, must be exact, reproducible, and never silently changed.
Operating context. The batch runs on each account's statement cycle date; cycles are staggered across the month but a single day can still fall due for tens of millions of accounts. Input is the immutable ledger for the period. Rendering is CPU-heavy and storage is large. Assume 50 million accounts, a peak day of 5 million statements, and a requirement that every eligible account gets exactly one statement per cycle, on time.
Out of scope. The ledger's correctness, tax or regulatory report generation, the email/push delivery infrastructure beyond enqueuing a notification, and the in-app viewer. Assume separate teams own ledger, notifications, and the customer app.
What to produce. A high-level architecture covering: how the batch is triggered and how work is divided into parallel units, gathering the period's data as a stable snapshot, the render-and-store pipeline, guaranteeing exactly-one statement per account per cycle under retries and worker failure, idempotent regeneration when a bug is fixed, storage and retrieval at scale, and how you meet the deadline on a peak day. Sketch the stages and dataflow; we will probe specifics in checkpoints.
Functional requirements
- Determine the set of accounts due on a given cycle date and enqueue a statement job for each.
- Gather the period's transactions and opening/closing balances from the ledger as a stable, point-in-time snapshot.
- Render each statement to an archival PDF plus a machine-readable copy and store both durably.
- Guarantee exactly one issued statement per account per cycle, even under retries and worker crashes.
- Enqueue a customer notification once a statement is successfully stored and mark the job complete.
Non-functional requirements
- Generate up to 5 million statements on a peak day and finish within an 8-hour batch window.
- Rendering throughput of at least 200 statements/sec per worker pool, horizontally scalable.
- 99.9% of due statements issued within the cycle-day SLA; no eligible account is skipped.
- Issued statements are immutable and reproducible: regenerating yields a byte-identical document.
- Store statements for 7 years, tens of petabytes, with retrieval p99 < 2 s for recent, < 30 s for archived.
- A failed or partially rendered job never leaves a customer-visible or duplicate statement.
Topics
- System Design HLD
- Fintech Statements
- Data Batch
- Scaling Throughput
- Patterns Idempotency