Build1 distinct publisher3 min readUpdated
Compaction failed sixty times an hour on a full volume while dashboards stayed correct, because queries are served from memory. Liveness checks cannot see durability.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
On 13 August, a Prometheus instance stopped writing blocks to disk, and its TSDB compaction started failing once a minute with "no space left on device" and never stopped [2]. Sixty failures an hour is not degradation, it is every single attempt [3], and none of it registered on any instrument pointed at the process: the public status page kept serving correct, moving numbers, every HTTP health check was green, and Grafana kept drawing graphs [4].
The stack is agentic-os, a self-hosted deployment on Railway running Prometheus, Grafana, an OpenTelemetry Collector, a cloudflared tunnel, and a public status API that publishes request, token, and cost numbers for the author's Claude Code usage [1]. It is a personal project, but a real deployment whose entire purpose is to say when something is wrong [c1b].
The structural point is the one worth carrying out of this repo. Prometheus answers queries out of the head block, which lives in memory, so from the outside a database that had persisted nothing for hours was indistinguishable from a healthy one [5]. A health check on a TSDB exercises the read path, and the read path was fine. Durability is a separate subsystem that emits its own signals, and in this stack nothing was scraping prometheus_tsdb_* metrics at all, so there was no series to write an alert rule against [9]. The author found the fault by reading container logs by hand [8].
The usual reassurance does not close the gap either. A restart is not instant data loss, because the head is reconstructed from the write-ahead log [6], but the WAL sat on the same volume that had run out of space [7], which makes "it recovers on restart" a bet on the one resource already exhausted.
The remediation was to scrape Prometheus with Prometheus, cap retention by size rather than time alone, and add a watchdog reporting to Sentry [10], driven by the query sum(increase(prometheus_tsdb_compactions_failed_total[1h])) [11].
Then the alerting path produced a worse failure. Sentry received one event, then nothing for six days [12]. Checked on 19 August, the issue read "last seen five days ago", which is what a cleared transient looks like, and the author nearly closed it [13]. The deduplication state was a module-level set: one notification per process lifetime [14]. The four events that did arrive were four restarts, not four detections [15]. Behind that shape, compaction was still failing sixty times an hour, on the order of 8,640 failed attempts across the silent stretch [1].
The author is precise about the defect: deduplication is correct, since a per-minute failure must not produce 1,440 events a day, and the bug was choosing a window of "forever," which cannot distinguish "happened once" from "still happening" [16][17]. The replacement stores a per-key last-sent timestamp with a 3,600 second interval [18], which caps the same condition at roughly 24 events a day instead of 1,440 [2]. The same code path also carried a cost defect, where the error path cost more than the success path [19].
Four things to check on your own stack, in order of how cheap they are: whether anything scrapes the monitoring system's own TSDB metrics, whether retention is bounded in bytes as well as days, whether the WAL shares the volume you are betting a restart on, and what your dedup does after the first event. Readers clicking through to PR #51 and PR #86 should note the repo's commit messages and code comments are in Italian [20].
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.
agentic-os is a small self-hosted observability stack run on Railway comprising Prometheus, Grafana, an OpenTelemetry Collector, a cloudflared tunnel, and a public status API that publishes three numbers about the author's Claude Code usage: requests, tokens, cost.
The author describes agentic-os as a personal project but a real deployment with real uptime whose entire purpose is to be the thing that tells him when something is wrong.
On 13 August, Prometheus stopped writing blocks to disk; its TSDB compaction started failing with "no space left on device" once a minute and never stopped.
The author characterises sixty compaction failures per hour as not a degradation but every single attempt failing.
During the failure the public status page kept serving correct, moving numbers, every HTTP health check was green, and Grafana kept drawing graphs.
Prometheus answers queries out of the head block, which lives in memory, so from the outside a database that had not persisted anything in hours was indistinguishable from a healthy one; the failure was invisible to every instrument pointed at it.
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 but wholly self-reported single source
The account is unusually concrete for its genre: a dated onset, the verbatim 'no space left on device' error, the exact metric family that was unscraped, the PromQL watchdog query, before/after code for the throttle, and two linked PRs. Against that, there is exactly one publisher and one observer, no dashboards, logs, disk-usage figures or third-party confirmation are shown, and the mechanism claims (head-block queries masking a persistence stall; WAL on the exhausted volume) are stated from experience rather than demonstrated. Enough to credit the failure mode; not enough to audit the incident.
One personal deployment, one operator
Observed adoption is a single self-hosted hobby stack on Railway with one operator and no reported users beyond a public status page, plus two pull requests in that same repository. There is no third-party usage, no reuse of the watchdog pattern reported elsewhere, and no figures on traffic or dependents in the supplied material, so the footprint is real but minimal.
Slightly understated relative to the lesson's reach
The write-up makes no product, performance or market claims and repeatedly discounts itself ('personal project', 'embarrassing in hindsight'), while the two transferable findings — liveness checks cannot observe durability when queries are served from memory, and an unbounded dedup window makes a live fault look resolved — apply far beyond one hobby stack. Framing therefore sits marginally below the evidence rather than above it; the negative reading is small because the underlying evidence is single-source and the incident specifics remain uncorroborated.
Sponsored contest entry featuring the tool it fixes
The post opens by declaring itself a submission to DEV's Summer Bug Smash 'powered by Sentry', and the remediation it showcases is built on Sentry, so the narrative benefits both the author (contest visibility, repository attention) and the named sponsor. Mitigating factors keep this mid-range rather than high: the sponsorship is disclosed up front, the piece is critical of the author's own Sentry integration rather than promotional about the product, and it volunteers an inconvenient caveat that the repository's commit prose is Italian and untranslated.
Mechanism credible, incident uncorroborated
Confidence is moderate: the technical mechanism and the code-level fix are specific, internally consistent and consistent with how Prometheus TSDB and head-block querying are generally understood, which supports the transferable lessons. But the cluster has a single publisher with a disclosed sponsor incentive, all incident timings and counts are self-reported, and no post-fix verification is offered, so the specific narrative should be held loosely.
build
One alert, two causes, four green dashboards: the day the stack agreed and was wrong1 distinct publisher
build
Five pods green, GPU at 99 percent, queue up 70x: the Kubernetes dashboard is the wrong instrument1 distinct publisher
build
The duplicate def that ate the trim, and the lint rule nobody was running1 distinct publisher
build
AI-written code fails the same four ways, and every gate you own reports green1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 19, 2026