One platform, one bank  / field guide
Practitioner field guide · 13 October 2026

When one platform runs everything

Monzo built a bank on a single uniform platform: one language, one datastore, one deploy path, one blast radius. Eleven years of its own incident reports, engineering posts and archived repositories show what that bought, what it cost twice in public, and why the remedy in 2025 was not diversity inside the platform but a second, deliberately smaller bank on somebody else's cloud.

31 sources on the page 57 rows in the ledger 3 published incidents Evidence through October 2026 Read: 44 min
01

The territory

A regulated business with no legacy estate decides to make every part of its software identical, then spends a decade discovering what identical costs. This is a single-company dig: the subject is Monzo, and the question is which structural changes were forced, and by what.

2,800
Services on one platform, in one monorepo, in one language
18
Services in the standby bank that replaces it during an outage
~1%
Of the primary platform's operating cost, for the standby
1h 21m
The 2017 outage that took the whole platform, not one service

The problem, stated without any product name in it: you are building a regulated service where a handful of operations must keep working at all times, you have no existing systems to protect, and you have to choose how much variety your software is allowed to contain. Variety is how a system limits damage, because unlike things fail at unlike times. Variety is also what makes a fleet of services unchangeable, because every migration has to be negotiated with every exception. Monzo chose almost no variety, published most of the consequences, and in 2025 bolted on the one piece of variety it could afford.

Three findings worth the reader's time before the detail. First, both of Monzo's published platform-wide outages came through the change path rather than the request path: a planned expansion of a coordination cluster in 2017, a planned migration of a database cluster in 2019. Neither was triggered by traffic. Second, the 2017 incident got worse because of the remediation: restarting several hundred service-mesh instances at once surfaced a version incompatibility that turned a partial failure into a total one, which is the shape the systems literature calls a sustaining effect. Third, and least expected, Monzo's own argument for a second platform on a second cloud provider is not that clouds fail. It is that its own software fails at least as often, and that a second copy of its software would fail the same way.

A bug in our code or processes is at least as likely to cause an outage as a cloud provider failure. Monzo, Tolerating full cloud outages with Monzo Stand-in, February 2025

That sentence is the hinge of the whole decade. If the risk you are hedging is your own code, then a hot replica of your platform in another region hedges almost nothing, and the only useful standby is one that shares no code with the thing it is standing in for. The size of Monzo's standby (18 services against roughly 2,800) follows from that, and so does its weakest property: it cannot make the decisions the primary platform makes, so it issues advice and lets the primary reconcile later.

Figure 1 · Eleven years, and what forced each turn

growth: 100 services becomes 1,500

incident: 1h 21m, whole platform

scale: 2,000+ services, 20,000 workloads

regulation, and its own bug risk

2015 to 2016
One platform, built from nothing
Go, own RPC wrapper, Cassandra, Kafka, Kubernetes

2017
The platform becomes the failure domain
self-run etcd grown from three nodes to nine

2019
Swap the data plane, gain a security boundary
Envoy sidecars, then per-pod network policy

2021 to 2024
Make the fleet changeable
100+ deploys a day, central fleet migrations

2025 to 2026
A second, smaller bank
Stand-in on another provider

growth: 100 services becomes 1,500

incident: 1h 21m, whole platform

scale: 2,000+ services, 20,000 workloads

regulation, and its own bug risk

2015 to 2016
One platform, built from nothing
Go, own RPC wrapper, Cassandra, Kafka, Kubernetes

2017
The platform becomes the failure domain
self-run etcd grown from three nodes to nine

2019
Swap the data plane, gain a security boundary
Envoy sidecars, then per-pod network policy

2021 to 2024
Make the fleet changeable
100+ deploys a day, central fleet migrations

2025 to 2026
A second, smaller bank
Stand-in on another provider

Every structural change on this path answers a growth constraint, a published incident, or a rule set outside the company. None of them is a preference. Compiled from Monzo 2016, the 2017 post-mortem thread, Monzo 2019, Monzo 2024 and Monzo 2025.
Diagram source
What this dig does not cover

The mobile applications, the credit and fraud models, the internals of the ledger, and anything about Monzo's cost base beyond the published ratios. Two large gaps are not choices but absences in the record: there is no public account of how the Kubernetes control plane is provisioned after 2022, and no account of the datastore after 2021. Both are marked open where they appear.

Retrieval limit worth knowing: this research session could fetch github.com directly and nothing else, so repository evidence here is first-hand and every other page was read through search-engine excerpts. The link check in the verifier could not run. The ledger in sources.md says which rows are which.

02

How it is actually built

One uniform platform on AWS, one deliberately unlike standby on Google Cloud, and a one-way join between them. Every box below is attributable; the two marked open are where the public record stops.

Figure 2 · The primary platform and the standby that is not a replica

Stand-in, Google Cloud

Primary platform, AWS

simplified UI
when enabled

one-way,
eventually consistent

advice per payment,
never re-decided

direct mode,
if AWS is down

Mobile app
polls for activation

Card networks
and schemes

Edge services

~2,800 Go services
one monorepo
Envoy sidecar per pod

Cassandra
quorum reads
and writes

Kafka and NSQ
event firehose

BigQuery
append-only

18 services: cards, transfers,
balances, card freeze

Local balances and limits

Stand-in, Google Cloud

Primary platform, AWS

simplified UI
when enabled

one-way,
eventually consistent

advice per payment,
never re-decided

direct mode,
if AWS is down

Mobile app
polls for activation

Card networks
and schemes

Edge services

~2,800 Go services
one monorepo
Envoy sidecar per pod

Cassandra
quorum reads
and writes

Kafka and NSQ
event firehose

BigQuery
append-only

18 services: cards, transfers,
balances, card freeze

Local balances and limits

The standby shares no services with the primary platform and is joined to it by a one-way event feed, with payment outcomes returning as advice that the primary never re-decides. Reconstructed from Tolerating full cloud outages, Processing payments in Monzo Stand-in and Monzo's data stack.
Diagram source

Start with what has not changed. Monzo's 2016 account of its backend describes a system that was already microservices, already in Go, already on Kubernetes, and already near 100 services at beta launch. The 2024 account of running fleet migrations describes 2,800 services in one monorepo, in Go, on Kubernetes. The shape is the same; only the count moved. That continuity is the single most important fact about this architecture, because every capability described below depends on it.

The in-house parts of 2015 are still visible in the repository record, and they have diverged in an instructive way. typhon, the wrapper around Go's net/http that Monzo's clients and servers are built on, was created in February 2015 and took substantive commits in August 2026, including a switch to the standard library's HTTP/2 client and idle-connection health checking. phosphor, the tracing system from the same month, has no such life; tracing moved to OpenTracing and then, under a deadline Monzo did not set, to OpenTelemetry. The surviving in-house component is the thin one that wraps a standard; the retired one is the one that substituted for a standard that later arrived.

