Disclaimer. This article is based entirely on Revolut's public communications — their engineering blog, conference talks, job postings, annual reports, and external case studies. It is not an official Revolut architecture document. We model what we know publicly to illustrate how a complex stack can be made legible with the C4 model. Where details are inferred rather than stated by Revolut, we say so.
Anatomy of a Transfer: Modeling Revolut in C4 with Archyl
It's 19:47 on a Friday in Paris. Léa opens Revolut, types £450, picks her London landlord from her contacts, and taps Send. Her euros are converted to pounds at the interbank rate, screened for fraud and sanctions, written to an immutable ledger, and pushed onto the UK's Faster Payments rail. The landlord's high-street bank credits the money before Léa has put her phone back in her pocket.
That three-second journey crosses a mobile app, an API edge, a transfer orchestrator, an FX engine, a financial-crime pipeline with a sub-50-millisecond budget, an event store, and an external national payment network — all operated by a company that didn't exist eleven years ago.
Revolut by the numbers
| Customers | 70+ million (May 2026), up from 50M in Nov 2024 |
| 2025 revenue | $6 billion (+46% YoY), $2.3B profit before tax |
| Transaction volume | £1.3 trillion in 2025 (+65% YoY) |
| Valuation | $75 billion |
| Footprint | 40+ countries — 13M customers in the UK, 6M in Spain, 5M in France |
| Fraud losses | ~1¢ per $100 processed, vs. an industry average of 7–8¢ |
| Core stack | Java 17/21 & Kotlin, PostgreSQL, GCP, Kubernetes — and famously no Kafka |
How do you understand a stack that moves £1.3 trillion a year? The same way we approached Stripe, Netflix and Uber in this series: you don't — not all at once. You follow one user action across the four C4 levels, write the ADRs that explain the decisions you meet along the way, and end with a map of who owns each box.
Léa's £450 is our thread.
Level 1 — System Context: a bank, a broker, an exchange, and an app store

At the System Context level, Revolut is not "a banking app". Public communications describe at least eight product systems sharing one foundation:
- Retail Banking — multi-currency accounts, cards, transfers: the historical core
- Business Banking — accounts, corporate cards, and a merchant acquiring arm with its own payment gateway
- FX & Multi-currency — the exchange engine that made Revolut famous, interbank rates across 30+ currencies
- Wealth & Trading — stocks, ETFs, commodities, crypto
- Credit — personal loans, credit cards, pay-later products by market
- FinCrime — fraud scoring (Sherlock), AML, sanctions screening, scam detection
- Onboarding & KYC — document verification, liveness checks, risk-rating at signup
- Core Ledger & Event Backbone — the source of truth every product writes to
Around them: card networks (Visa, Mastercard), payment rails (UK Faster Payments, SEPA and SEPA Instant, SWIFT for the long tail), partner and correspondent banks, regulators (the PRA and FCA in the UK — Revolut received its full UK banking licence in March 2026 after the restricted licence of July 2024; the ECB and Bank of Lithuania in the EU), market-data and brokerage partners for Wealth, and Google Cloud as the underlying infrastructure.
Eight systems, six categories of external actors. Everything else is detail.
Note what Level 1 already tells you that no org chart does: FinCrime is a system, not a feature. It sits on the critical path of every product — retail transfers, card payments, crypto withdrawals, business payouts. When a company draws its context diagram and one box has arrows from everywhere, that box is either the crown jewel or the bottleneck. At Revolut it's both, and they staffed it accordingly.
ADR-001 · An event-driven backbone — without Kafka
Status · Accepted (~2017, still active in 2026)
Context · Revolut's backend is hundreds of independent microservices that coordinate by exchanging events. The industry-default answer in 2017 (and arguably today) was Apache Kafka. But Kafka brings a heavy operational surface: brokers, partitions, rebalancing, retention tuning — a full-time platform concern. Revolut's engineering culture favors small teams owning simple, queryable primitives.
Decision · Don't adopt Kafka. Persist events in a single event store built on PostgreSQL, and build the streaming and messaging layer in-house — written in Kotlin on JetBrains Ktor, using coroutines for high-concurrency event delivery. Consumers like Risk, PnL and fraud detection read from the store, with read replicas absorbing query load.
Consequences · The event backbone is maintainable by a small team, and — crucially — queryable with SQL. Debugging a payment isn't spelunking through partitioned logs; it's a SELECT. The trade-off is real: Revolut owns the availability, ordering and delivery semantics that Kafka would have given them off the shelf. This is a decision that only stays correct while the team that owns the platform stays excellent.
In Archyl, this ADR links to the Core Ledger & Event Backbone system and to every container that publishes to it. Whoever asks "why is there no Kafka in this diagram?" — and every senior hire asks — gets the answer in one click.
The three seconds, on a timeline
Before zooming into Level 2, here's Léa's transfer as a timeline. (Latency figures are illustrative orders of magnitude, not Revolut-published numbers.)
| t | What happens | Where |
|---|---|---|
| 0 ms | Léa taps Send | Mobile app |
| ~10 ms | Session validated, request authenticated and parsed | API edge |
| ~30 ms | Balance check and funds reservation, transactionally | Transfer orchestrator + Ledger (PostgreSQL) |
| ~50 ms | EUR→GBP quoted at interbank rate | FX engine |
| ~100 ms | Sanctions screening + fraud/scam scoring — the sub-50 ms budget | FinCrime pipeline |
| ~150 ms | TransferInitiated appended to the event store; Risk, PnL, notifications and analytics consume it |
Event backbone |
| ~200 ms | Payment submitted to Faster Payments | FPS rail connector |
| ~2–3 s | Receiving bank confirms; ledger finalizes; push notification fires | Rails + Ledger + Notifications |
Eight hops, three of them irreversible side effects (reserve funds, submit to rail, finalize ledger). Keep that structure in mind — it's exactly what the Container level needs to make visible.
Level 2 — Container: zoom into the transfer path

