Your Medusa.js store went down. Orders are failing. The checkout flow is returning 502s. Your customers are seeing blank pages and your revenue is bleeding. And you only found out because someone DM'd you on Twitter.
Medusa.js is a powerful open-source headless e-commerce platform built on Node.js. It powers storefronts, subscription flows, multi-warehouse order management, and custom checkout logic — all as composable modules. But "composable" means more moving parts, more surfaces to break, and more silent failures to miss. Vigilmon gives you the external, independent eye that watches your Medusa backend even when you're not.
This tutorial shows you how to add a health endpoint to Medusa and monitor it end-to-end with Vigilmon.
What You'll Build
- A health check endpoint in your Medusa backend (TypeScript)
- A Vigilmon HTTP monitor with JSON body assertion
- A keyword monitor for your storefront API
- Heartbeat monitoring for background workers
Prerequisites
- A Medusa.js backend (v2.x, Node.js 20+)
- A free account at vigilmon.online
Step 1: Add a Health Check Endpoint
Medusa v2 uses a modular architecture with Express under the hood. The cleanest way to add a health endpoint is via a custom API route.
Create the file src/api/health/route.ts:
// src/api/health/route.ts
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const checks: Record<string, string> = {};
let healthy = true;
// 1. Database check via Medusa's query service
try {
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY);
await query.graph({ entity: "product", fields: ["id"], pagination: { take: 1 } });
checks.database = "ok";
} catch (e) {
checks.database = `error: ${(e as Error).message}`;
healthy = false;
}
// 2. Event bus check (Redis or in-memory)
try {
const eventBus = req.scope.resolve("eventBusService");
// A noop emit — just confirms the bus is instantiated and reachable
await eventBus.emit("health.check", {});
checks.event_bus = "ok";
} catch (e) {
checks.event_bus = `error: ${(e as Error).message}`;
// Degrade but don't mark unhealthy for event bus issues unless critical
}
res.status(healthy ? 200 : 503).json({
status: healthy ? "ok" : "degraded",
checks,
ts: new Date().toISOString(),
});
};
This route is automatically registered at GET /health by Medusa's file-based router.
Test it locally:
curl http://localhost:9000/health
Expected response:
{
"status": "ok",
"checks": {
"database": "ok",
"event_bus": "ok"
},
"ts": "2026-01-15T10:23:00.000Z"
}
If your store is already using a /health route for Kubernetes liveness probes, add a deeper /health/deep route using the same pattern for Vigilmon to hit.
Step 2: Monitor the Health Endpoint with Vigilmon
- Log in to Vigilmon and click New Monitor → HTTP.
- Set URL to
https://api.your-store.com/health. - Set Check interval to 60 seconds.
- Set Expected status code to
200. - Under Advanced → JSON body assertion, add:
- Path:
status - Expected value:
ok
- Path:
- Save the monitor.
Vigilmon now polls your health endpoint from multiple external regions every minute. If the database connection pool drains, the event bus crashes, or the server stops responding entirely, you'll receive an alert within 60 seconds.
Step 3: Monitor the Storefront API
Medusa exposes its Store API at /store. A broken auth middleware or a corrupted product module can cause 5xx errors that your health endpoint never sees. Add a second monitor targeting a lightweight Store API call.
- Click New Monitor → HTTP.
- Set URL to
https://api.your-store.com/store/products?limit=1. - Set Expected status code to
200. - Under Advanced → Keyword check, set:
- Keyword present:
"products" - Keyword absent:
"error"
- Keyword present:
- Save.
This catches broken product routes, corrupted module state, and middleware regressions that a database ping won't surface.
Step 4: Alert Channels
Go to Notifications → New Channel in Vigilmon and add:
- Email — immediate alert to your engineering on-call inbox
- Webhook — forward to Slack, PagerDuty, or Discord
For Slack, create an incoming webhook at api.slack.com/apps and paste it into Vigilmon. A down alert looks like:
🔴 DOWN: api.your-store.com/health
Status: 503 Service Unavailable
Region: US-East
3 minutes ago
When the backend recovers:
✅ RECOVERED: api.your-store.com/health
Downtime: 4 minutes
Step 5: Heartbeat Monitor for Background Workers
Medusa's subscriber/workflow system runs background jobs — order processing, inventory sync, email triggers. HTTP monitors can't see these. Use Vigilmon's heartbeat pattern instead.
In any Medusa subscriber or workflow step, ping Vigilmon at the end of each successful run:
// src/subscribers/inventory-sync.ts
import type { SubscriberArgs } from "@medusajs/framework";
export default async function inventorySyncHandler({ event }: SubscriberArgs) {
try {
await runInventorySync();
// Ping Vigilmon heartbeat on success
const heartbeatUrl = process.env.VIGILMON_HEARTBEAT_URL;
if (heartbeatUrl) {
await fetch(heartbeatUrl, { method: "POST" });
}
} catch (error) {
// No ping on failure — Vigilmon will alert on missed ping
throw error;
}
}
async function runInventorySync() {
// your inventory sync logic
}
export const config = {
event: "product.updated",
};
Set the environment variable:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/<your-id>
In Vigilmon, create a Heartbeat Monitor with a grace period slightly longer than your job interval. If the job stops firing — due to a crash, a dead Redis queue, or a misconfigured subscriber — Vigilmon alerts before your inventory drifts.
Step 6: Status Page
Go to Status Pages → New Status Page in Vigilmon. Add both monitors (health endpoint and Store API) and share the public URL. Add the badge to your storefront README:

What You've Built
| Scenario | How Vigilmon catches it |
|---|---|
| Database connection pool exhausted | Health endpoint returns degraded, alert fires |
| Event bus (Redis) goes down | Health endpoint reports event_bus error |
| Broken product module / middleware regression | Store API keyword monitor fails |
| Background inventory sync stops | Heartbeat monitor misses ping, alert fires |
| Entire backend unreachable (crash, OOM, deploy failure) | HTTP timeout on health endpoint |
| Checkout API silent 5xx | Additional monitor on /store/carts endpoint |
Medusa's power comes from its composability — but each module is a potential failure point. Vigilmon gives you the external, independent view that catches what your internal health checks miss.
Start monitoring your Medusa.js store today — register free at vigilmon.online.