Between the services sits the part that was replaced. Until 2019 inter-service traffic went through linkerd 1.x, and Monzo's own measurement put it at the top of the p99 budget under normal load. The replacement with Envoy was justified on performance (at 15,000 requests per second, lower 99th percentile latency and less than half the CPU) but its structural consequence was different: Envoy ran as a sidecar in each pod rather than as a shared proxy, which meant traffic finally had per-pod identity. That is what made the network isolation work of late 2019 possible at all, covering roughly 1,500 services and more than 9,300 service-to-service interactions whose dependency graph Monzo recovered by static analysis of its own monorepo rather than by observing traffic.

Egress went the same way, and the design is worth copying. Monzo's egress-operator rejects the obvious approach of inspecting outbound protocols. Instead each external dependency gets an internal cluster IP, DNS is rewritten to point at it, an Envoy gateway fronts it, and a network policy admits only pods carrying the label for that dependency. The README is blunt about the limit: the operator blocks nothing by itself, and the cluster needs default-deny egress for any of it to mean anything.

The data side is a mirror of the same instinct. Analytics is not fed by reading the operational store; services emit events into Kafka and NSQ, and the feed lands in append-only BigQuery projects where dbt compiles a model graph that Airflow executes. In 2021 that was over 4,700 models and about 600,000 lines of SQL; by May 2026, InfoQ reports 12,000 models across 100 teams, governed as a data mesh. The interesting artefact here is the one that died: Monzo wrote ddbt, a Go reimplementation of the dbt command line, because dbt "gets very slow on large projects (3000+ data models)". It was archived in May 2023 with the note that it is "left here for historic purposes". Why it was abandoned is not published.

The part an architect usually underestimates is how much of this platform is an interface for humans rather than for traffic. Monzo's tooling is pitched deliberately above Kubernetes, biased, in its own words, towards a simple and opinionated experience over configurability, so that engineers ship without touching the orchestrator; the published rate was over a hundred deploys a day in 2022 and hundreds of production changes a day by March 2026. The same uniformity shows up in the authorisation model, where staff access is granted per remote procedure call rather than per system, and sensitive calls can require multi-party approval. And it shows up in a constraint that would stop most organisations: by 2026 Monzo's platform group says around 250 services are already impractical to run on a laptop, which is why development happens in partial-stack environments it calls tenancies rather than locally. The latest turn in that story is the one worth watching. The house conventions that eleven years of enforced sameness produced are now encoded as skills for coding agents, so that generated services come out in the same shape as the handwritten ones. Uniformity, bought in 2016 to make migrations possible, turns out to be the thing that makes machine-written code reviewable.

Uniform service substrate

Go, one monorepo, generated service scaffolding, an in-house RPC wrapper, Kubernetes underneath, and tooling pitched deliberately above Kubernetes so engineers do not touch it. This is the asset that makes fleet-wide change affordable.

Sources: deploy tooling, 2022, migrations, 2024

Mesh as a policy surface

Envoy per pod, Calico network policy per service, label-gated egress gateways, and a Prometheus exporter for policy packet counts so a rollout can be measured before it is enforced.

Sources: isolation, 2019, calico-accountant

One operational datastore

Cassandra with quorum reads and writes for almost everything, which is why a cluster migration is a bank-wide event rather than a service-level one. Status after 2021 is open: no public account of node counts, versions, or replacements.

Sources: 2019 incident report, QCon 2023

Event firehose, not database reads

Service events stream through Kafka and NSQ into append-only analytics projects. The same feed is what keeps the standby's balances approximately current, which is why the standby could be built without touching the primary's data path.

Sources: data stack, 2021, InfoQ, 2026

Enclaves for the few things that cannot trust the platform

Multi-party authorisation runs in AWS Nitro Enclaves, with attestation gating secret release and the secrets kept out of the platform's own store so a platform administrator cannot subvert the control that constrains them.

Sources: admin access, 2023, aws-nitro-util

The standby, sized by what it can keep correct

Eighteen services on another provider covering card payments, transfers, balances and card freezing, with one-way replication in and advice out. Control plane provisioning for either platform after 2022 is open.

Sources: Stand-in, 2025, payments in Stand-in, 2025

03

The decisions that matter

Four forks with the reasoning Monzo published, and the condition under which the rejected option becomes the right one. Monzo publishes no decision records, so the rejected options below come from blog posts, repository READMEs and archive banners.

Decision: operate the hard infrastructure yourself, or hand it to the provider?

Chosen
  • Self-operated, 2015 onward: Kubernetes, etcd, Cassandra, Kafka, all on EC2
  • In 2016 there was no managed Kubernetes to buy, and a banking licence needs evidence of control, not a shrug
  • Monzo published its etcd design: nine nodes across three zones, quorum intact with four members gone
Rejected, then partly reversed
  • Managed storage and coordination. The dissent was public: an AWS engineer asked after the 2019 incident whether running Cassandra yourself "really makes you a better bank"
  • By 2024 the artefact of self-run etcd, etcd3-terraform, was archived read-only
  • What replaced it is open: Monzo has published nothing about its control plane since 2022
Flips when
  • A managed option exists that produces the audit evidence you owe a regulator, and the customisations you built are cheaper to delete than to keep
  • Watch the repository, not the blog: a deprecation banner on your own infrastructure recipe is the decision becoming visible

Decision: one language, one store, one deploy path, or variety per service?

Chosen
  • Near-total uniformity: Go, one monorepo, Cassandra for almost all persistence, one deploy pipeline, tooling above Kubernetes rather than through it
  • Payoff is measurable: over 100 deploys a day in 2022 and hundreds a day by 2026, with automated rollback extended across 2,100+ services
  • Fleet migrations are run centrally by one team, which Monzo says avoids the coordination overhead and stalling that service-by-service migration produces
Rejected
  • Per-team choice of language, datastore or deploy mechanism
  • Service owners running their own migrations
  • Cost accepted knowingly: one datastore means a cluster migration is a bank-wide change, which is exactly how the 2019 outage happened
Flips when
  • A workload's access pattern cannot be served by the common store, or a domain genuinely needs a different runtime; then the exception costs you the automation, so price it against a year of fleet migrations
  • Below roughly a hundred services the central-migration model has nobody to amortise against and becomes a bottleneck

Decision: should the standby be a replica of the bank, or a different, smaller bank?

Chosen
  • Eighteen purpose-built services on Google Cloud, sharing no code and no services with the primary platform
  • Replication into it is one-way, non-blocking and eventually consistent
  • Payments made there emit advice messages that the primary platform reads and never re-decides
  • Runs continuously in production at about 1% of the primary platform's operating cost
Rejected
  • A hot replica of the platform in another region or provider. If your dominant risk is your own code, a replica inherits the bug
  • Synchronous replication, which would have made the standby a dependency of the thing it protects
  • Covering the full product: credit decisions, support tooling and most features are simply absent while it is active
Flips when
  • The operations that cannot wait need state the standby cannot hold, or decisions that cannot be reconciled afterwards; then you have to keep the decision in the primary and degrade the feature instead
  • Also flips if the standby grows: at thirty or forty services it starts sharing your defects and your release process, and the independence you paid for is gone

Decision: authorise egress by inspecting protocols, or by name and label?

Chosen
  • A cluster IP per external dependency, DNS rewritten to it, an Envoy gateway in front, and a network policy that admits only pods labelled for that dependency
  • Works for any TCP protocol and needs no parser per protocol
