VACVAC
Apps

Health checks

How VAC gates deploys on health, and how it detects crash-loops and OOM kills.

2 min readUpdated June 15, 2026Edition · v0.5.xBeta

VAC doesn't flip a deploy to "running" until it has proof the new version is serving. Because the control plane can't reach app containers directly (it's off the edge network), that proof comes from Caddy.

Deploy health gating

After bringing the new stack up and syncing routes, VAC polls Caddy's /reverse_proxy/upstreams admin endpoint until every routable service reports healthy — or it times out. Caddy runs active health checks against each service's health path.

SettingDefault
Health path/ (per-service, configurable)
Healthy responseHTTP 2xx or 3xx
Check interval5 seconds
Overall gate budget~30 seconds

You can set a custom health path per service (e.g. /healthz, /api/health) from its settings; the change re-syncs Caddy immediately, no redeploy required.

Outcomes

  • running — upstreams went healthy within the budget. The deploy is live.
  • degraded — the stack came up but never passed health checks. The app is recorded as degraded and you're notified; the previous version, if any, keeps serving.
  • error — a build or preflight failure before the stack ever came up.
Workers don't get health checks

Only services with an HTTP port are routed and health-checked. Background workers, queues, and databases have no route and don't gate the deploy.

Auto-restart

VAC's generated stacks restart containers automatically when they exit, so a transient crash recovers on its own. What you don't want is a container that crashes, restarts, crashes again, forever — which is where crash-loop detection comes in.

Crash-loop detection

VAC watches container death events. If a service restarts 5 times within 2 minutes, VAC considers it crash-looping:

  • it stops the service (rather than letting it thrash the box),
  • marks it crash-loop,
  • writes a system log line explaining why,
  • and fires a notification.

Restarting the service from the dashboard clears the flag and resets the counter.

OOM kills

If a container is killed by the kernel's out-of-memory killer (exit code 137), VAC confirms the OOM, increments the service's OOM counter, and notifies you once per episode — often the signal that you need a higher (or a first) memory limit.

Certificate expiry

Separately from app health, VAC checks managed certificates daily and warns you 14 days before any expires without having renewed — so a stuck renewal surfaces as an alert, not an outage.

Next

On this page