Revolut System Design interview
This blog breaks down how to ace Revolut’s System Design interview by designing around a correctness-first ledger, safe retries, FX and card workflows, and reconciliation when external payment truth arrives late.
Revolut’s system design interview tests whether you can keep a financial system provably correct when the real world misbehaves, from duplicate card network messages and FX rate swings to partner timeouts and late settlement files. Unlike general distributed systems interviews, the focus is on ledger-centric architecture, where money movement is modeled as a state machine backed by append-only, double-entry journal entries, with explicit invariants, idempotency boundaries, and reconciliation loops that survive retries, partitions, and delayed external truth.
Key takeaways
- Ledger as source of truth: Every balance is derived from immutable, append-only journal entries rather than stored as a mutable number in a database row.
- Invariants before microservices: A strong answer states double-entry correctness rules and idempotency boundaries before drawing boxes and arrows.
- Failure behavior is a primary output: The interview rewards candidates who walk through retry storms, FX volatility, and partner delays as deterministic design narratives, not afterthoughts.
- Operational state vs. financial state: Separating what you attempted from what is financially posted lets the system stay honest with users while reconciling against late external truth.
- Regulatory constraints shape architecture: Data residency rules, PCI-DSS, and GDPR compliance are not footnotes. They change where data lives, how long it is retained, and who can access it.
Most system design interviews reward you for making something fast. Revolut’s interview rewards you for making something correct when every external dependency is lying to you, running late, or sending duplicates. If you have ever designed a service where “it worked in prod” was good enough, that mental model will fail you here. The money must be right, the audit trail must be defensible, and the business must be able to reconcile against external rails weeks after a transaction clears.
This guide walks through the full arc of a Revolut-style system design answer: from clarifying requirements like a financial engineer, through ledger modeling and architecture, to the failure-mode reasoning and reconciliation workflows that separate strong candidates from generic ones.
Why Revolut system design questions feel different#
A typical big-tech prompt asks you to design a URL shortener or a chat system. A typical Revolut prompt asks you to design a multi-currency ledger with card payments. The words sound similar, but the evaluation criteria diverge sharply.
Revolut interviewers are listening for whether you naturally reach for the constraints fintech engineers live with daily. Those constraints include idempotency boundaries across payment rails, audit trails that must be defensible years later, and reconciliation strategies for when external settlement is delayed or disputed. Speed matters, but correctness is non-negotiable.
Real-world context: Card networks like Visa and Mastercard routinely deliver duplicate authorization messages, send settlement files hours or days after capture, and occasionally reverse transactions via chargebacks weeks later. Your system must handle all of this without manual intervention on the happy path.
The interview is “finance-first distributed systems.” You treat partners as unreliable and late. You make correctness legible through invariants, state transitions, and auditable entries. If you only talk about throughput and horizontal scaling, you will sound like you are solving the wrong problem.
The following diagram illustrates how a Revolut-style system design prompt maps to deeper evaluation dimensions that go far beyond typical scalability questions.
Understanding this difference is the first step. The next is learning how to open the interview by surfacing the requirements that actually change your architecture.
Clarify requirements like a financial engineer#
Your opening minutes set the tone. A strong candidate does not rattle off a checklist of generic questions. Instead, they surface requirements that materially change the data model, consistency boundaries, and failure behavior of the system.
Tie every question to a Revolut workflow. Instead of “what’s the expected QPS?”, ask questions like these:
- Auth vs. capture: “Is this a card authorization placing a temporary hold, or a capture posting a final charge?”
- FX rate binding: “Is the FX rate locked at quote time or at posting time?”
- Data residency: “Do we need to enforce data residency boundaries per regulatory zone, for example keeping EU user data in EU regions?”
- Reconciliation lag: “What’s the allowed reconciliation lag with external settlement files from the card network?”
A powerful opening move is a short story, not a question list: “If we time out after posting to the ledger but before responding to the client, how do we prevent a second debit on retry?” This immediately signals that you think about distributed failure, not just happy-path throughput.
Pro tip: Frame requirements in terms of what is strongly consistent vs. what can be eventually consistent. Ledger postings demand strong consistency. Read projections like available balance or per-merchant spend can tolerate slight staleness. Making this distinction early shapes every architectural decision that follows.
You should also ask about reversibility. Some operations (like FX conversions) may be reversible within a window. Others (like settled card captures) require formal dispute and chargeback flows. Knowing which is which changes whether you model an operation as a simple rollback or as an explicit correction entry in the ledger.
With the requirements landscape established, you can anchor the design around the core workflows that Revolut systems implement repeatedly.
Identify the core Revolut workflows#
After requirements, ground the system in a few high-value workflows that recur across Revolut’s product surface. These typically include multi-currency balance management, card authorization and capture, FX quoting and conversion, fraud and risk decisioning, and compliance-grade auditability.
The happy path and where it breaks#
Pick one end-to-end flow and narrate both its success and its failure modes. Card payment is the canonical example:
- Authorization. A merchant sends an auth request. Your system checks available funds (a derived projection), runs a risk decision, and places a hold by posting an internal ledger entry that moves funds from “available” to “held.”
- Capture. Hours or days later, the merchant captures the charge. You post a final ledger entry that moves funds from “held” to “settled expense,” possibly with a separate fee posting and an FX conversion leg if currencies differ.
- Settlement. The card network sends a settlement file that may arrive later still and can disagree with the original capture amount.
- Dispute. The cardholder disputes the charge, triggering a chargeback flow that posts to a suspense account pending investigation.
Each step touches different services and has different correctness requirements. Authorization is latency-sensitive (card networks impose tight timeouts, often under 2 seconds). Settlement is batch-oriented and tolerant of delay. Disputes are human-in-the-loop with legal implications.
Attention: Do not conflate operational steps with financial posting. Sending a “200 OK” to the card network is an operational acknowledgment. Posting a debit to the ledger is a financial fact. These are separate concerns with separate failure modes, and conflating them is one of the most common mistakes in fintech system design interviews.
Use Revolut interview language naturally throughout: “ledger is source of truth,” “derived projections,” “risk gate,” “idempotency boundary,” “audit trail,” “multi-region failure isolation,” and “data residency.” These phrases signal domain fluency.
With the workflows identified, the next critical step is modeling the data that underpins them. In a Revolut interview, this is where answers are won or lost.
Define a robust and auditable data model#
Your data model is the foundation of every correctness argument you will make. The interviewer wants to see that you do not model balances as a mutable number in an accounts table. Revolut-grade systems treat balances as values derived from
Ledger primitives#
Start with the core entities:
- Accounts. Often multi-currency sub-accounts under a single user. Each account is identified by a stable ID and a currency code.
- Journal entries. Each entry represents a financial event (an exchange, a card capture, a fee) and contains one or more postings.
- Postings. Individual debit or credit lines within a journal entry. Every posting references an account, an amount, a currency, and a direction.
- References. Every posting ties back to an originating intent (card auth, transfer request, refund) and, where applicable, an external reference (card network ID, bank transfer reference).
From these primitives, you build derived projections: available balance, booked balance, per-merchant spend totals, risk feature aggregations, monthly statements, and compliance reports. The critical insight is that these projections are computed from the ledger, not stored alongside it as independent mutable state.
Real-world context: If you cannot reconstruct a user’s complete financial history from immutable events, you do not have a financial system. You have an API with a liability problem. Regulators and auditors expect full traceability, and Revolut’s internal tooling depends on it for dispute resolution and compliance reporting.
Model FX rates as snapshots, not as “current rate at read time.” Every posting that involves a currency conversion must reference a specific
The following diagram shows how ledger primitives relate to derived projections.
With the primitives defined, the next question is how to enforce correctness. That is where double-entry bookkeeping becomes your proof system.
Double-entry ledger modeling and the invariants Revolut cares about#
Double-entry is not a buzzword in these interviews. It is your correctness framework. The principle is simple: every financial movement has a counter-movement, so money never magically appears or disappears. In practice, this means every journal entry contains postings whose debits and credits sum to zero.
How double-entry maps to Revolut operations#
Consider the life cycle of a card payment for a EUR-based user spending in USD:
Transaction Processing – Double-Entry Accounting Operations
Operation | Debit Account | Credit Account | Notes |
Authorization Hold | Available EUR | Held EUR | Reserves funds at snapshot FX rate |
Capture | Held EUR | Settled Expense EUR | Posts final amount, may include FX adjustment |
Fee Posting | User Fee Account | Revolut Revenue | Separate entry for transparency |
Refund | Settled Expense EUR | Available EUR | Reversal of prior capture |
Chargeback | Dispute Suspense | Settled Expense EUR | Pending investigation, funds held in suspense |
The key invariant: for every journal entry, $\\sum \\text{debits} = \\sum \\text{credits}$. This must be enforced at write time through database constraints or application-level validation, not discovered later by an offline repair job.
Pro tip: Prefer correction entries over overwrites. If a capture amount differs from the original authorization hold, do not update the hold entry. Instead, post a new adjustment entry that accounts for the difference. This preserves the full audit trail and makes the ledger defensible under regulatory scrutiny.
What interviewers listen for is specificity. Do not just say “we use double-entry.” State the invariant, explain how you enforce it (unique constraints, transactional writes, application-level checks), and show how correction entries handle real-world deviations. This is the difference between a textbook answer and an engineering answer.
The invariants you define here become the contract that every other component in the architecture must respect. Next, we will build the architecture outward from the ledger.
Propose a secure, scalable Revolut-style architecture#
A strong architecture answer starts with the ledger write path and builds outward. You want to demonstrate two distinct paths through the system: a “thin” decision path optimized for real-time latency (especially for card authorizations) and a “thick” posting and audit path optimized for correctness and completeness.
The canonical flow#
The typical request life cycle looks like this:
- API gateway. Handles authentication, rate limiting, and routing.
- Domain service. Cards, transfers, or FX, depending on the operation.
- Risk gate. A synchronous or near-synchronous check that can approve, decline, or flag for manual review.
- Intent creation. The system persists a durable intent record with an idempotency key before any financial side effect occurs.
- Ledger posting. The double-entry journal entry is committed atomically.
- Event emission. A domain event is published (e.g., to Apache Kafka) for downstream consumers.
- Derived projections. Read-optimized stores (available balance, spend analytics, statements) are updated asynchronously from the event stream.
Partners and external rails integrate through dedicated adapter services. Every external message is treated as untrusted input that must pass idempotency validation and schema checks before affecting internal state.
Attention: A common architectural mistake is placing the risk gate after ledger posting. In most Revolut workflows, risk decisions should occur before the financial fact is recorded. However, some compliance checks (like sanctions screening) may run asynchronously after posting, with the ability to trigger a reversal. Be explicit about which checks are synchronous gates and which are asynchronous reviewers.
Say this out loud during the interview: “The ledger is the source of truth. Everything else is a projection or an integration boundary.” This single sentence communicates architectural clarity.
Consistency and storage trade-offs#
The choice of storage technology reflects the consistency requirements of each component.
Financial System Components: Consistency, Technology, and Trade-offs
Component | Consistency Requirement | Typical Technology | Trade-off |
Ledger | Strong consistency / ACID | PostgreSQL or CockroachDB | Higher write latency but guarantees correctness |
Intent Store | Strong consistency | Same RDBMS as ledger or co-located | Must survive crashes to prevent double-posting |
Balance Projection | Eventual consistency | Redis or materialized view | Fast reads but may be slightly stale |
Event Bus | At-least-once delivery | Kafka | Consumers must be idempotent |
Settlement Reconciliation | Batch processing | S3 + processing pipeline | Tolerates hours of delay |
This is where formal distributed systems concepts enter the picture. The
For systems that span multiple services or regions, you may need a
Historical note: The saga pattern was originally described by Hector Garcia-Molina and Kenneth Salem in 1987 as an alternative to long-lived distributed transactions. It has become the dominant pattern in microservices architectures where holding distributed locks is impractical, and it is especially well-suited to financial systems where every compensation must be auditable.
With the architecture in place, the real test begins: reasoning about what happens when things go wrong. Revolut interviewers spend significant time probing failure modes, and your answers here are what separate a solid candidate from a strong one.
Address real-world fintech complexity with failure-mode reasoning#
This is where you move from “design” to “engineering.” Revolut interviewers often ask “what happens when…” because the system’s behavior under failure is the real test. You should proactively walk through failure stories and narrate the system’s decisions, invariants, and recovery paths.
Your north star is simple: no silent financial corruption. The best candidates do not promise zero failures. They promise that every failure produces a deterministic outcome or an explicit correction entry with an audit trail. They show the mechanisms that make this promise enforceable.
Failure story 1: duplicate submissions and partial failures#
A user taps “Exchange 500 EUR to USD” and the app sends POST /fx/execute. The request passes authentication, and the FX domain service creates an intent with an
Now the network drops the response after the ledger commit but before the client receives it. The client retries. Without rigorous design, you risk a second posting and a duplicated exchange.
In a Revolut-grade design, the retry hits the API and maps to the same idempotency record. The system does not re-run the exchange. It fetches the already-created intent outcome and ledger reference, then returns the same result deterministically.
What to say in the interview: “If the ledger commit succeeded, retries must return the same outcome without re-posting. That is an idempotency boundary backed by unique constraints on the business reference.”
Pro tip: Enforce deduplication at the ledger level, not only at the API gateway. If an API gateway restarts and loses its in-memory dedup cache, the ledger’s unique constraint on business_ref is your last line of defense against double-posting.
Failure story 2: FX rate volatility mid-transaction#
Consider a card purchase in USD for a customer whose base balance is in EUR. The authorization arrives at time T with amount USD 100. You need to reserve the EUR equivalent, but the FX rate at authorization may differ from the rate at capture (hours or days later), and the capture can be for a different amount than the auth.
A strong design makes the policy explicit:
- Option A: Lock an FX rate snapshot at authorization for the hold. At capture, post the final amount using the original snapshot if within policy, or a new snapshot with a transparent adjustment entry if outside policy.
- Option B: Hold in the transaction currency (USD) if the account supports it, and do conversion at capture or settlement.
Either way, you never “look up the current rate” at arbitrary points. You bind postings to a stored snapshot so the ledger can explain itself. If amounts change between auth and capture, you post explicit adjustment entries rather than silently recalculating.
Interview language that lands well: “FX conversion is a two-leg posting using a stored rate snapshot. If the rate or amount changes, we post adjustments explicitly rather than hiding them in a recalculated balance.”
Failure story 3: partner delays and late confirmations#
Card networks and bank rails do not always confirm quickly. You might authorize successfully, then wait hours for capture or clearing. For transfers, you might submit to a partner and get an ACK, but final confirmation arrives via batch files or delayed webhooks. If you treat “ACK received” as “money moved,” you create a reconciliation nightmare.
A Revolut-ready design splits
Real-world context: In the UK Faster Payments scheme, a payment can be submitted and acknowledged within seconds, but the final confirmation or rejection may arrive minutes later. In SEPA credit transfers, settlement can take a full business day. Your system must handle both without corrupting state or confusing users.
A reliable mental model: “External truth arrives late. The ledger records our best-known facts now, plus the mechanisms to correct later.”
These failure stories illustrate principles, but the mechanisms that prevent corruption deserve their own focused treatment. The most critical of these is idempotency across payment rails.
Idempotency, retries, and deduplication across external payment rails#
In fintech, retries are not a corner case. They are the default behavior of clients, networks, and partners. Your job is to define idempotency boundaries and enforce them consistently from the API layer down to the ledger and out to partner webhooks.
A good answer states three things clearly:
- Where idempotency is guaranteed. You can guarantee idempotent ledger posting for a given business reference through unique database constraints.
- Where it cannot be guaranteed. You cannot guarantee a card network will not send a duplicate notification. You cannot guarantee a bank will not send the same settlement line twice.
- How you contain damage. You make every consumer dedupe-safe. External callbacks map to the same internal reference through deterministic matching rules.
Attention: If you say “we will make it exactly-once,” expect pushback. Exactly-once delivery is impossible in distributed systems without strong coordination. If you say “we design idempotency at each boundary and make consumers dedupe-safe,” you will sound senior.
A retry-storm scenario#
A “retry storm” is when one slow dependency triggers exponential retries across layers. Consider this cascade:
- A card network sends authorization requests. Your edge is healthy, but the risk service is slow due to a feature-store issue. Auth processing time creeps up.
- The card network times out (their timeout is often 2 seconds or less). They retry the same auth with the same network identifiers.
- Your API layer has also retried internally to the risk gate. Now you have duplicates from outside and duplicates within.
- Some requests reach ledger posting, some time out before response, some get declined by risk-gate fallback. Without dedup, you might place multiple holds on the same card auth.
The resolution requires several coordinated mechanisms:
- Cap retries at each layer with
and jitter.exponential backoff A retry strategy where the delay between successive attempts increases exponentially (e.g., 1s, 2s, 4s, 8s), often with jitter, to avoid thundering-herd effects when many clients retry simultaneously. - Shift to lookup-by-idempotency rather than re-execute once an intent exists.
- Apply backpressure from the risk service to the API layer, signaling “slow down” rather than accepting requests it cannot process in time.
- Force deterministic behavior: same request maps to same outcome, always.
Define idempotency keys per boundary. The client sends its own key. The server generates a business reference. The partner uses its network identifier. Do not reuse one key everywhere blindly, because different boundaries have different dedup semantics.
With idempotency covered, the next question is what happens when external truth finally arrives and disagrees with what you assumed. That is the domain of reconciliation.
Reconciliation, settlements, and disputes#
Reconciliation is where “distributed systems” meets “accounting reality.” External rails often finalize financial truth on their own schedule: card settlement files, bank transfer confirmations, partner adjustments, and chargebacks. Your system must behave correctly when the final truth arrives late and sometimes contradicts earlier assumptions.
Deterministic matching, not a cron job#
You reconcile by treating the ledger as your source of truth and external rails as external truth sources. The mapping between them is an engineering problem, not a background task someone bolts on later. You need:
- Stable identifiers. Every ledger posting carries an external reference (card network ID, bank transfer reference) that can be matched to incoming settlement records.
- Inboxing. External messages (settlement files, webhooks, batch confirmations) are ingested into a durable inbox and processed idempotently.
- Deterministic matching rules. Each incoming external record is matched to a ledger posting by reference. Matches confirm the posting. Mismatches generate adjustment entries and route exceptions to ops tooling.
When a settlement file says the capture was $99.50 but your ledger posted $100.00, you do not edit the original entry. You post an explicit adjustment of $0.50 and flag it for review. When a chargeback arrives, you post to a dispute suspense account and begin investigation workflows.
Real-world context: Visa’s Transaction Control (TC) files and Mastercard’s IPM clearing files arrive in batch, typically once or twice per day. Each file contains thousands of records that must be matched against your ledger. A single unmatched record can block settlement for an entire batch if your matching logic is not robust.
Operational state vs. financial state#
The following table captures a distinction that interviewers love to see candidates articulate explicitly.
Operational State vs. Financial State in Payment Processing
Dimension | Operational State | Financial State |
What it Tracks | What we attempted and what partners reported | What the ledger has posted as final fact |
Mutability | Updated as partner responses arrive | Append-only; corrections made via new entries |
Source of Truth For | User-facing status, customer support tooling | Audit, compliance, reconciliation, regulatory reporting |
Example | Card auth status: submitted, approved, timed-out, declined | Hold entry posted, capture entry posted, adjustment entry posted |
Failure Behavior | May show 'pending' for extended periods | Must never show a balance that contradicts the ledger |
The phrase to use: “Operational state drives user experience. The ledger drives financial truth and auditability.”
Reconciliation ties together everything discussed so far: idempotent processing, append-only corrections, deterministic matching, and separation of operational from financial state. But all of these mechanisms exist within a regulatory context that shapes the architecture in fundamental ways.
Regulatory compliance as an architectural constraint#
Competitors in this space emphasize something worth making explicit: regulations like PCI-DSS, GDPR, and financial audit standards are not compliance checkboxes bolted on after the design. They are architectural constraints that influence where data lives, how long it is retained, who can access it, and how it moves between jurisdictions.
Key design implications include:
- Data residency. GDPR and local banking regulations may require that EU user data stays in EU regions. This affects database placement, replication topology, and cross-region query patterns.
- PCI-DSS. Card data (PANs, CVVs) must be isolated in a dedicated, heavily audited environment with strict access controls. Your ledger should reference tokenized card identifiers, never raw card numbers.
- Retention and right to erasure. Financial records must be retained for years (often 5–7 years depending on jurisdiction). But GDPR grants users a right to erasure of personal data. The resolution is to separate personal identifiers from financial records, allowing pseudonymization without destroying the audit trail.
- Sanctions and watchlist screening. Some jurisdictions require real-time screening against sanctions lists. This can be a synchronous gate (blocking the transaction) or an asynchronous review (flagging for investigation after posting, with the ability to freeze and reverse).
Pro tip: When the interviewer asks about compliance, do not list regulations like a checklist. Instead, show how a specific regulation changes a specific design decision. For example: “GDPR data residency means we partition the ledger by regulatory zone and route queries through region-aware gateways, which adds latency for cross-region operations but ensures we never move protected data outside its jurisdiction.”
Compliance constraints also shape observability requirements. Auditors need to see who accessed what data, when, and why. This means your system needs comprehensive access logging, not just application metrics.
Speaking of observability, the ability to monitor, alert, and introspect the system under failure is a dimension that separates production-ready designs from whiteboard sketches.
Observability, monitoring, and operational tooling#
Revolut interviewers appreciate candidates who think about how humans will operate the system, not just how machines will run it. A system that is correct but opaque is nearly as dangerous as one that is incorrect, because you cannot detect or respond to anomalies.
Your design should include:
- Metrics. Ledger posting latency, reconciliation match rate, idempotency-hit ratio, risk-gate decision latency, and partner response times.
- Alerts. Thresholds on reconciliation mismatch rates, ledger write failures, partner timeout spikes, and balance-projection drift (the gap between projected and ledger-derived balances).
- Tracing. Distributed tracing (e.g., via OpenTelemetry) that follows a transaction from API entry through risk gate, ledger posting, event emission, and partner adapter.
- Operational tooling. Internal dashboards for customer support (showing both operational state and financial state), reconciliation exception queues, manual review workflows for flagged transactions, and the ability to replay events for debugging.
Historical note: The concept ofwas borrowed from control theory by the software industry. In control theory, a system is observable if you can determine its internal state from its outputs. In distributed fintech systems, this translates to being able to reconstruct exactly what happened to a transaction from logs, metrics, and traces alone, without needing to query production databases or guess. observability The ability to infer the internal state of a system from its external outputs, typically through logs, metrics, and traces, originating from control theory and now a core principle in distributed systems operations.
A strong interview mention: “I would instrument the reconciliation pipeline to emit a match-rate metric. If the match rate drops below 99.5%, we page on-call because it likely indicates a partner-side schema change or a bug in our matching logic.”
With observability covered, let us see how all of these concepts come together in a concrete example prompt.
Example prompt: design a real-time multi-currency ledger for Revolut accounts#
This is the kind of prompt you might actually hear. Here is how to structure your answer using everything we have discussed.
Opening narration#
“A user holds EUR and USD balances. They want to exchange EUR to USD and then spend on a card in GBP. I will place the ledger at the center, build projections for reads, and put risk gates before posting.”
Core flows#
FX execute. The user requests an exchange. The system creates an intent with an idempotency key, stores an FX rate snapshot, and posts a journal entry with two legs (debit EUR, credit USD) plus a fee posting. The available-balance projection is updated asynchronously from the ledger event.
Card authorization. The user taps their card at a GBP merchant. The card domain service checks available USD balance (from the projection), runs the risk gate, and posts a hold entry. The hold uses a stored FX snapshot for the USD-to-GBP conversion. Authorization response goes back to the network within 2 seconds.
Capture. Hours later, the merchant captures. The system posts final entries, possibly with an FX adjustment if the rate or amount changed. Settlement reconciliation is scheduled when the network file arrives.
Dispute. The user disputes the charge. A chargeback entry is posted to a dispute suspense account. The operational state changes to “under investigation.” If the dispute is won, a credit is posted. If lost, the suspense entry is reversed.
If you only talk about services and APIs, you will sound generic. If you talk about posting rules, idempotency boundaries, FX snapshots, and reconciliation pipelines, you will sound like a Revolut engineer.
Variations by seniority level#
Expectations differ by role level, and acknowledging this can help you calibrate your answer depth.
Mid-level vs. Senior Engineer Comparison
Aspect | Mid-level Engineer | Senior Engineer |
Scope | Focus on one or two core flows end-to-end | Cover multiple interacting flows plus cross-cutting concerns |
Failure Reasoning | Identify key failure modes and describe recovery | Proactively walk through cascading failures, retry storms, and reconciliation edge cases |
Invariants | State the primary double-entry invariant | Define invariants per boundary, explain enforcement mechanisms, and discuss violations |
Compliance | Mention regulatory requirements when asked | Proactively identify regulatory constraints and show how they shape architecture |
Operational Maturity | Mention monitoring and alerting | Describe specific metrics, SLAs, runbooks, and operational tooling for exception handling |
With the full example covered, let us distill what a strong candidate answer sounds like in summary.
What a strong candidate answer sounds like#
You want your answer to sound like you have operated systems like this: crisp invariants, explicit boundaries, and specific failure behavior. Avoid vague claims (“we will ensure consistency”) and replace them with enforceable mechanisms (“unique constraint on business_ref prevents double-posting”).
Here is a model closing statement:
“I will treat the ledger as the source of truth with append-only journal entries and double-entry validation. All reads come from derived projections that can be rebuilt. I will define idempotency boundaries at the API, intent, ledger, and partner layers, and I will model operational state separately from financial state because settlement arrives late. Failures should never cause silent financial corruption. They should produce deterministic outcomes or explicit correction entries with audit trails.”
This statement is powerful because it is falsifiable. Every claim can be checked against the design. It names specific mechanisms (append-only entries, unique constraints, idempotency layers, correction entries) rather than aspirational adjectives.
Real-world context: Revolut processes tens of millions of transactions per month across dozens of countries and multiple currencies. The engineering culture values deterministic behavior and auditability. When you speak in the interview, imagine a production incident where your design is being tested. If your words would help the on-call engineer understand what should happen, you are saying the right things.
Conclusion#
The Revolut system design interview is fundamentally about proving that your system stays financially correct when the world misbehaves. The two ideas that matter most are placing the append-only ledger at the center of everything and treating failure behavior as a primary design output with deterministic outcomes, not a footnote. Every other concept we covered, from double-entry invariants and FX rate snapshots to idempotency boundaries, saga-based compensation, reconciliation pipelines, and regulatory constraints, exists in service of that core commitment to correctness under adversity.
Looking ahead, the fintech system design space is evolving toward real-time settlement rails (like the EU’s push toward instant SEPA settlement) and programmable compliance through embedded regulatory engines. Candidates who can reason about reducing reconciliation lag from days to seconds, while maintaining the same correctness guarantees, will be increasingly valuable.
Treat the interview as a production design review narrated aloud. Put the ledger at the center, speak in invariants, show how your design behaves when partners lie and networks fail, and make every failure survivable and auditable. That is the story that stands out.