Open the Retail Banking box and follow the £450. Public sources — engineering posts, talks, and a decade of job specs — let us name the containers on the path:
- Mobile apps — iOS and Android, the only user interface that matters; there is no meaningful web banking surface
- API edge — the front door on GCP, terminating auth and routing to product services
- Transfer orchestrator — a Java service owning the transfer state machine:
initiated→reserved→screened→submitted→settled(or the compensating path at each step) - Ledger service — double-entry, append-only, on PostgreSQL. Balances are projections of the event history, not mutable rows
- FX engine — real-time pricing across 30+ currencies, interbank rate plus policy (weekend markups, plan-based allowances)
- FinCrime pipeline — sanctions screening plus ML scoring; Sherlock for card fraud, dedicated scam-detection models for push payments (we zoom in at Level 3)
- Rails connectors — one adapter per network: Faster Payments, SEPA / SEPA Instant, SWIFT, and the card processor. Each speaks the protocol of its network and isolates its failure modes
- Event store & streaming platform — the Postgres-backed backbone from ADR-001, with the Kotlin/Ktor delivery layer
- Notification service — the push message that beats the landlord's bank app by a full day
The technology stack at this level, straight from Revolut's own job postings: Java 17/21 as the dominant backend language, Kotlin for the streaming platform, PostgreSQL everywhere it matters, Redis for caching, jOOQ for typed SQL, Flyway for migrations, Spock for testing, all on GCP and Kubernetes, observed through Grafana, Prometheus and New Relic.
Notice what the diagram makes obvious: the rails connectors are the only containers whose failure Revolut cannot engineer away — Faster Payments being down is not a Revolut incident, but it is a Revolut support ticket. Modeling external dependencies as first-class containers with explicit relationships is how you make that risk visible before the incident review makes it visible for you.
ADR-002 · Bring card processing in-house
Status · Accepted (~2019, fully deployed since)
Context · Like nearly every fintech of its generation, Revolut launched on a third-party card processor. The processor sat on the critical path of every card transaction: its outages were Revolut's outages (and made headlines), its per-transaction fees scaled with Revolut's growth, and its roadmap gated Revolut's card features.
Decision · Build an in-house payment processor and migrate card traffic to it. Own the connection to the card networks directly.
Consequences · Revolut reports processing millions of payments weekly on in-house systems with near-perfect uptime. Unit economics improved at exactly the moment volume exploded, and card features ship on Revolut's calendar, not a vendor's. The price: Revolut now operates PCI-scope infrastructure that most companies rightly outsource, and carries the regulatory and audit burden that comes with it. This ADR only makes sense past a certain transaction volume — which is precisely what an ADR's context section is for. Copy the decision without the context and it's a catastrophe.
Level 3 — Component: inside Sherlock, the 50-millisecond judge