Rejected
  • Protocol inspection at an egress proxy, which the README names and sets aside
  • Trusting the gateway to enforce anything: the operator blocks nothing without cluster-wide default-deny egress
Flips when
  • You need per-request authorisation rather than per-destination, or your cluster DNS is not CoreDNS and you cannot hijack resolution

Figure 3 · Choosing between a replica and a minimum viable standby

yes

no

many

a handful

no

yes

no

yes

Can customers wait
for the primary to recover?

Build no standby.
Spend on recovery time

How many operations
cannot wait?

Replica, and accept that it
shares your code and your bugs

Can those operations be decided
from slightly stale state?

Keep the decision in the primary.
Degrade the feature instead

Can the outcome be
reconciled afterwards?

Minimum viable standby:
separate code, separate provider,
one-way feed, advice back

yes

no

many

a handful

no

yes

no

yes

Can customers wait
for the primary to recover?

Build no standby.
Spend on recovery time

How many operations
cannot wait?

Replica, and accept that it
shares your code and your bugs

Can those operations be decided
from slightly stale state?

Keep the decision in the primary.
Degrade the feature instead

Can the outcome be
reconciled afterwards?

Minimum viable standby:
separate code, separate provider,
one-way feed, advice back

The branch that decides the design is not cost, it is whether the operations that cannot wait can be decided from stale state and reconciled afterwards. Derived from Monzo's two Stand-in posts and the re:Invent 2025 session on the same system.
Diagram source
DecisionChosenRejectedBecauseEvidence
Service mesh data planeEnvoy as a per-pod sidecar, 2019linkerd 1.x, Linkerd 2.0, Istiolinkerd 1.x dominated p99 under normal load; Envoy used less than half the CPU at 15,000 rps, which is what made a sidecar per pod affordableMonzo, Apr 2019
Service dependency graph for policyStatic analysis of the monorepoObserved trafficObservation only shows what has happened; a policy that admits only observed traffic breaks the first rare call pathMonzo, Nov 2019
Rollout safetyArgo Rollouts with automated rollback across 2,100+ servicesHuman-judged rollouts at 100 deploys a dayAt that deploy rate the slow step is the human watching dashboardsMonzo, Nov 2022
Fleet migration ownershipOne central team drives itEach service owner migrates their ownCoordination overhead makes owner-led migrations slow and prone to stalling; uniformity is what lets one team automate itMonzo, Aug 2024
Tracing libraryOpenTelemetry, 2024Staying on OpenTracingThe deadline came from outside: the CNCF technical oversight committee approved archiving OpenTracing in January 2022CNCF, Jan 2022
Enclave image buildsOwn Nix-based reproducible builderAWS nitro-cliIts images are timestamped and therefore not bit-for-bit reproducible, and it depends on pre-compiled vendor blobsmonzo/aws-nitro-util
Analytics access to operational dataEvent firehose into append-only warehouse tablesReading the operational storeKeeps analytical load off the bank's single datastore and gives the standby a feed it can consumeMonzo, Oct 2021
Incident toolingBuilt in-house, 2019Buying itNothing Slack-native existed; the people who built it founded incident.io in 2021 and the market caught upmonzo/response, Index Ventures

One pattern runs through that table. Monzo builds when the standard does not exist yet and retires its own work when the standard arrives, and the retirement is visible in the repository before it is visible anywhere else. etcd3-terraform archived in May 2024, ddbt archived in May 2023, phosphor left behind by OpenTelemetry; against that, typhon still being modernised in 2026 because nothing in the ecosystem replaced a thin wrapper around the standard library. If you are deciding what to build, that is the test worth stealing: build the wrapper, not the substitute.

The build-versus-hand-over question was asked out loud, and the answer has moved in both directions at once. A trade-press interview with the platform team describes it weighing whether to keep running Kubernetes, Kafka and Cassandra itself or pass them to AWS, which is the question the 2019 incident put on the table in public when an AWS principal engineer praised Monzo's write-up and then asked whether running Cassandra yourself really makes you a better bank. Since then the self-operated artefacts have been retired quietly while, in the opposite direction, Monzo started building against its provider's tooling where verifiability mattered: its enclave images are built from source with Nix because the vendor's builder produces timestamped, blob-dependent images that cannot be reproduced. Read together, those two movements are not inconsistent. The commodity parts went to the provider; the parts where Monzo has to be able to prove something to a regulator stayed in-house, and in the enclave case moved further in-house than the vendor's own path allows.

04

What broke in production

Five cards covering three Monzo incidents, grouped by class rather than by date: two published post-mortems (the 2017 outage appears twice because its remediation is a separate lesson), the ecosystem's unresolved version of the same fault, and the standby failing to fully stand in.

Both of Monzo's platform-wide outages belong to the same class: a planned change to shared infrastructure, made by the platform team, that altered what the fleet believed about cluster membership. Neither came from a traffic spike. In a platform where every service uses the same coordination layer and the same datastore, there is no such thing as a contained change to either, and the public record contains no example of a Monzo incident that stayed inside one service.

Postmortem

October 2017: growing etcd took the platform down two weeks later

AssumptionA no-downtime expansion of the coordination cluster, from three nodes to nine across three zones, was finished when it completed successfully.
What happenedA Kubernetes defect caused requests to time out after the cluster reconfiguration, so the mesh stopped receiving endpoint updates and kept routing to addresses with no process behind them. Accounts differ on whether the expansion was one or two weeks before the outage.
Blast radius1 hour 21 minutes, whole platform. Payments largely still completed through redundancy, and Monzo's head of engineering reported two customer complaints.
FixPublished as a mesh and version-compatibility problem; structurally, it ends in the 2019 replacement of the data plane and in a much more cautious posture about infrastructure changes.
Design ruleA control-plane change is not complete when it succeeds. It is complete when every consumer of its state has been observed to re-learn that state, which means an explicit check on the mesh, not on the cluster.
Postmortem

October 2017, second act: the remediation was the outage

AssumptionIf one mesh instance is unhealthy and restarting it helps, restarting all of them helps more. The forum timeline records that decision at 14:26, ten minutes after the outage was declared.
What happenedRestarting several hundred instances at once exposed an incompatibility between the mesh and Kubernetes versions, which a running instance never hit. A failure affecting some traffic became a failure affecting all of it.
Blast radiusConverted a partial outage into a total one for the remainder of the incident.
FixNot published as a structural change. The transferable artefact is the timeline itself, which Monzo published in unusual detail.
Design ruleAny bulk restart is a deploy of the currently installed version, and nobody has tested that version's cold start against today's control plane. Make the incident playbook restart a fraction and check, with the fraction written down before the incident.
Postmortem

July 2019: the database told every client about servers the firewall blocked

