---
title: "Database availability monitoring: Postgres, MySQL | Logdash"
description: "No TCP check needed: a SELECT 1 health route or a heartbeat from the database host, with a Telegram alert when Postgres or MySQL stops answering."
url: https://logdash.io/monitoring/database
---

# Database availability monitoring

Logdash cannot connect to a database itself, so you monitor database availability through something that can: an HTTP health route that runs select 1 and returns 503 when it fails, or a push monitor called by a script on a host next to the database.

Logdash does not open a connection to Postgres or MySQL. Monitors send HTTP GET requests from the public internet, there are no TCP port checks, and private addresses are refused. That sounds like a gap until you look at what a port check proves: that something accepted a TCP handshake on 5432\. Not that your app can log in, not that the pool has a free connection, not that a query comes back.

Your database should not be reachable from the internet in the first place. So the check goes through something that already holds a connection, and there are two honest ways to do that.

## Database uptime monitoring through your app

The best signal is a route in your app that runs the cheapest query the database can answer. It fails for the same reasons a user request fails: credentials rotated without a redeploy, an exhausted pool, a failover your DNS has not caught up with, a database that is simply gone.

 health.js 

```javascript
import express from 'express';
import pg from 'pg';

// In a real app, import the pool your handlers use instead.
const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  connectionTimeoutMillis: 2000, // no free connection in 2 s is a failure
  query_timeout: 2000,
});

const app = express();

app.get('/health/db', async (req, res) => {
  try {
    await pool.query('select 1');
    res.status(200).send('ok');
  } catch {
    res.status(503).send('db');
  }
});

app.listen(3000);
```

Use the pool the handlers use, or the check cannot see that pool running dry. MySQL is the same route with mysql2 and the same query. The 2-second timeouts matter: the Logdash pinger gives up after 10 seconds and records a timeout, but a hung pool should become a 503 you can read, not a timeout you have to guess at.

## Postgres uptime monitoring from the database host

Some databases have no app in front of them: a reporting replica, a self-hosted Postgres on a VPS, a MySQL box only a nightly export touches. Run a small loop on that host, or one next to it, that queries the database and calls a push monitor when the query succeeds. Push monitors are on Pro and expect a call inside every 15-second window.

 db-heartbeat.sh 

```bash
#!/bin/sh
# Password from ~/.pgpass, -w never prompts for one.
# MySQL: mysql -h 127.0.0.1 -u app -e 'select 1' app
PING=https://api.logdash.io/ping/68b4c1f0e3a2d5c7b9f01234

while true; do
  psql -w -h 127.0.0.1 -U app -d app -tAc 'select 1' > /dev/null 2>&1 \
    && curl -fsS -m 5 -X POST "$PING" > /dev/null
  sleep 10
done
```

Query with the credentials your app uses. pg\_isready exits 0 without a valid user or password, and mysqladmin ping exits 0 even on Access denied. Both prove the server process answers, which is less than you think you are checking.

1. **Pick the path** Public app in front of the database: ship the /health/db route. No app, or only a private network: run the heartbeat script under systemd, on Pro.
2. **Create the monitor** For the route, add a monitor with https://yourapp.com/health/db, checked every 5 minutes free, every minute on Builder, every 15 seconds on Pro. For the script, add a push monitor and paste its id.
3. **Stop the database** Connect Telegram and stop Postgres or MySQL. The route returns 503, or the pings stop, and a Telegram alert tells you the monitor is down.

## MySQL uptime monitoring without code

### Logdash vs Uptime Kuma

| Feature                               | Logdash                                              | Uptime Kuma                                                       |
| ------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------- |
| Connect to the database directly      | No, through a health route or a push heartbeat       | PostgreSQL, MySQL/MariaDB, SQL Server, MongoDB and Redis monitors |
| TCP port check                        | None                                                 | Yes                                                               |
| Reach a database on a private network | Only by push, from a host inside it, on Pro          | Directly, when Kuma runs inside that network                      |
| Check the path your users take        | A health route tests app, pool and database together | Same, with an HTTP monitor on the same route                      |
| Who watches the monitor               | Hosted, outside your infrastructure                  | You run it, and on the database box it dies with the database     |
| Alert channels                        | Telegram and webhook                                 | Telegram, Discord, Slack, email and 90+ more                      |

### When Uptime Kuma is the better pick

- You already run a box inside the network and want a database check without touching the app.
- You need TCP port checks, or Redis and MongoDB monitors as well.
- Self-hosting is a requirement. Uptime Kuma runs on your server today, and Logdash self-hosting is not a one-command install yet.

### What is database availability monitoring? 

Checking on a schedule that the database accepts connections and answers queries, and alerting when it stops. The useful version runs a real query with your app's credentials, because a server can accept TCP connections and still refuse your app.

### How do I set up database uptime monitoring without exposing the database? 

Keep the database private and check it through something that already reaches it: an HTTP route in your app that runs select 1, or a script on a nearby host that queries every 10 seconds and pings a push monitor on Pro after each success.

### How does postgres uptime monitoring work in Logdash? 

Through your app or a heartbeat. A /health/db route runs select 1 and returns 503 on failure, checked every 5 minutes free or every 15 seconds on Pro. Or psql in a loop on the host calls a push monitor on Pro. Logdash never connects to port 5432 itself.

### Is mysql uptime monitoring any different? 

Only in the driver. Use mysql2 in the route or the mysql client in the script, with the same select 1\. Do not rely on mysqladmin ping, which exits 0 even when the server answers Access denied.

## Keep reading

[All monitoring guides](https://logdash.io/monitoring): One page per thing you run, each with the code that makes it checkable and the monitor that watches it.

[API uptime monitoring](https://logdash.io/monitoring/api): API uptime monitoring sends a GET to one public route of your API on a fixed interval, records the status code and the response time, and alerts you the moment the answer falls outside 200-399 or does not arrive within 10 seconds.

[REST API monitoring](https://logdash.io/monitoring/rest-api): REST API monitoring means requesting one public GET route that touches the same database your endpoints use, on a fixed interval from outside your servers, and alerting on any status outside 200-399, which the free plans of Logdash, UptimeRobot and Better Stack all do.

[Website uptime monitoring](https://logdash.io/monitoring/website): Website uptime monitoring requests your site on a schedule, every 5 minutes on a free plan, and alerts you the moment it answers with an error or stops answering, so you hear about downtime before a visitor emails you.

[Uptime monitoring](https://logdash.io/features/monitoring): HTTP checks as often as every 15 seconds. When one fails, Telegram tells you before your users do.
