Monitoring Deno Deploy with Vigilmon
Deno Deploy runs your TypeScript and JavaScript at the edge in 35+ regions worldwide. Deployments are instant, there's no Docker to manage, and the global distribution means low latency for users everywhere.
But global distribution also means global failure modes. An edge function that errors in Tokyo may still respond correctly in Frankfurt. A deployment that breaks an import path silently affects all regions simultaneously. Standard application logs don't tell you whether users in a specific region are hitting errors right now.
Vigilmon gives you an external health check that probes your Deno Deploy endpoint from multiple locations and alerts you the moment something breaks — regardless of which region fails first.
Note: This tutorial covers Deno Deploy — the hosted edge deployment platform by Deno. For monitoring a self-hosted Deno application on your own server, the patterns are different. This guide is specifically for the Deno Deploy hosting platform.
What You'll Build
- A
/healthhandler inside your Deno Deploy project - A Vigilmon HTTP monitor targeting your
.deno.devendpoint - Alert channels for deployment failure and regional degradation
- A heartbeat monitor for Deno Deploy Cron
Prerequisites
- A Deno Deploy project (linked to a GitHub repo or via
deployctl) - A free account at vigilmon.online
Step 1: Add a health handler to your Deno Deploy project
Deno Deploy uses a single entry file with a Deno.serve() handler. Add a /health route that checks your real dependencies.
main.ts (Deno Deploy entry file):
import { serve } from "https://deno.land/std@0.224.0/http/server.ts";
// Replace with your actual KV or external dependency
const kv = await Deno.openKv();
serve(async (req: Request): Promise<Response> => {
const url = new URL(req.url);
if (url.pathname === "/health") {
return await handleHealth(req);
}
// ... rest of your routing
return new Response("Not found", { status: 404 });
});
async function handleHealth(_req: Request): Promise<Response> {
const checks: Record<string, string> = {};
let ok = true;
// Deno KV probe — write and read a sentinel key
try {
const key = ["_health", "probe"];
await kv.set(key, "1", { expireIn: 60_000 });
const result = await kv.get<string>(key);
checks.kv = result.value === "1" ? "ok" : "read_mismatch";
if (checks.kv !== "ok") ok = false;
} catch (err) {
checks.kv = `error: ${(err as Error).message}`;
ok = false;
}
// External API probe (replace with your real dependency)
try {
const resp = await fetch("https://api.example.com/ping", {
signal: AbortSignal.timeout(3_000),
});
checks.upstream = resp.ok ? "ok" : `http_${resp.status}`;
if (!resp.ok) ok = false;
} catch (err) {
checks.upstream = `error: ${(err as Error).message}`;
ok = false;
}
return Response.json(
{
status: ok ? "ok" : "degraded",
region: Deno.env.get("DENO_REGION") ?? "unknown",
checks,
},
{ status: ok ? 200 : 503 }
);
}
Deno Deploy injects DENO_REGION automatically — include it in your health response so Vigilmon's check logs tell you exactly which edge region degraded.
Deploy your change:
# Via deployctl
deployctl deploy --project=my-project main.ts
# Or push to your linked GitHub repo — Deno Deploy auto-deploys on every push
git push origin main
Your health endpoint is available at:
https://my-project.deno.dev/health
Step 2: Add Vigilmon HTTP Monitor
- Log in to Vigilmon and click New Monitor → HTTP
- URL:
https://my-project.deno.dev/health - Check interval: 1 minute (paid) or 5 minutes (free)
- Response timeout: 10 seconds
- Expected status:
200 - Under Advanced, enable JSON body assertion:
- Path:
status - Expected value:
ok
- Path:
- Save
Vigilmon now probes your Deno Deploy endpoint from multiple external locations and alerts you the moment it returns a non-200 response or "status": "degraded".
Alert channels
Go to Notifications → New Channel and configure:
- Email — your on-call address
- Webhook — Slack incoming webhook or PagerDuty endpoint for team visibility
Step 3: Catching deployment failures
Deno Deploy deployments are atomic — a new deployment either succeeds or fails, and traffic switches instantly. If a deployment breaks an import or introduces a runtime error, all your users are affected simultaneously.
Vigilmon will catch this within the first check interval after deployment.
To minimize risk, use Deno Deploy Preview deployments for testing before production:
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Deno Deploy
uses: denoland/deployctl@v1
with:
project: my-project
entrypoint: main.ts
When a deployment causes Vigilmon to alert, roll back by redeploying the previous commit:
# Find the previous successful deployment hash
git log --oneline -5
# Redeploy the previous version
git revert HEAD --no-commit
git commit -m "revert: roll back broken deployment"
git push origin main
Step 4: Cron job heartbeat monitoring
Deno Deploy supports Cron for scheduled tasks. If your cron handler fails silently, standard HTTP monitoring won't catch it.
Add a Vigilmon heartbeat ping at the end of each successful cron run:
// main.ts — cron handler
Deno.cron("data-sync", "*/15 * * * *", async () => {
try {
await runDataSync();
// Ping Vigilmon heartbeat only on success
const heartbeatUrl = Deno.env.get("VIGILMON_CRON_HEARTBEAT");
if (heartbeatUrl) {
await fetch(heartbeatUrl, { method: "GET" });
}
console.log("Cron: data-sync complete");
} catch (err) {
console.error("Cron: data-sync failed", err);
// Do NOT ping heartbeat — Vigilmon will alert on missing ping
}
});
async function runDataSync() {
// your scheduled work
}
Store the heartbeat URL in Deno Deploy's environment variable settings:
- Go to Deno Deploy dashboard → your project → Settings → Environment Variables
- Add
VIGILMON_CRON_HEARTBEAT=https://vigilmon.online/heartbeat/your-monitor-id
In Vigilmon, create a Heartbeat Monitor:
- Click New Monitor → Heartbeat
- Set the expected interval to match your cron schedule (e.g., 15 minutes)
- Set the grace period to
20 minutes - Copy the ping URL into your Deno Deploy env var
If Vigilmon doesn't receive a ping within the grace period, it fires an alert.
Step 5: Custom domain monitoring
If you use a custom domain with Deno Deploy, add a second Vigilmon monitor for the custom domain alongside the .deno.dev monitor:
- Add a monitor for
https://api.yourdomain.com/health - This catches DNS misconfiguration and TLS certificate issues that a
.deno.devmonitor won't detect
Group both monitors under a single Status Page — visitors see one aggregate status without knowing your internal infrastructure.
What Vigilmon catches that Deno's dashboard misses
| Scenario | Deno Deploy Dashboard | Vigilmon |
|---|---|---|
| New deployment breaks an import | Shows error in logs after the fact | HTTP monitor alerts within 1 minute |
| Edge function errors in one region | Aggregated across all regions | Per-check log shows failing region |
| Deno KV write failure | Requires log analysis | /health KV probe alerts immediately |
| Cron job stops running | No built-in alerting | Heartbeat grace period alerts |
| Custom domain DNS issue | Not monitored | Custom domain monitor catches it |
Deno Deploy is fast and globally distributed, but it still fails. External monitoring from Vigilmon gives you the independent vantage point you need to catch failures before your users file bug reports.
Set up monitoring for your Deno Deploy project today — register free at vigilmon.online.