AssumptionSix new servers added to a 21-server Cassandra cluster at 13:10 would sit idle until data streamed to them, and joining the old and new clusters so they shared data was an operation the clients would not notice.
What happenedCassandra's topology events told every service about every node in the joined cluster. The new servers could reach the old ones, but services could not: a firewall blocked that path. Clients kept trying unreachable nodes and requests failed with the connection attempts, while reads and writes required a quorum of three replicas.
Blast radiusLogins, payments, balances and support degraded; Monzo's same-day note said data was not processed properly for about two hours. The full account came 40 days later.
FixStop services connecting to the old servers, then change how upgrades and data storage are performed.
Design ruleAny datastore client with membership discovery treats the cluster's view of itself as reachable. Your network's view and the cluster's view must be reconciled before a topology change, usually by filtering the hosts a client is allowed to learn.
Source

The same fault class, open in the ecosystem and closed unreproduced

AssumptionA fault you hit in a widely used dependency will be fixed upstream in a timeframe that matters to you.
What happenedKubernetes issue #47131, apiserver timeouts after a rolling etcd update, was opened in June 2017 and closed in February 2018 pointing at a client-library fix that landed only in 1.10, with a maintainer noting the reports lacked detail to confirm one root cause. Linkerd issue #1730, routing to a departed endpoint, was opened two months after Monzo's outage and closed with "Hard to say for sure if this is fixed or not given our inability to reproduce it".
Blast radiusUnknown and unknowable; at least one bank, and one reporter who wrote that the cluster was in production so a third outage could not be risked to reproduce the fault.
FixFor Monzo, replacing the component rather than waiting for the fix.
Design ruleBefore you plan around an upstream fix, read how the issue was closed. An issue closed as not reproducible is not a fixed issue, and it is a strong argument for replacing the component or putting your own detection in front of it.
Press account

August 2026: the standby was activated and some customers still could not transact

AssumptionActivating the standby restores the operations it covers, for everyone it covers.
What happenedOn 19 August 2026 problems began shortly after midday UK time and a downtime tracker logged more than 3,000 reports. Monzo enabled Stand-in; press accounts and customer comments report that some people still saw transfers and balances misbehaving while it was active. No root cause has been published beyond Monzo saying the core issue was fixed.
Blast radiusReported as roughly two hours, resolved the same day. Monzo's own phrasing was that Stand-in ran "for a short period today".
FixUnpublished. This entry is press and user reports, not an incident review, and it is included because the gap is itself the finding.
Design ruleA standby's success metric is the completion rate of the operations it promises, measured during activation and reported afterwards. Activation is an input, not an outcome; if you cannot report the former, nobody can tell a working standby from a switch that was flipped.

Figure 4 · The 2017 cascade, including the remediation that widened it

"Services""linkerd, severalhundred""Kubernetesapiserver""Self-run etcd""Platform team""Services""linkerd, severalhundred""Kubernetesapiserver""Self-run etcd""Platform team"14:16 outage declared, 14:18 mesh suspectedpartial failure becomes platform-widegrow cluster from three nodesto ninereconfiguration completes, nodowntimewatch requests timeout, known upstreamdefectendpoint updates stop arrivingroute to addresses with noprocess behind them14:26 restart every instanceversion incompatibility onreconnect
"Services""linkerd, severalhundred""Kubernetesapiserver""Self-run etcd""Platform team""Services""linkerd, severalhundred""Kubernetesapiserver""Self-run etcd""Platform team"14:16 outage declared, 14:18 mesh suspectedpartial failure becomes platform-widegrow cluster from three nodesto ninereconfiguration completes, nodowntimewatch requests timeout, known upstreamdefectendpoint updates stop arrivingroute to addresses with noprocess behind them14:26 restart every instanceversion incompatibility onreconnect
The trigger was two weeks in the past and already gone; what kept the platform down was the fleet's stale view plus a bulk restart into an untested version pairing. Reconstructed from the community post-mortem and InfoQ's summary.
Diagram source

Figure 5 · July 2019: discovery told the truth about the cluster and a lie about the network

quorum read and write

topology event:
here is every node

blocked by firewall

Service with
Cassandra client

New cluster
six added servers

Old cluster
21 servers

Connection attempts fail,
quorum requests fail with them

Fix: stop clients learning
hosts they cannot reach

quorum read and write

topology event:
here is every node

blocked by firewall

Service with
Cassandra client

New cluster
six added servers

Old cluster
21 servers

Connection attempts fail,
quorum requests fail with them

Fix: stop clients learning
hosts they cannot reach

The clients were not wrong about the cluster; they were wrong about which parts of it they were permitted to reach, and the fix was to narrow what a client is allowed to learn. Reconstructed from Monzo's incident report.
Diagram source

One pattern in this corpus is about disclosure rather than architecture, and it is a reconstruction rather than a reported fact. In 2017 the head of engineering published a minute-level analysis on the customer forum three days after the outage. In 2019 the same-day note said only that some data had not been processed properly for about two hours, and the mechanism arrived 40 days later as a blog post detailed enough to be useful to other engineers. For the August 2026 incident, no root cause has been published at all beyond a statement that the core issue was fixed, and what is publicly known about how the standby behaved comes from press reports and customer comments. The trajectory is towards less published mechanism as the bank grew, which is the normal direction of travel for a regulated company, and it means the most useful material in this dig is also the oldest. If you are relying on another organisation's published failures to validate your own design, collect them while the organisation is still small enough to write them down.

The class nobody has published

There is no public Monzo incident in which a failure was contained to one service, and no public account of a Stand-in activation drill that failed. The first absence is what you would expect from a uniform platform; the second means the evidence that the standby works comes from three real activations (August 2024, January 2026, August 2026) and from Monzo's statement that it runs continuously in production. If you build this pattern, the drill results are the artefact nobody in this corpus has published, and they are the ones your own board will ask for.

05

Numbers you can plan against

Service counts, incident durations, the standby's cost ratio and the load the platform now carries. Everything here is self-reported by Monzo unless the source column says otherwise.

MetricValueContextAs ofSource
Services~100At beta launch, already microservices in Go2016-09Monzo
Services~1,500Covered by the network isolation rollout, with 9,300+ interactions between them2019-11Monzo
Services~1,600Reported from a QCon talk2020-03The Register
Services and workloads2,000+ / 20,000+Microservices, and containerised workloads running them, all on AWS2022-03Monzo
Services2,100+Brought under automated rollback with Argo Rollouts2022-11Monzo
Services2,800Scope of a single central fleet migration2024-08Monzo
Services, contested3,000+ vs 30,000+Primary platform size, as given by two accounts of the same system. Monzo's own posts favour the lower figure2025AWS / LeadDev
Deploys to production100+ per dayAcross the fleet, with opinionated tooling above Kubernetes2022-05Monzo
Production changeshundreds per dayPlatform group's own description four years later2026-03InfoQ
Local development limit250 servicesThe subset that is impractical to run locally, which is why partial-stack "tenancies" exist2026-03InfoQ
etcd cluster3 then 9 nodesThree zones, quorum retained with four members unavailable; the expansion preceded the 2017 outage2017-11Monzo
Cassandra cluster21 servers, RF 3Quorum reads and writes; six servers added during the 2019 incident2019-07Monzo
Mesh comparison15,000 rpsTest load at which Envoy showed lower p99 and under half the CPU of linkerd 1.x. Self-measured, no independent replication published2019-04Monzo
dbt models4,700 then 12,000About 600k lines of SQL in 2021; 12,000 models across 100 teams by 20262021-10 / 2026-05Monzo / InfoQ
Standby size18 servicesCards, transfers, balances, card freeze. No shared services with the primary platform2025AWS
Standby cost~1%Of the primary deployment's operating cost. One account says total cloud bill instead, which is a different base2025-02InfoQ
Outage1h 21mWhole platform, 27 October 2017; two customer complaints reported2017-10Techerati
Outage~2 hours29 July 2019; data not processed properly for about two hours by Monzo's same-day account2019-07Monzo
Standby activations3 reportedAugust 2024 (about one hour, first full activation), January 2026, 19 August 20262024 to 2026Finextra / Crowdfund Insider
Infrastructure headcount8 engineersVendor-published claim, for a bank of more than 4 million customers at the time2020-09AWS
Engineers~200Secondary estimate of the engineering population behind the platform2022Container Solutions
Business load15.2m customers10.4m monthly actives, GBP 1.7bn revenue, GBP 25.7bn deposits, year to 31 March 20262026-05Monzo annual report
Regulatory deadline31 March 2025End of the UK transition period for staying within impact tolerances for important business services2025-03FCA
Read these carefully

