Coder is an open-source cloud development environment (CDE) platform that provisions on-demand workspaces on Kubernetes, cloud VMs, or bare metal — all defined as Terraform templates. Engineering teams use it to give every developer a reproducible, right-sized cloud environment without managing local tooling or waiting for IT provisioning.
But when Coder's infrastructure wobbles, the impact is immediate and broad: every developer on the platform loses their workspace simultaneously. In this tutorial you'll set up comprehensive monitoring for Coder's critical paths using Vigilmon — free tier, no credit card required.
Why Coder deployments need external monitoring
Coder's internal metrics (Prometheus metrics at /api/v2/metrics, Grafana dashboards) tell you what Coder thinks is happening. External monitoring tells you what developers actually experience.
The gap matters more than you might think:
- Coder API unreachable — the
coderdprocess crashes or the reverse proxy in front of it goes down; existing workspaces may continue running but nobody can connect, provision new ones, or even log in - Agent connectivity broken — Coder agents run inside workspaces and phone home through DERP relay servers; if DERP is misconfigured or blocked, connections hang silently while the workspace status shows
Running - Template provisioning timeout — a Terraform template apply hangs waiting for a cloud API or a slow container registry; Coder marks the workspace as
Startingindefinitely - Resource quota exhaustion — when a team hits its Kubernetes namespace quota, new workspace provisioning fails with cryptic errors that Coder surfaces only on the workspace detail page
- Web terminal / VS Code proxy failing — Coder proxies IDE connections through its server; if the proxy layer breaks, developers see authentication errors or blank screens even though the workspace is healthy
External monitoring from multiple regions catches the class of failures that affect users before Coder's own alerting fires.
What you'll need
- A running Coder deployment (any version — self-hosted or Coder-managed)
- Access to the Coder API (your deployment URL)
- A free Vigilmon account — sign up takes 30 seconds
Step 1: Monitor the Coder API health endpoint
Coder exposes a built-in health endpoint that checks whether the core service is operational:
# Check Coder health
curl -s https://coder.example.com/healthz
# {"status":"ok"}
# Or the more detailed API health check (requires auth)
curl -s -H "Coder-Session-Token: $CODER_TOKEN" \
https://coder.example.com/api/v2/deployment/config
The unauthenticated /healthz endpoint is ideal for external monitoring because it returns a non-200 status if any critical Coder component is unhealthy.
In Vigilmon:
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS
- URL:
https://coder.example.com/healthz - Interval: 1 minute
- Expected status code:
200 - (Optional) Response body contains:
"status":"ok" - Save the monitor
Vigilmon probes from multiple geographic regions. If coderd crashes or its proxy goes down anywhere, you'll know within seconds across all regions — not when the first developer files a ticket.
Also monitor the login page
The login page exercises Coder's authentication stack, which is separate from the API health path:
- Add another HTTP monitor
- URL:
https://coder.example.com/login - Expected status:
200 - Save
A login page outage means developers can't authenticate even if the backend API is fine — database connectivity issues or session store failures often manifest here first.
Step 2: Monitor workspace build health
Workspace build health tracks whether Coder can successfully apply Terraform templates to create workspaces. When this breaks, your developers are blocked.
The Coder API exposes build history you can query:
# Get recent workspace builds (requires auth token)
curl -s -H "Coder-Session-Token: $CODER_TOKEN" \
"https://coder.example.com/api/v2/workspacebuilds?limit=10" | \
jq '[.workspacebuilds[] | {workspace: .workspace_name, status: .status, transition: .transition}]'
Set up a probe script that checks recent build success rates and sends a heartbeat to Vigilmon only when builds are succeeding:
#!/usr/bin/env bash
# coder-build-probe.sh — run every 5 minutes via cron
CODER_URL="https://coder.example.com"
CODER_TOKEN="${CODER_SESSION_TOKEN}"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/YOUR_HEARTBEAT_ID"
# Get builds from the last 30 minutes
recent_builds=$(curl -s -H "Coder-Session-Token: $CODER_TOKEN" \
"${CODER_URL}/api/v2/workspacebuilds?limit=20" | \
jq '[.workspacebuilds[] | select(.status == "failed")] | length')
if [ "$recent_builds" -gt 3 ]; then
echo "Too many failed builds: $recent_builds in last 20"
exit 1
fi
# Send heartbeat — all clear
curl -s "${HEARTBEAT_URL}"
In Vigilmon, create a Heartbeat monitor with a 10-minute grace window. If the probe script stops reporting — because build failures spiked, the Coder API is unreachable, or the probe host is down — Vigilmon fires an alert.
Step 3: Monitor template provisioning latency
Template provisioning latency is the wall-clock time from "workspace start requested" to "workspace agent connected." Teams expect this to be under 2 minutes for warm builds; cold builds with large container images can take 5–10 minutes.
When latency exceeds acceptable thresholds, something in the provisioning pipeline is degraded — slow cloud APIs, overloaded Kubernetes schedulers, or a misconfigured Terraform provider.
Create a provisioning probe that times a real workspace creation:
#!/usr/bin/env bash
# coder-provision-probe.sh
CODER_URL="https://coder.example.com"
CODER_TOKEN="${CODER_SESSION_TOKEN}"
TEMPLATE_NAME="probe-template"
WORKSPACE_NAME="monitor-probe-$(date +%s)"
MAX_WAIT=300 # 5-minute SLA
HEARTBEAT_URL="https://vigilmon.online/heartbeat/YOUR_LATENCY_HEARTBEAT_ID"
# Create workspace
start_time=$(date +%s)
coder create "$WORKSPACE_NAME" \
--template "$TEMPLATE_NAME" \
--parameter "region=us-east-1" \
--yes 2>&1
if [ $? -ne 0 ]; then
echo "Workspace creation request failed"
exit 1
fi
# Poll until workspace is running or timeout
while true; do
elapsed=$(( $(date +%s) - start_time ))
if [ $elapsed -gt $MAX_WAIT ]; then
echo "Provisioning timed out after ${elapsed}s"
coder delete "$WORKSPACE_NAME" --yes
exit 1
fi
status=$(coder show "$WORKSPACE_NAME" --output json | jq -r '.latest_build.status')
if [ "$status" = "running" ]; then
echo "Workspace ready in ${elapsed}s"
break
elif [ "$status" = "failed" ]; then
echo "Workspace build failed"
coder delete "$WORKSPACE_NAME" --yes
exit 1
fi
sleep 10
done
# Report success
curl -s "${HEARTBEAT_URL}" -d "elapsed_seconds=$(( $(date +%s) - start_time ))"
# Clean up
coder delete "$WORKSPACE_NAME" --yes
Run this probe every 15 minutes from a cron job outside the Coder deployment — on a separate VM or in your CI/CD system. The heartbeat's 20-minute grace window means one missed run triggers an alert.
Step 4: Monitor agent connectivity via DERP relays
Coder's workspace agents communicate with coderd through a peer-to-peer Tailscale-based network, using DERP (Designated Encrypted Relay for Packets) servers when direct connections fail. If your DERP servers are unreachable, all IDE connections and web terminal sessions break.
Check your DERP server health:
# Coder exposes DERP server health via the API
curl -s -H "Coder-Session-Token: $CODER_TOKEN" \
"https://coder.example.com/api/v2/debug/derp" | \
jq '.regions | to_entries[] | {region: .key, healthy: .value.healthy}'
If you run a custom DERP server alongside Coder, monitor it directly:
- In Vigilmon, go to Monitors → New Monitor
- Choose TCP Port
- Host:
derp.example.com, Port:3478(STUN) or443(HTTPS DERP) - Interval: 1 minute
- Save
Also add an HTTP check:
- Choose HTTP / HTTPS
- URL:
https://derp.example.com/derp/latency-check - Expected status:
200 - Save
Step 5: Monitor resource quota utilization
Resource quota exhaustion is a silent killer for Coder platforms. When a team hits its Kubernetes namespace quota, new workspaces fail immediately — but existing workspaces continue running, so the problem isn't obvious until someone tries to start a workspace.
Expose quota utilization as a health endpoint via a small probe service:
# quota-probe.py — deploy in your Coder namespace
from flask import Flask, jsonify
from kubernetes import client, config
app = Flask(__name__)
@app.route('/quota-health')
def quota_health():
config.load_incluster_config()
v1 = client.CoreV1Api()
quota_list = v1.list_resource_quota_for_all_namespaces()
warnings = []
for quota in quota_list.items:
namespace = quota.metadata.namespace
if not namespace.startswith('coder-'):
continue
for resource, hard_limit in quota.spec.hard.items():
used = quota.status.used.get(resource, '0')
# Parse and check if used > 80% of hard limit
# (simplified — production code should parse Kubernetes quantity strings)
warnings.append(f"{namespace}/{resource}: {used}/{hard_limit}")
return jsonify({
'status': 'ok',
'quota_summary': warnings,
'timestamp': __import__('datetime').datetime.utcnow().isoformat()
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Then monitor http://quota-probe.coder-system.svc.cluster.local:8080/quota-health (or expose it via Ingress) with Vigilmon expecting a 200 response.
For the alert channels, go to Alert Channels → Add Channel in Vigilmon and configure:
- Email — platform team on-call address
- Webhook — your Slack
#platform-alertschannel or PagerDuty integration
Putting it all together
| Monitor | Type | What it catches |
|---------|------|-----------------|
| https://coder.example.com/healthz | HTTP | Core coderd service crashes, proxy failures |
| https://coder.example.com/login | HTTP | Auth stack failures, session store issues |
| Workspace build heartbeat | Heartbeat | Build failure rate spikes |
| Provisioning latency heartbeat | Heartbeat | Template apply hangs, slow cloud APIs |
| derp.example.com:443 | TCP | DERP relay reachability for agent connectivity |
| http://quota-probe/quota-health | HTTP | Resource quota exhaustion |
Set all HTTP and TCP monitors to 1-minute intervals. Use 10-minute grace windows for build heartbeats and 20-minute windows for provisioning latency heartbeats.
What's next
- SSL certificate monitoring — Coder's TLS certificate is critical; a lapsed certificate breaks all developer connections immediately. Vigilmon monitors expiry and alerts you 30 days in advance
- Multi-region deployments — if you run Coder in multiple regions for low-latency workspace provisioning, set up separate monitors per region and a grouped status page so platform teams can identify regional failures instantly
- Heartbeat for scheduled workspace auto-stop — Coder's auto-stop feature saves costs; monitor that the scheduler is actually stopping idle workspaces by tracking whether it fires on schedule via a Vigilmon heartbeat
Get started free at vigilmon.online — no credit card, monitors start running in under a minute.