Skip to content
Hallway is out (npm i -g hallway): v0, v1 and v2 have shipped, apart from checking it all on a real Mac. See the roadmap.

Health states

Every app has one current state v0. In the dashboard each state is shown with a colour, a shape and a word, never colour alone, and in the hallway imagery as a door.

StateMeaningDoorTone
● healthyResponding as expectedAjar, a sliver of warm light showingCalm, positive
▲ unhealthyListening but failing: HTTP 5xx, the health path not answering as expected, or a timeoutLight flickering behind itWarning
■ downShould be running, and is not listeningDark, boarded upAlarm: the only red state
○ stoppedNot listening, and that is fineClosedNeutral, quiet
◌ unknownNot probed yetIn shadowNeutral

A managed service that has just been started shows a short-lived ◐ starting for a grace period (30 seconds by default) before “not listening” counts as down.

The key rule. A slide deck you are not using today must not glow red. Only apps you said should be running can be down; everything else that isn’t listening is calmly stopped. What you expect of an app is its expected field:

expectedWhen it isn’t listening
runningIt should always be up: down
adhocUp sometimes: stopped
stoppedIntentionally off: stopped

A managed service you stopped yourself is stopped too. Uptime percentages exclude stopped time: being off on purpose is not downtime.

Every 60 seconds (every 15 while a dashboard is open, so the page feels live), with a little jitter and a limit on how many run at once, each declared and discovered app is probed:

  1. TCP connect to its host and port, with a one-second timeout. No answer means not listening: down, stopped or starting, per the tables above.
  2. If the app has a health.path, Hallway sends GET <path>. The expected status (by default any 2xx) means healthy; anything else means unhealthy.
  3. Otherwise it sends GET /. Anything below 500 is healthy. Redirects, 401 and 403 count as healthy: an app behind a login page is up. A 5xx, or no response within five seconds, is unhealthy.

Probes don’t follow redirects, use GET rather than HEAD (some dev servers mishandle HEAD), measure latency to the response headers, send User-Agent: hallway/<version>, and send the upstream’s own Host so apps that check it answer normally.

Flap damping: an app needs two failed probes in a row to leave healthy, and one success to come back.

Each probe is recorded: the state, the HTTP status and the latency.

  • v0 The last 24 hours at full resolution, drawn on every card as 48 bars of 30 minutes each.
  • v0 7-day and 90-day history from hourly rollups (with p50/p95 latency and a latency chart), in the app’s detail drawer. The 90-day view reads only the rollups, so it stays quick: a few milliseconds per app with 30 apps and 90 days of history.

Periods when Hallway itself was not running are drawn as no data, an empty outline, never as down.

v0 The dashboard’s tab title counts problems, so a pinned tab works as a passive monitor without any notification system:

Hallway everything fine
(1 down) Hallway
(2 down · 1 unhealthy) Hallway

The tab’s favicon gets a small status mark too. Only down and unhealthy count; stopped never does. Both update live, so a background tab changes the moment an app falls over.