Measured and self-reported: the service counts, deploy rates, cluster sizes and the 15,000 rps mesh comparison all come from Monzo, which has been consistent and specific over eleven years but is also the only party measuring. Vendor claims: the eight-engineer infrastructure team and the 18-service standby come from AWS material. Contested: the primary platform's size, where one account says 30,000+ services and AWS says over 3,000; Monzo's own posts say more than 2,000 in March 2022 and 2,800 in August 2024, so the lower figure is the one to plan against and the higher one is probably workloads rather than services. Derived: nothing in this table is computed by this dig. Unknown: the standby's own operation completion rate during activation, Cassandra's current size, and how either platform's Kubernetes control plane is run today.

One ratio is worth carrying into a budget conversation. A standby that covers the handful of operations customers cannot live without costs roughly one per cent of the platform it protects, by the operator's own figure, and it covers 18 services out of thousands. That is the number to put next to the usual proposal, which is an active-active replica of everything at something closer to one hundred per cent. The difference is not a discount on the same product; the replica protects against infrastructure loss and the minimum viable standby protects against your own software, and only one of those two is the risk Monzo says dominates.

06

What eleven years of this teaches

One lesson, stated so it transfers to a system that is nothing like a bank.

Monzo made the same decision twice, eight years apart, and the second one is only intelligible as a correction to the first. In 2016 it decided that its software would contain almost no variety: one language, one datastore, one deploy path, one mesh, one coordination cluster, tooling that hides all of it. That decision is why one team can now migrate 2,800 services, why automated rollback could be switched on across 2,100 of them, why hundreds of changes a day are routine, and why the house conventions are now clean enough to hand to a coding agent. It is also why there is no public example of a Monzo failure that stayed inside one service, and why both published platform outages arrived through a planned change to something every service shared.

You cannot fix that by adding variety back. A second datastore, a second language, a second deploy path: each one subtracts from the changeability that the uniformity bought, and the failure domains stay correlated anyway because the code is still the same code. The hedge Monzo eventually built is the only one that does not eat its own premise. One deliberately different, deliberately small system, on a different provider, sharing no services, fed one-way, covering four operations, costing about one per cent, and incapable of making the decisions the real platform makes. It does not reduce the chance of an outage at all. It reduces what an outage means.

The rule to carry into your own design review

Uniformity and a standby are two halves of one decision. Buy changeability with uniformity, then accept that you have bought a single correlated failure domain, and pay for it with a second system sized by what you can keep correct rather than by what you would like to preserve. The sizing test is three questions in order: which operations cannot wait, can they be decided from stale state, and can the outcome be reconciled afterwards. Everything that fails any of those three questions stays in the primary platform and degrades.

The corollary is the part most teams get wrong. A standby that shares your code, your release process or your data path is a replica, and a replica hedges infrastructure loss, not software defects. If your honest post-mortem history says your own changes cause most of your outages, a replica is the wrong purchase at any price.

Two caveats that the evidence will not let this dig drop. The standby is not proven: three activations are reported, and in August 2026 some customers still could not transact while it was running, with no published root cause. And the whole model rests on a property most organisations do not have, namely that Monzo had no legacy estate and could impose uniformity from the first commit. If you are retrofitting, the cheap version of this lesson is to stop adding variety, name the handful of operations that cannot wait, and build the small separate thing for those, in that order.

07

The evidence wall

Thirty-one of the fifty-seven ledger rows, graded and filterable. The full ledger, including the rows that only corroborate, is in sources.md beside this page.

Postmortem Monzo2019-09

Why Monzo wasn't working on July 29th

The most detailed incident report in this corpus. Gives the cluster shape (21 servers, replication factor three, quorum reads and writes), the action (six servers added at 13:10), and the mechanism: joined clusters advertised hosts that services were firewalled away from.

Carry forwardFilter the hosts a datastore client is allowed to learn, before any topology change, and test the filter rather than the cluster.
monzo.com/blog/2019/09/08/why-monzo-wasnt-working-on-july-29th
Postmortem Monzo community2017-10

Major outage 27/10/2017, post-mortem thread

Monzo's head of engineering posted the analysis on the customer forum, with a minute-level timeline: 14:16 declared, 14:18 the mesh suspected, 14:26 the decision to restart every instance. It also records the etcd expansion from three nodes to nine that set the trap.

Carry forwardWrite the bulk-restart fraction into the playbook before the incident; during one, "restart everything" is the decision that converts partial failure into total.
community.monzo.com/t/resolved-current-account-payments-may-fail-major-outage-27-10-2017/26296
Postmortem Monzo2019-07

We had issues with Monzo yesterday

The same-day note on the July 2019 incident, saying a change meant data was not processed properly for about two hours and the change was rolled back. The real root cause followed 40 days later.

Carry forwardPublish the thin account fast and the mechanism later, and say which one the reader is holding. The gap between the two is a measure of how long diagnosis actually takes.
monzo.com/blog/2019/07/30/we-had-issues-with-monzo-yesterday
Source Kubernetes2017-06

Issue #47131, apiserver timeouts after rolling-update of etcd cluster

Opened June 2017, closed February 2018 pointing at a client-library bump that landed in 1.10, with a maintainer saying the reports lacked detail to confirm a single root cause. The reporter notes they cannot risk a third production outage to reproduce it.

Carry forwardThe upstream fault class behind a vendor-free outage is usually findable and usually older than your incident. Check it before you conclude the fault was yours alone.
github.com/kubernetes/kubernetes/issues/47131
Source Linkerd2017-12

Issue #1730, linkerd continues to talk to old endpoint

Filed two months after Monzo's outage, describing the same symptom: the proxy fixated on an endpoint Kubernetes had already removed. Closed in March 2018 with "Hard to say for sure if this is fixed or not given our inability to reproduce it", reopened in May, closed again the same day.

Carry forwardAn issue closed as not reproducible is not a fixed issue. Treat that closure as evidence for replacing the component or adding your own staleness detection.
github.com/linkerd/linkerd/issues/1730
Source monzo/etcd3-terraform2024-05

