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