Build1 distinct publisher3 min readUpdated
Tailscale logged 19 corrupted shard databases in six months, and the first alarm came from a pipeline reading its S3 backups. Using SQLite correctly did not bound the failure.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
Nineteen corruptions in six months is about one every nine or ten days [9][17]. Tailscale calls SQLite corruption highly unusual and not something you should meet in normal operation [16], and that can be true at the same time as the rate above, because the unit differs. Per shard, the odds stayed small, and most shards were never involved at all [15]. Across the fleet, something broke every week and a half [20]. The status page reports the fleet [15].
The first signal, last August, did not come from the process that owned the database. It came from a data pipeline reading the S3 backups, and the integrity check was run against the backup copy [8]. That pipeline uploads the entire database file every few minutes [7], so a corrupt file reaches the bucket before anyone has looked at it, while the single Go process holding the write lock keeps serving [5]. Detection latency was therefore the snapshot interval plus whatever schedule the downstream reader ran on [18]. Nothing in the serving path was looking.
That is the part that generalises, more than the WAL internals. Tailscale had done what the documentation asks: one process, exclusive access, the pattern SQLite is built around [5], on a database it has run as primary storage since 2022 [6]. The fault was in SQLite itself, in WAL reset [3]. Correct usage bought a great deal and it did not bound corruption.
With the cause unknown, two mitigations were available and only one was reachable. Recovery got faster across the incident series [13]; incidence did not fall until the bug was identified months later [1][2][19]. That is a reasonable response to an undiagnosed fault, and it also means the team spent half a year treating corruption as a recurring operational event, paid for by stopping the shard's control plane each time [12].
For anyone running shard-per-SQLite, the practical reading is arithmetic. PRAGMA integrity_check exists and is cheap enough that Tailscale ran it by hand the moment it had a suspect file [8]. The number of database files scales with the shard count, and each one is a separate object that either has a named owner checking it on a cadence you set, or does not. Inheriting detection from a backup consumer means your mean time to detect is a property of your analytics schedule.
One more thing kept the blast radius survivable: these databases hold tailnet and device metadata, never private keys or traffic [10], so the worst outcome in the early incidents was a handful of recent devices and configuration changes that had to be re-entered [11]. Devices already connected stayed connected, blind to changes, while anything arriving during the repair window could not join [14]. A shard-per-SQLite design holding state that cannot be re-typed would have produced a very different post.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
Tailscale's uptime was shaky at the end of last year and the instability continued into the new year; many of these outages were caused by a single bug deep in SQLite, and it took months of intense forensics to track down.
By summer, Tailscale says it is confident it has found the bug, understands it, and has fixed it.
Tailscale's post is titled "How Tailscale helped find the SQLite WAL-Reset bug" and describes the fault as a long-standing bug in the heart of the SQLite database that Tailscale helped uncover.
Tailscale has used SQLite as its primary database since 2022, chosen because it is well known, reliable and widely used, which the company calls boring technology in a good way.
Tailscale's backup pipeline takes a complete snapshot of each database every few minutes and uploads the entire SQLite file to an S3 bucket; it had run without incident since early 2023.
In August last year a data pipeline reading the S3 backups reported an error in one database; Tailscale ran SQLite's PRAGMA integrity_check against the backup, found it corrupted, repaired the database and investigated the cause without success.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed first-party postmortem, no external corroboration
The account is specific and checkable in shape — 19 events, six months, first detection in August via a backup reader, PRAGMA integrity_check confirmation, >1h early recovery windows, a six-week quiet period, named architecture and language — which is well above typical vendor incident prose. But it is one source, the affected party, the supplied body truncates before the WAL-Reset mechanism is explained, and nothing in the cluster independently verifies the root cause or the fix.
Real production deployment at one vendor, no ecosystem signal
Adoption is well evidenced but narrow: SQLite as primary database in production since 2022 across many control-plane shards, plus a backup pipeline running since early 2023 and a 19-event incident series in live traffic. That is genuine at-scale usage by one significant infrastructure vendor. The cluster shows no other operators adopting the pattern, no upstream release uptake of the fix, and no third-party deployment evidence.
Mildly overstated resolution and reassurance
The post is unusually candid — it owns the outages, apologises, and quantifies the series — which keeps the gap small. It tilts positive because the strongest assertions are the least verified: that the bug is found, understood and fixed; that the single-writer design is 'exactly how SQLite is meant to be used' when that discipline neither prevented nor detected corruption; and that most shards were never affected, which reassures without addressing how long corruption sat undetected inside the serving path. No post-fix corruption-free interval or detection-latency figure is offered.
Sole source is the affected vendor explaining its own outages
Every fact in this cluster comes from the company whose reliability failed, published on its own blog. It has clear incentive to locate root cause upstream in SQLite, to credit itself with finding the bug, to emphasise that keys and traffic were never exposed and that most shards were untouched, and to declare the matter closed. Those incentives are visible in the framing rather than hidden, and the post does disclose damaging specifics (19 events, hour-plus outages, months without a root cause), but no independent counterweight exists in the cluster.
Internally consistent but single-sourced and truncated
The mechanics that matter for readers — architecture, detection path, recovery behaviour, blast radius, event count — are stated plainly and hang together, so the descriptive claims can be relied on. Confidence is held back by single-publisher sourcing from an interested party, the truncated body that omits the bug mechanism, and the absence of any post-fix verification or quantified detection latency.
build
Once the question needs a cube, you own the parser1 distinct publisher
build
The streaming edit is a software layer: proxies, stubs and an ffmpeg hook on storage you own1 distinct publisher
build
Object or file storage: the wrong pick stays quiet until inode exhaustion1 distinct publisher
build
The 300-monitor wall is real, and sharding Uptime Kuma is a bill you keep paying1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
1 article · August 23, 2026