Archived: the recipe for self-run etcd

Created 28 November 2017, a day before the "Very Robust etcd" post, described in its README as "an illustration of how we run etcd clusters", and archived read-only on 16 May 2024. The banner is the only dated public signal about this layer after 2022.

Carry forwardRead the archive banners on a company's own infrastructure recipes. They date platform decisions that never get a blog post.
github.com/monzo/etcd3-terraform
Source monzo/typhon2026-08

The 2015 RPC wrapper, still being modernised in 2026

Created February 2015 and still taking substantive commits eleven years later: a move to the standard library's HTTP/2 client and idle-connection health checking in August 2026. Compare phosphor, the tracing system from the same month, which the ecosystem replaced.

Carry forwardIn-house code that wraps a standard survives; in-house code that substitutes for a standard gets retired when the standard arrives. Build wrappers.
github.com/monzo/typhon
Source monzo/egress-operator2019-12

Egress authorised by name and label, not by protocol inspection

A cluster IP per external dependency, DNS rewritten to point at it, an Envoy gateway in front, a network policy keyed on a per-dependency label. The README names the rejected alternative and admits the operator "won't block any traffic for you" without default-deny egress.

Carry forwardProtocol-agnostic egress control is a naming problem, not a parsing problem. The enforcement still has to come from a default-deny policy you own.
github.com/monzo/egress-operator
Source monzo/aws-nitro-util2024-02

Reproducible enclave images, because the vendor's builder is not

A Nix flake that builds AWS Nitro Enclave images deterministically. The README's reasoning is explicit: nitro-cli output is timestamped and so not bit-for-bit reproducible, it depends on pre-compiled vendor blobs, and building from source reduces "implicit trust on AWS".

Carry forwardIf an attestation is the control, the image it attests has to be reproducible by you. Otherwise you have attested the vendor's build, not your code.
github.com/monzo/aws-nitro-util
Source monzo/ddbt2023-05

Archived: the in-house replacement for a vendor CLI

Built because dbt "gets very slow on large projects (3000+ data models)", archived on 4 May 2023 and "left here for historic purposes", with no successor named. Monzo's model count went on to triple.

Carry forwardA performance fork of somebody else's tool is a dated bet. Record why you built it, so the decision to delete it is cheap when upstream catches up.
github.com/monzo/ddbt
Source monzo/calico-accountant2019-09

A Prometheus exporter for Calico policy packet counts

Created a month before the isolation post. It counts what a policy would drop for a given service, which is how a default-deny rollout across 1,500 services becomes measurable rather than a coin toss.

Carry forwardBefore enforcing a policy, ship the instrument that counts what enforcement would have broken. The instrument is the project; the policy is the easy part.
github.com/monzo/calico-accountant
Source monzo/response2019-04

The in-house incident tool that became somebody's company

403 commits, still public, still carrying Django 2.2 era instructions and no maintenance notice. The engineers who built it founded incident.io in 2021, which is the cleanest example in this dig of in-house capability leaving by the front door.

Carry forwardWhen your in-house tool's authors start a company in the same category, the build-versus-buy answer for everyone else has changed.
github.com/monzo/response
ADR CNCF2022-01

CNCF archives the OpenTracing project

The technical oversight committee's archiving decision, graded here as a decision record because that is what it is. It is also the origin of the deadline for Monzo's 2,800 service tracing migration two years later.

Carry forwardSome of your migration backlog is set by foundations and vendors. Track project archival decisions as dependencies with dates, not as news.
cncf.io/blog/2022/01/31/cncf-archives-the-opentracing-project
ADR FCA2025-03

Operational resilience: insights and observations for firms

The UK regulator's published position: in-scope firms had to be ready to comply by 31 March 2025, having identified important business services and set impact tolerances. Graded as a decision record: it is a published rule with stated reasoning.

Carry forwardIn a regulated setting the resilience design is partly specified for you, in the vocabulary of services and tolerances. Name your important business services before you size any standby.
fca.org.uk/firms/operational-resilience/insights-observations
Blog Monzo2025-02

Tolerating full cloud outages with Monzo Stand-in

The architecture of the standby, and the sentence that justifies it: a bug in Monzo's own code or processes is at least as likely to cause an outage as a cloud provider failure. Also states that no service runs in both platforms, that replication is non-blocking and eventually consistent, and that direct mode (AWS fully down) is expected to be a small fraction of incidents.

Carry forwardWrite down which risk the standby hedges. If it is your own code, the standby must share none of it, which bounds how large it can be.
monzo.com/blog/tolerating-full-cloud-outages-with-monzo-stand-in
Blog Monzo2025

Processing payments in Monzo Stand-in

How the standby stays honest about state it does not own. Every payment it processes emits an advice message; the primary platform was extended to understand those messages and explicitly does not re-run any decisioning for them. If degradation is severe enough, the standby talks to scheme connectivity directly.

Carry forwardReconciliation design decides standby scope. One way replication plus advice that is never re-decided is the cheapest correct shape; two way reconciliation means you have built a second bank.
monzo.com/blog/processing-payments-in-monzo-stand-in
Blog Monzo2019-04

We deployed Envoy Proxy to make Monzo faster

linkerd 1.x was the main contributor to 99th percentile latency under normal load. Linkerd 2.0, Istio and Envoy were evaluated; at 15,000 requests per second Envoy showed lower p99 and under half the CPU, which is what made a per-pod sidecar affordable.

Carry forwardA data-plane swap justified on CPU can buy you a security boundary, because per-pod proxies give per-pod identity. Price the second benefit when you make the first argument.
monzo.com/blog/2019/04/03/deploying-envoy-proxy
Blog Monzo2019-11

We built network isolation for 1,500 services

Default-deny between services, with the dependency graph recovered by static analysis of the monorepo (a tool called rpcmap) rather than from observed traffic, across more than 9,300 interactions. Rolled out in log-only mode first using a high-order Calico policy.

Carry forwardDerive policy from code, not from traffic: traffic misses the rare path, and the rare path is the one that pages you at 3am.
monzo.com/blog/we-built-network-isolation-for-1-500-services
Blog Monzo2024-08

How we run migrations across 2,800 microservices

Fleet migrations are owned centrally rather than devolved to service owners, because devolving them creates coordination overhead and stalling. The enablers named are uniformity, the monorepo, mass-deploy tooling and automated rollback checks.

Carry forwardUniformity is not an aesthetic; it is the precondition for one team being able to change three thousand services. Every exception you grant is a line item in next year's migration.
monzo.com/blog/how-we-run-migrations-across-2800-microservices
Blog Monzo2022-11

Argo Rollouts at scale

Automated rollback brought to 2,100+ services at over a hundred deploys a day, with the platform owning the rollout mechanism rather than each team scripting it.

Carry forwardAbove roughly a hundred deploys a day the human in the rollout loop is the bottleneck and the hazard; automate the rollback decision before you automate anything else.
monzo.com/blog/2022/11/02/argo-rollouts-at-scale
Blog Monzo2022-03

How we secure Monzo's banking platform