Of everything in Revolut's stack, the fraud engine is the most publicly documented — the team published how they built it in nine months, and the vendor case study fills in the data layer. That makes it our best candidate for a Component-level zoom, exactly like Stripe's idempotency layer in the previous post.
When a card transaction (or, through the adjacent scam models, a push-payment like Léa's) needs a verdict, it flows through these components:
- Feature assembler — turns the raw transaction into a feature vector: amount vs. history, merchant category, geography, device signals, velocity counters
- Profile store — customer and merchant behavioral profiles held in Couchbase, an in-memory NoSQL layer, so lookups stay in single-digit milliseconds
- Model server — a CatBoost gradient-boosting model scores the transaction; the entire decision has a budget of under 50 milliseconds
- Decision policy — thresholds turn a score into an action: approve, decline, or step-up (push notification asking Léa "was this you?")
- Nightly retraining pipeline — every night, models retrain on the day's confirmed fraud and false declines, closing the feedback loop daily rather than quarterly
- Case & feedback service — analyst decisions and customer responses flow back as labels for the next training run
The reported results: roughly 96% detection accuracy and fraud losses around one cent per $100 processed, against an industry average of seven to eight cents — a gap worth on the order of $3M in the first year alone.
The architectural lesson isn't "use CatBoost". It's the shape: a hard latency budget forced a dedicated in-memory profile store; a daily feedback loop forced retraining to be a pipeline, not a project. Constraints first, boxes second.
ADR-003 · Buy the profile store, build everything else
Status · Accepted (~2018, still active)
Context · Revolut's culture is conspicuously build-first: in-house processor (ADR-002), in-house event streaming (ADR-001), in-house banking core. Sherlock needed sub-10 ms reads on millions of behavioral profiles, with writes streaming in continuously — a solved problem in the database market, and one where "roll your own" adds latency risk to the one component with the tightest budget in the company.
Decision · Buy: use Couchbase as the in-memory profile store inside Sherlock, and spend the team's build capacity on the parts that differentiate — features, models, decision policy, and the retraining loop.
Consequences · The fraud team ships models, not storage engines. And the architecture carries a useful lesson in its bones: even the most build-happy engineering culture in European fintech buys when the component is undifferentiated and the failure mode is unforgiving. An ADR that says "we bought this, here's why, here's what would make us revisit" is worth ten wiki pages of vendor evaluation.

Three decisions, three cards in Archyl, each linked to the C4 elements they shape — the event backbone to every publishing container, in-house processing to the rails connectors, the buy-vs-build call to Sherlock's profile store. Two "build" decisions and one deliberate "buy": the diagram shows what is; the ADRs show what was weighed.
Ownership: a hundred companies inside a company

Revolut is famously organized as autonomous product teams — leadership talks about the company as "a hundred startups", each with an owner accountable end-to-end for a product's metrics, roadmap, and services. That maps directly onto the C4 model:
- Retail Payments owns the transfer orchestrator, rails connectors, and the transfer state machine
- FX & Pricing owns the FX engine and its market-data integrations
- FinCrime owns Sherlock, the scam-detection models, sanctions screening, and the case tooling
- Core Platform owns the ledger, the event store and streaming platform, and the Kubernetes substrate
- Onboarding owns KYC flows and identity-verification integrations
- Business, Wealth, Credit each own their product systems and their edges to the shared core
Once every container has an owner, the model stops being documentation and starts being governance. A new service appears in the codebase that isn't on the diagram? A specific team gets the drift notification. A container tries to read the ledger directly instead of consuming events? That's a conformance rule violation with a name attached — and in a company operating under PRA supervision since March 2026, "who owns this box" is a question regulators ask too.
In Archyl, the Ownership Map plus drift detection plus the weekly team digest turn Revolut's org design into an enforceable property of the architecture: Retail Payments' Monday digest covers the orchestrator and the rails; FinCrime's covers Sherlock and the screening pipeline. Same surface, scoped to each team's perimeter.
Steal this, skip this
The point of modeling someone else's architecture is to make better decisions in your own. Our take:
Steal:
- The event log as source of truth, on PostgreSQL. You almost certainly don't need Kafka on day one. An append-only table with disciplined consumers gives you replayability, audit, and SQL-debuggability — and it scales much further than the conference-talk consensus admits.
- A hard latency budget for the riskiest decision. "Fraud scoring answers in 50 ms or it approves with a flag" is an architectural constraint that designs half the system for you.
- One accountable owner per box. Revolut's "hundred startups" model is extreme, but its C4 translation — no container without a named team — costs nothing and changes everything about incident response and drift.
Skip (unless you have Revolut's context):
- Building your own event-streaming platform. That ADR is downstream of having a world-class platform team and hundreds of services. At ten services, managed messaging or plain Postgres queues win.
- In-house card processing. The decision paid off at millions of transactions per week. Below that, it's PCI scope and audit burden with no upside — the context section of ADR-002 is doing the heavy lifting.
You don't need 70 million customers
The discipline scales down. Separating Context from Container from Component; writing the ADR that explains a path-dependent decision (we skipped Kafka, we brought processing in-house, we bought the profile store); attaching an owner to every box — that's what keeps a stack of thirty services legible while it becomes a stack of three hundred.
C4 + ADRs + Ownership + Drift + Conformance is what Archyl gives you out of the box. Revolut is simply what that discipline looks like compounded over a decade at fintech velocity — from zero to a $75B bank on Java, Postgres, and unusually clear ownership.
Open your own architecture. Draw the systems (eight, or three). Follow your product's equivalent of Léa's £450 through the containers. Write the three ADRs a senior hire would ask about in week one. Map a team to every box.
You'll be ahead of where most engineering organizations get to in a year.
FAQ
Does Revolut use Kafka? No — by deliberate choice. Revolut persists events in a PostgreSQL-backed event store and built its streaming and messaging platform in-house in Kotlin (JetBrains Ktor, coroutines), finding it easier to maintain, customize and query than a Kafka deployment.
What database does Revolut use? PostgreSQL is the backbone — including for the event store that acts as the source of truth — complemented by Redis for caching and Couchbase as the in-memory profile store inside the Sherlock fraud engine.
What programming language is Revolut written in? The backend is predominantly Java (17/21), with Kotlin for the event-streaming platform and jOOQ for typed SQL access. It runs on Google Cloud and Kubernetes.
Is Revolut a real bank? Yes. Revolut operates under an EU banking licence (via the Bank of Lithuania) and received its full UK banking licence from the PRA in March 2026, after the restricted licence granted in July 2024.
How does Revolut detect fraud? With Sherlock, an in-house machine-learning system: CatBoost models score every card transaction in under 50 milliseconds against behavioral profiles stored in Couchbase, and retrain nightly. Revolut reports fraud losses of about 1¢ per $100 processed, versus an industry average of 7–8¢.
Want to model your own architecture in C4? Start with Archyl. This is the fourth post in the Anatomy series — read Stripe: Anatomy of a Charge, Netflix: Anatomy of a Play, and Uber: Anatomy of a Ride, or dive into why ADRs and C4 work better together.