How to Monitor Your PostgreSQL Database with Vigilmon
PostgreSQL is the world's most advanced open-source relational database, trusted by companies from startups to Fortune 500s. But even the most reliable database can have issues — slow queries, connection pool exhaustion, replication lag, or an outright crash. When that happens at 2 AM, you need to know immediately.
This guide shows you how to monitor your PostgreSQL database with Vigilmon, the uptime and endpoint monitoring tool built for developers.
Why PostgreSQL Monitoring Matters
Most applications treat their database as an afterthought when it comes to monitoring. They'll set up uptime checks for their frontend and API, but not the database powering everything underneath.
Here's what can go wrong with PostgreSQL:
-
Connection exhaustion: Too many connections hitting
max_connectionslimit - Slow queries: A single bad query blocking your entire application
- Replication lag: Read replicas falling behind your primary
- Disk pressure: WAL files accumulating, storage running out
- Lock contention: Transactions waiting on each other, creating cascading delays
Setting Up PostgreSQL Monitoring with Vigilmon
Step 1: Create a Health Check Endpoint
The most reliable way to monitor PostgreSQL with Vigilmon is to expose a health check endpoint from your application that tests the database connection:
// Express.js example
app.get('/health/db', async (req, res) => {
try {
const start = Date.now();
await pool.query('SELECT 1');
const latency = Date.now() - start;
if (latency > 1000) {
return res.status(503).json({
status: 'degraded',
latency_ms: latency,
message: 'Database responding slowly'
});
}
res.json({
status: 'ok',
latency_ms: latency
});
} catch (err) {
res.status(503).json({
status: 'error',
message: err.message
});
}
});
# FastAPI example
@app.get("/health/db")
async def database_health():
try:
start = time.time()
await database.execute("SELECT 1")
latency_ms = (time.time() - start) * 1000
if latency_ms > 1000:
raise HTTPException(
status_code=503,
detail={"status": "degraded", "latency_ms": latency_ms}
)
return {"status": "ok", "latency_ms": latency_ms}
except Exception as e:
raise HTTPException(status_code=503, detail={"status": "error", "message": str(e)})
Step 2: Add the Monitor in Vigilmon
- Go to vigilmon.online and sign up for a free account
- Click Add Monitor → HTTP(S) Monitor
- Enter your health endpoint URL:
https://yourapp.com/health/db - Set check interval: 1 minute for production databases
- Configure alerts: email notification within 1 minute of failure
Step 3: Set Response Validation
Vigilmon lets you validate the response body, not just the HTTP status code. Use this to catch degraded states:
-
Status code: Must return
200 -
Response body: Must contain
"status":"ok" - Response time: Alert if over 2000ms (database is struggling)
Monitoring PostgreSQL Replication
If you're running read replicas, you need to monitor replication lag separately:
-- Query to check replication lag (run on replica)
SELECT
now() - pg_last_xact_replay_timestamp() AS replication_lag,
CASE
WHEN now() - pg_last_xact_replay_timestamp() > interval '30 seconds'
THEN 'LAGGING'
ELSE 'OK'
END as status;
Wrap this in a health endpoint and monitor it with a separate Vigilmon check:
app.get('/health/db/replication', async (req, res) => {
const result = await pool.query(`
SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) as lag_seconds
`);
const lagSeconds = result.rows[0].lag_seconds;
if (lagSeconds > 30) {
return res.status(503).json({ status: 'lagging', lag_seconds: lagSeconds });
}
res.json({ status: 'ok', lag_seconds: lagSeconds });
});
Connection Pool Monitoring
Monitor your connection pool to prevent exhaustion:
// pg-pool example
pool.on('connect', () => {
console.log('New client connected');
});
app.get('/health/db/pool', (req, res) => {
const stats = {
total: pool.totalCount,
idle: pool.idleCount,
waiting: pool.waitingCount
};
if (stats.waiting > 10) {
return res.status(503).json({ status: 'congested', ...stats });
}
res.json({ status: 'ok', ...stats });
});
Alert Configuration
For a production PostgreSQL database, set up these Vigilmon alerts:
| Monitor | Check Interval | Alert Threshold |
|---|---|---|
| DB connectivity | 1 min | Immediate on failure |
| Query latency | 1 min | Alert if P95 > 1s |
| Replication lag | 2 min | Alert if lag > 30s |
| Connection pool | 1 min | Alert if waiting > 10 |
Real-World Incident: Catching a Vacuum Bloat
One common PostgreSQL issue is table bloat caused by a blocked VACUUM. Your queries will gradually slow down as dead tuples accumulate.
With Vigilmon's response time tracking, you'll see a gradual increase in your /health/db endpoint response time — a leading indicator that something is wrong before it becomes a user-visible outage.
Summary
PostgreSQL is reliable, but it's not self-monitoring. A simple health check endpoint plus a Vigilmon monitor gives you:
- Instant alerts when your database goes down
- Response time tracking to catch performance degradation early
- Replication monitoring to protect your read replicas
- Connection pool visibility to prevent exhaustion
Get started free at vigilmon.online — no credit card required, monitor up to 5 endpoints on the free plan.
Top comments (0)