Scale and stance together: more than 20,000 containerised workloads across more than 2,000 microservices, with a default of not trusting workloads, so a newly deployed service can reach nothing until access is granted.

Carry forwardDefault-deny is affordable at thousands of services only if grants are generated from the code that makes the calls. Make the grant a build artefact.
monzo.com/blog/2022/03/31/how-we-secure-monzos-banking-platform
Blog Monzo2023-12

Securing admin access to Monzo's platform

Multi-party authorisation running in enclaves, with AWS-signed attestation gating secret release, and the secrets deliberately held outside the platform's own secret store so a platform administrator cannot subvert the control that constrains them.

Carry forwardDraw the dependency graph of your controls. A control whose secrets live in the system it polices is decoration.
monzo.com/blog/2023/12/14/securing-admin-access-to-monzos-platform
Blog Monzo2017-11

Very Robust etcd

Published a month after the outage the etcd expansion helped cause: nine nodes across three zones, quorum surviving four losses, peers discovered through DNS SRV records rather than an external bootstrap service.

Carry forwardA quorum design that tolerates four node losses does not tolerate a fleet that cannot re-learn the membership. Availability of the cluster and availability of its consumers' view are two different properties.
monzo.com/blog/2017/11/29/very-robust-etcd
Blog Monzo2021-10

An introduction to Monzo's data stack

Analytics is fed by a service event firehose through Kafka and NSQ into append-only BigQuery projects, with dbt compiling a model graph that Airflow runs. Over 4,700 models and about 600,000 lines of SQL at the time.

Carry forwardAn event feed built for analytics is also the cheapest feed for a standby. Design it once, with both consumers in mind.
monzo.com/blog/2021/10/14/an-introduction-to-monzos-data-stack
Blog Ben Kehoe2019-08

The published dissent on self-operated storage

Days after the 2019 report, an AWS principal engineer praised the write-up and then asked the uncomfortable question: the incident would not have happened on a managed storage service, so does running Cassandra yourself really make you a better bank?

Carry forwardKeep the strongest external objection to your operating model written down next to the decision. Five years later it is the best test of whether the decision still holds.
x.com/ben11kehoe/status/1160180141361963008
Talk AWS re:Invent, community write-up2025-12

HMC201, Architecting resilient multicloud operations, featuring Monzo Bank

The session's framing, from a community transcript: multicloud does not raise resilience by itself because it adds complexity, and the standby is justified through failure-mode analysis (single points of failure, excessive load, excessive latency, misconfiguration and bugs, shared fate) rather than by provider redundancy.

Carry forwardArgue a second provider from a named failure mode you cannot otherwise cover, usually shared fate. "Multicloud" on its own is a cost centre.
dev.to/kazuya_dev/aws-reinvent-2025-architecting-resilient-multicloud-operations-feat-monzo-bank-hmc201-3jh9
Talk InfoQ, QCon London2026-03

Shipping constantly with humans and beyond at Monzo

The 2026 state of the platform: hundreds of production changes a day, partial-stack "tenancies" because 250 services are already impractical to run locally, and backend conventions encoded as skills so coding agents produce services in the house shape.

Carry forwardA decade of enforced uniformity turns out to be the input format machine-written code needs. The convention document becomes an interface.
infoq.com/news/2026/03/shipping-monzo
Talk QCon London2023-03

Banking on thousands of microservices

The mid-decade account, describing a platform of nearly two thousand microservices and the early choices (Cassandra, Kubernetes) that the rest of the decade had to live with.

Carry forwardConference bios are a usable time series for scale claims, because speakers restate the current number every year.
qconlondon.com/presentation/mar2023/banking-thousands-microservices
Paper OSDI '222022

Metastable Failures in the Wild

Supplies the vocabulary the 2017 incident needs: a trigger causes temporary overload, a sustaining effect keeps the system failed after the trigger is gone. The HotOS '21 predecessor states plainly that a systematic approach to robustness against unknown metastable failures remains an open problem.

Carry forwardSeparate trigger from sustaining effect in every post-mortem. Removing the trigger is not recovery, and the sustaining effect is usually something you built to help.
usenix.org/conference/osdi22/presentation/huang-lexiang
Case study Monzo2026-05

Annual Report 2026

The load the architecture now carries: 15.2 million customers, 10.4 million monthly actives, GBP 1.7bn revenue and GBP 25.7bn of deposits in the year to 31 March 2026, with a technology and platform section of its own.

Carry forwardAnnual reports date-stamp the scale a published architecture was serving, which is the context every engineering number needs and rarely carries.
monzo.com/annual-report/2026
Vendor AWS2025

Monzo Bank success story

Source of the two figures that frame the standby: over 3,000 services on the primary platform, 18 in Stand-in. Vendor material, and the only account that puts both numbers in the same sentence.

Carry forwardVendor case studies are the cheapest source of a ratio and the worst source of a mechanism. Use them for the shape, never for the outcome.
aws.amazon.com/solutions/case-studies/monzo-case-study
08

Build a miniature, then productionise it

Six rungs that reproduce the pattern at a scale you can hold in your head. The crossing from toy to real happens at rung four, where the standby starts running all the time.

Name the operations that cannot wait

Take a real service you own and write the list: for Monzo it is card payments, bank transfers, balance display and freezing a card. Everything not on the list is explicitly allowed to be unavailable. Get the list agreed by somebody who is not an engineer.

Done when: the list is four items or fewer and the owner of the product has signed it.  Teaches: that scope, not technology, is what makes a standby affordable.

Build the one-way feed

Emit the state those operations need (balances, limits, card status) onto an event stream, and write a consumer that keeps a separate store approximately current. Do not let the consumer call back into the primary system for anything.

Done when: killing the consumer for an hour and restarting it converges without manual repair.  Teaches: why the replication has to be non-blocking: a synchronous standby is a new dependency of the thing it protects.

Decide from stale state, and emit advice

