Off-the-shelf monitors watch one site at a time and answer “is it up?” An agency maintaining hundreds of Drupal and WordPress sites on Pantheon needs the harder questions answered across the whole estate: which sites are quietly degrading, what changed right before they did, who's already looking at it — and what does the team know that isn't written down anywhere.
The real failure mode of a monitoring tool isn't a missed alert. It's a calm, confident dashboard that has silently stopped watching. Almost every design decision in the product exists to keep it from ever telling that lie: coverage travels with every finding, and a collector that stops running is itself a finding.
No signal
awaiting board screenshot
Statistics, not thresholds
Anomalies are detected with median/MAD robust statistics over each site’s own 90-day history — "cache hit rate dropped" means dropped for this site. A busy Tuesday and a quiet Sunday never get averaged into a lie.
Four tiers, one loud one
Emergency / needs-you / worth-a-look / fine. "Emergency" means a capability is gone right now — a site that can’t send email, a corrupt table, an exposed installer — and it interrupts. Everything else stays calm, so nothing glows when the fleet is healthy.
Prevalence over noise
Reads each site’s own status report across 105 Drupal sites and sorts findings by how many sites share them: a warning on 99 sites is one programme of work, not 99 findings. A warning on three sites is those three being genuinely different.
Remembers what the platform forgets
Pantheon keeps ~14 days of deploy history and 28 days of traffic granularity. V.I.N.CENT has archived 11,000+ workflow events and 4,400+ daily samples that would otherwise be gone — the substrate for "what changed six minutes before the error spike?"
Knowledge lives on the finding
Six operational reactions (looking at this / handled / expected / worse than it looks / root cause found / waiting on someone), threaded conversation, and team-wide pinning. "This spike is a scheduled campaign" is attached to the finding for the next time it fires — not lost in a chat scroll.
Sites you can recognize
Weekly thumbnails rendered by a headless browser turn machine names into pages you know on sight — and catch the page that returns HTTP 200 while rendering blank.
Backend
Headless Drupal 11 on PHP 8.3 — an API-only custom module exposing JSON. It owns the detectors, the data, and every authorization decision. Mandatory two-factor, admin-only account creation, and Drupal’s TFA-bypassing login route removed at the routing layer.
Front end
Next.js 14 static export served from the same Drupal docroot at /app/ — same origin, so the session cookie is first-party and there is no CORS surface.
Collectors
Native Drupal queue workers on cron where possible (uptime probing, the fleet sweep); external scripts where a shell is unavoidable (site logs and status reports over the platform API). A collector that stops running is surfaced, never hidden.
Platform
Deployed on Pantheon via Integrated Composer, with a hard-won respect for its edge cache, 180-second cron budget, and read-only filesystem.
| Decision | Instead of | Because | How it aged |
|---|---|---|---|
| Headless Drupal 11, API-only | A standalone Node/Go API | The detectors, the data, and every authorization decision live in one hardened place — Drupal’s permission system is the authz engine, not a reimplementation of one. | Holding. Every new collector inherits the same gate instead of a fresh mistake. |
| Next.js static export served from the Drupal docroot at /app/ | A separate front-end host | Same origin: the session cookie is first-party and there is no CORS surface at all. | Well. The entire class of CORS/cookie bugs never existed. |
| Median/MAD statistics over each site’s own 90-day history | Global thresholds | “Cache hit rate dropped” must mean dropped for this site — a busy Tuesday and a quiet Sunday must not average into a lie. | The core bet of the product — it is why an alert is worth reading at all. |
| Archive what the platform discards | Query platform APIs on demand | Pantheon keeps ~14 days of deploy history and 28 days of traffic granularity; questions arrive later than the data expires. | 11,000+ events and counting — history the platform itself no longer holds. |
| Collectors run where they must | One uniform collector fleet | Native Drupal queue workers where cron suffices; external scripts only where a shell is unavoidable. The 180-second cron budget is a law, not a suggestion. | Too new to say. The seam between the two is the part watched closest. |
| Four severity tiers, saturation spent on rank | Red / yellow / green | “Emergency” means a capability is gone right now. Everything else stays calm so the loud tier keeps its meaning. | Well. Nothing glows when the fleet is healthy, so people still look when it does. |
Contrast as code
Light and dark themes, both WCAG AA — held by a contrast check that reads the palette from source and flags any text/surface pair below the floor. The palette was once wrong for months in a way nobody could see by looking; now a script can see it.
Severity off the brand axis
A "Slate & Iris" palette — navy-tinted neutrals, iris-violet accent — with severity colors kept deliberately separate from brand colors, so an interactive control can never be misread as an alarm.
Reads like an ops room
shadcn/ui, IBM Plex, persistent sidebar — legible at a desk and across a room on a wall display. Saturation is spent on rank, so the resting state recedes.
An unchecked site must never look like a healthy one.
Coverage travels with every finding — “we looked at 105 of 158; 4 we couldn't read; 42 WordPress sites we can't log-monitor at all.” The most dangerous dashboard is the one that's quietly wrong, and this one was built by someone who knew it.
Need something like this? →