Prisma is the most popular ORM for Node.js and TypeScript, used with PostgreSQL, MySQL, SQLite, and MongoDB. Your app code trusts Prisma to bridge the gap to the database — but when the database goes down, the connection pool exhausts, or a migration leaves the schema out of sync, your API starts throwing errors with no proactive alert. Vigilmon gives you uptime checks, database health probes, and alerting to catch infrastructure failures before they cascade into user-facing downtime.
What You'll Set Up
- HTTP health endpoint that verifies Prisma database connectivity
- Uptime monitor for API servers using Prisma
- TCP port monitor for the database server
- Cron heartbeat for Prisma-powered background workers
- SSL monitoring for database admin interfaces
Prerequisites
- Prisma Client installed and configured (
@prisma/client) - A backend API (Express, Fastify, NestJS, or similar) using Prisma
- A free Vigilmon account
Step 1: Add a Database Health Check Endpoint
The most important thing to monitor with Prisma is actual database connectivity. A /health endpoint that calls Prisma's $queryRaw lets Vigilmon verify the full connection path — connection pool, credentials, and network — on every probe:
Express
import express from 'express';
import { PrismaClient } from '@prisma/client';
const app = express();
const prisma = new PrismaClient();
app.get('/health', async (req, res) => {
try {
// Lightweight DB ping — uses an existing connection from the pool
await prisma.$queryRaw`SELECT 1`;
res.json({
status: 'ok',
database: 'connected',
uptime: process.uptime(),
});
} catch (err) {
res.status(503).json({
status: 'error',
database: 'unreachable',
detail: err.message,
});
}
});
app.listen(3000);
Fastify
import Fastify from 'fastify';
import { PrismaClient } from '@prisma/client';
const app = Fastify();
const prisma = new PrismaClient();
app.get('/health', async (request, reply) => {
try {
await prisma.$queryRaw`SELECT 1`;
return { status: 'ok', database: 'connected' };
} catch (err) {
return reply.status(503).send({ status: 'error', detail: err.message });
}
});
app.listen({ port: 3000 });
NestJS
// health.controller.ts
import { Controller, Get } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Controller()
export class HealthController {
constructor(private prisma: PrismaService) {}
@Get('health')
async health() {
try {
await this.prisma.$queryRaw`SELECT 1`;
return { status: 'ok', database: 'connected' };
} catch (err) {
throw new ServiceUnavailableException({ status: 'error', detail: err.message });
}
}
}
SELECT 1 is the lightest possible query — it does not touch any table or trigger any application logic, but it does traverse the full Prisma → connection pool → database path.
Step 2: Add Connection Pool Metrics to the Health Check
Prisma's connection pool can silently exhaust under load, causing new requests to hang. Add pool metrics to your health endpoint to detect exhaustion before it causes downtime:
app.get('/health', async (req, res) => {
try {
await prisma.$queryRaw`SELECT 1`;
// $metrics is available in Prisma 4+ with the metrics preview feature
// Enable in schema.prisma: previewFeatures = ["metrics"]
const metrics = await prisma.$metrics.json();
const poolWaiting = metrics.counters.find(
c => c.key === 'prisma_pool_connections_idle'
);
res.json({
status: 'ok',
database: 'connected',
pool: poolWaiting?.value ?? 'unknown',
uptime: process.uptime(),
});
} catch (err) {
res.status(503).json({ status: 'error', detail: err.message });
}
});
Enable Prisma metrics in schema.prisma:
generator client {
provider = "prisma-client-js"
previewFeatures = ["metrics"]
}
Step 3: Add Vigilmon Monitors
Monitor 1: API Health Endpoint
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter:
https://api.yourdomain.com/health - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Optionally set Response must contain to
"database":"connected". - Click Save.
The response body check ensures the monitor distinguishes a running-but-database-disconnected server from a fully healthy one.
Monitor 2: TCP Port for the Database Server
Even if your API's health endpoint fails, knowing whether the database port is reachable narrows the diagnosis. Add a TCP monitor directly to the database host:
- Click Add Monitor → TCP Port.
- Set Host to your database server IP (e.g.
db.internal.yourdomain.comor a private IP). - Set Port to:
- PostgreSQL:
5432 - MySQL / PlanetScale:
3306 - MongoDB:
27017
- PostgreSQL:
- Set Check interval to
1 minute. - Click Save.
If the TCP monitor fails but the API health endpoint is up, the database connection pool is caching stale connections — a Prisma restart will fix it. If both fail, the database host is unreachable.
Step 4: Heartbeat for Prisma-Based Background Workers
Many Prisma apps run background jobs that write to the database — queue processors, scheduled tasks, data sync workers. Use a Vigilmon heartbeat to confirm these workers are alive:
- In Vigilmon, click Add Monitor → Cron Heartbeat.
- Set the expected ping interval to match your job frequency.
- Copy the heartbeat URL.
- Add the heartbeat call at the end of each successful job run:
import fetch from 'node-fetch';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const HEARTBEAT_URL = 'https://vigilmon.online/heartbeat/YOUR_KEY';
async function processJob() {
// ... read from DB, process, write results
const items = await prisma.job.findMany({ where: { status: 'pending' } });
for (const item of items) {
await processItem(item);
await prisma.job.update({ where: { id: item.id }, data: { status: 'done' } });
}
// Signal Vigilmon that the job completed successfully
await fetch(HEARTBEAT_URL).catch(() => {});
}
If the job throws (e.g. due to a database constraint violation), it never pings, and Vigilmon alerts after the expected interval.
Step 5: Monitor Database Admin Interfaces
If you run Prisma Studio, pgAdmin, or Adminer for database management, add uptime monitors for those interfaces:
# Prisma Studio (default port)
http://localhost:5555
# pgAdmin
https://admin.yourdomain.com
# Adminer
https://db-admin.yourdomain.com
For publicly accessible admin interfaces, also enable SSL monitoring:
- Open the monitor for the admin interface.
- Enable Monitor SSL certificate.
- Set Alert when certificate expires in less than
21 days. - Click Save.
Step 6: Migration Drift Detection
Prisma migrations can drift in production if a migration is applied partially or if schema changes are made directly to the database. Add a heartbeat for your CI/CD migration step so you know migrations ran:
# Example: GitHub Actions migration step with Vigilmon heartbeat
- name: Run Prisma migrations
run: |
npx prisma migrate deploy
curl -s https://vigilmon.online/heartbeat/MIGRATION_KEY
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
If prisma migrate deploy fails, the curl is never reached, and the heartbeat misses its expected ping.
Step 7: Alert Configuration
- Go to Alert Channels in Vigilmon and add Slack, email, or PagerDuty.
- Set Consecutive failures before alert to
2on the API health monitor — a single probe can catch a transient connection error. - Set Consecutive failures before alert to
1on the TCP database monitor — database port closure is never transient. - Suppress alerts during maintenance windows or migrations:
curl -X POST https://vigilmon.online/api/maintenance \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"monitor_id": "YOUR_MONITOR_ID", "duration_minutes": 10}'
npx prisma migrate deploy
Summary
| Monitor | Target | What It Catches |
|---|---|---|
| API health endpoint | /health with SELECT 1 | Database connectivity failure |
| TCP port | DB host :5432 / :3306 | Database server down |
| SSL certificate | API / admin domain | TLS cert expiry |
| Cron heartbeat | Background worker | Job crash, missed schedule |
| CI heartbeat | Migration step | Failed or skipped migration |
Prisma is a powerful abstraction — but abstractions don't monitor themselves. With a SELECT 1 health probe, a direct TCP check on the database port, and heartbeats on your background workers, you have full visibility into your Prisma-backed infrastructure from the ORM layer down to the database server.