Implement one operation in the standby against that stale store, with its own limits (Monzo's analogue is approving payments it cannot fully decide). Have it emit an advice record per action, and write the primary-side reader that accepts the outcome without re-deciding it.

Done when: a payment made in the standby appears in the primary's ledger with the same outcome and no second decision.  Teaches: the correctness boundary of the whole pattern.

Put the switch in the client, and leave the standby running

Have the client poll for activation in the background and swap to a reduced interface when it flips. Then deploy the standby permanently, on a different provider or at least a different account, with its own pipeline and its own credentials.

Done when: the standby has been serving its feed continuously for a week and its deploy pipeline shares nothing with the primary.  Teaches: that an always-on standby is tested by existing, and a cold one is tested by hoping.

Measure the thing that actually matters

Instrument the completion rate of each covered operation during activation, not just activation itself. Publish it internally after every drill and every real use, which is the artefact missing from the entire public record on this pattern.

Done when: you can answer "what fraction of card payments succeeded while we were in standby" for the last drill.  Teaches: the difference between flipping a switch and standing in.

Break the control plane, not a node

Run a game day that removes the primary's control plane or its coordination layer rather than killing instances: the 2017 and 2019 incidents both came from a planned change to shared state, so that is the drill worth rehearsing. Include a bulk restart, and see what version pairing you discover.

Done when: the drill has produced at least one surprise that changed a runbook.  Teaches: that the change path, not the request path, is where platform-wide failures come from.

09

Keep hunting

The searches that produced this page, including the ones that produced nothing, which is how two of the open questions above were established.

One company's decade, from its own words

  • monzo blog "here's what happened" outage incident report
  • "why monzo wasn't working" cassandra partition key remediation
  • monzo "we deployed" OR "we built" OR "we run" microservices site:monzo.com
  • community.monzo.com post mortem "major outage" timeline
  • monzo engineering talk infoq qcon "thousands of microservices" bio

Repository archaeology, which dates what blogs omit

  • github.com/monzo sort by updated, then read the archive banners
  • "This repository was archived by the owner on" infrastructure terraform
  • repo:kubernetes/kubernetes is:issue etcd rolling-update apiserver timeout 2017
  • repo:linkerd/linkerd is:issue is:closed stale endpoint "unable to reproduce"
  • monzo stand-in "18 services" OR "1%" cost primary platform figures

Two queries returned nothing useful, repeatedly, and that is recorded here because it is the cheapest finding on the page: searches for a Monzo account of moving to a managed Kubernetes control plane, and searches for any Cassandra detail after 2021. If you need either, the next move is the conference programmes rather than the blog, and failing that, job postings for the platform group.

10

References

Checked 13 October 2026. This session's network policy permitted direct fetches to github.com only, so GitHub rows were read first-hand and the rest through search-engine retrieval; the verifier's link check could not run.

  1. Monzo, Building a Modern Bank Backend Monzo blog, 19 September 2016.
  2. Monzo, Very Robust etcd Monzo blog, 29 November 2017.
  3. Monzo community, Major outage 27/10/2017 post-mortem thread Monzo community forum, October 2017.
  4. InfoQ, Monzo Outage Post Mortem InfoQ, November 2017.
  5. The Register, Kubernetes bug ate my banking app The Register, 31 October 2017.
  6. Techerati, Lessons learned from Monzo's Kubernetes outage Techerati, 3 May 2018.
  7. Kubernetes issue #47131, apiserver timeouts after rolling-update of etcd cluster GitHub, opened 7 June 2017, closed 12 February 2018.
  8. Linkerd issue #1730, linkerd continues to talk to old endpoint GitHub, opened 6 December 2017, closed 18 May 2018.
  9. Monzo, We deployed Envoy Proxy to make Monzo faster Monzo blog, 3 April 2019.
  10. Monzo, We built network isolation for 1,500 services Monzo blog, November 2019.
  11. InfoQ, How Monzo Isolated Their Microservices Using Kubernetes Network Policies InfoQ, December 2019.
  12. monzo/egress-operator GitHub, created 11 December 2019, updated 15 June 2026.
  13. Monzo, Why Monzo wasn't working on July 29th Monzo blog, 8 September 2019.
  14. Monzo, We had issues with Monzo yesterday Monzo blog, 30 July 2019.
  15. The Downtime Project, Monzo's 2019 Cassandra Outage Podcast episode, 2021.
  16. Ben Kehoe, post on the 2019 incident X, 9 August 2019.
  17. Monzo, How we deploy to production over 100 times a day Monzo blog, 16 May 2022.
  18. Monzo, Argo Rollouts at scale Monzo blog, 2 November 2022.
  19. Monzo, How we run migrations across 2,800 microservices Monzo blog, August 2024.
  20. CNCF, CNCF archives the OpenTracing project CNCF blog, 31 January 2022.
  21. Monzo, How we secure Monzo's banking platform Monzo blog, 31 March 2022.
  22. Monzo, Humans who can RPC Monzo blog, 26 May 2022.
  23. Monzo, Securing admin access to Monzo's platform Monzo blog, 14 December 2023.
  24. Monzo, Securing our software supply-chain better with reproducible builds for enclaves Monzo blog, 2024 to 2025.
  25. monzo/aws-nitro-util GitHub, created 13 February 2024, updated 28 July 2026.
  26. monzo/etcd3-terraform GitHub, created 28 November 2017, archived 16 May 2024.
  27. monzo/ddbt GitHub, created 11 September 2020, archived 4 May 2023.
  28. monzo/typhon GitHub, created 12 February 2015, commits through 12 August 2026.
  29. monzo/calico-accountant GitHub, created 22 September 2019.
  30. monzo/response GitHub, created 13 April 2019, 403 commits, not archived.
  31. Index Ventures, incident.io raises $62M Index Ventures, 2025 to 2026.
  32. Monzo, An introduction to Monzo's data stack Monzo blog, 14 October 2021.
  33. InfoQ, Monzo builds governed data mesh across 100 teams and 12,000 dbt models InfoQ, May 2026.
  34. Monzo, Tolerating full cloud outages with Monzo Stand-in Monzo blog, February 2025.
  35. Monzo, Processing payments in Monzo Stand-in Monzo blog, 2025.
  36. InfoQ, How Monzo Bank Built a Cost-Effective, Unorthodox Backup System InfoQ, 24 February 2025.
  37. LeadDev, How Monzo built a Stand-in platform to sidestep costly outages LeadDev, 2025.
  38. AWS, Monzo Bank success story AWS customer case study, undated.
  39. AWS, Monzo case study (PDF) AWS, September 2020.
  40. Finextra, Monzo develops backup bank to cover outages Finextra, 2024.
  41. Crowdfund Insider, Monzo highlights backup system Crowdfund Insider, January 2026.
  42. Finextra, Monzo deploys backup bank in face of outage Finextra, August 2026.
  43. StatusCake, Monzo's Stand-In held up on Wednesday StatusCake, August 2026.
  44. PYMNTS, Monzo steers customers to backup bank amid technical outage PYMNTS, August 2026.
  45. FCA, Operational resilience: insights and observations for firms Financial Conduct Authority, 2024 to 2025.
  46. AWS re:Invent 2025 session HMC201, community write-up dev.to, 3 December 2025.
  47. QCon London, Banking on Thousands of Microservices QCon London, March 2023.
  48. InfoQ, Modern Banking in 1500 Microservices InfoQ presentation, 2020.
  49. InfoQ, QCon London 2026: Shipping Constantly with Humans and beyond at Monzo InfoQ, March 2026.
  50. InfoQ, Monzo's Recipe for Developer Experience InfoQ, April 2025.
  51. The Register, How does Monzo keep 1,600 microservices spinning? The Register, 9 March 2020.
  52. Monzo, Annual Report 2026 Monzo, 19 May 2026.
  53. Bronson, Aghayev, Charapko, Zhu, Metastable Failures in Distributed Systems HotOS '21, 2021.
  54. Huang et al., Metastable Failures in the Wild USENIX OSDI '22, 2022.
  55. Performance Comparison of Service Mesh Frameworks: the MTLS Test Case arXiv preprint, November 2024.
  56. Container Solutions, How Monzo's opinionated platform and tools support their developer experience Container Solutions, 2022.
  57. diginomica, Monzo Bank eyes AWS managed services diginomica, 2020 to 2021.
  58. Tigera, Conversation with Monzo on compliance with Calico Tigera, undated.