DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your PostgreSQL Database with Vigilmon

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_connections limit
  • 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 
    });
  }
});
Enter fullscreen mode Exit fullscreen mode
# 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)})
Enter fullscreen mode Exit fullscreen mode

Step 2: Add the Monitor in Vigilmon

  1. Go to vigilmon.online and sign up for a free account
  2. Click Add MonitorHTTP(S) Monitor
  3. Enter your health endpoint URL: https://yourapp.com/health/db
  4. Set check interval: 1 minute for production databases
  5. 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;
Enter fullscreen mode Exit fullscreen mode

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 });
});
Enter fullscreen mode Exit fullscreen mode

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 });
});
Enter fullscreen mode Exit fullscreen mode

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)