Monitoring Your Self-Hosted Botpress Platform with Vigilmon
Your Botpress chatbot went silent. Users are sending messages, but no replies are coming back. You found out an hour later when a customer emailed support.
Botpress is a powerful open-source conversational AI platform, but running it self-hosted means you own the reliability story. By the end of this guide you'll have:
- HTTP monitors for the Botpress web UI and API server
- Health checks for the NLU engine, dialogue manager, and bot runtime
- Database and Redis cache monitoring
- Messaging channel endpoint monitoring (WhatsApp, Telegram, Slack, web chat)
- WebSocket connection health monitoring
- Heartbeat monitoring for background job processors
- Slack alerts and a public status page
Why monitoring matters for Botpress
Botpress runs multiple internal services on two ports — the web UI on port 3000 and the API on port 3001. A failure in any one component can silently degrade the entire bot experience:
- NLU engine failure — bots respond with fallback messages but never correctly classify intent
- Redis cache eviction or crash — session state is lost mid-conversation
- PostgreSQL connectivity loss — conversation history and bot config are unavailable
- Messaging channel webhook failure — WhatsApp or Telegram messages stop being received
- Bot runtime crash — bots stop responding entirely while the API stays up
Standard uptime monitoring only tells you "the port is open." You need deeper visibility into each component.
Step 1: Expose Botpress health endpoints
Botpress exposes a built-in health check at the root of the API server. Add a lightweight custom endpoint to aggregate component health.
Create a file at data/global/hooks/after_server_start/health.js:
// Registers a health check endpoint at /api/v1/bots/health
const axios = require('axios')
module.exports = async ({ logger }) => {
// Botpress registers HTTP handlers via the built-in router
// This hook runs after server start and can extend routing
logger.info('Health hook loaded')
}
For a more complete health check, use a dedicated monitoring endpoint in your reverse proxy or add a small Express sidecar:
// health-server.js — run alongside Botpress
const express = require('express')
const { Client } = require('pg')
const redis = require('redis')
const app = express()
app.get('/health', async (req, res) => {
const checks = {}
// PostgreSQL
const pg = new Client({ connectionString: process.env.DATABASE_URL })
try {
await pg.connect()
await pg.query('SELECT 1')
checks.postgres = 'up'
await pg.end()
} catch {
checks.postgres = 'down'
}
// Redis
const rc = redis.createClient({ url: process.env.REDIS_URL })
try {
await rc.connect()
await rc.ping()
checks.redis = 'up'
await rc.disconnect()
} catch {
checks.redis = 'down'
}
// Botpress API
try {
const r = await axios.get('http://localhost:3001/api/v1/auth/ping', { timeout: 3000 })
checks.botpress_api = r.status === 200 ? 'up' : 'degraded'
} catch {
checks.botpress_api = 'down'
}
const healthy = Object.values(checks).every(v => v === 'up')
res.status(healthy ? 200 : 503).json({ status: healthy ? 'ok' : 'degraded', checks })
})
app.listen(3002, () => console.log('Health server on :3002'))
Start it alongside Botpress:
node health-server.js &
Verify:
curl http://localhost:3002/health
# {"status":"ok","checks":{"postgres":"up","redis":"up","botpress_api":"up"}}
Step 2: Monitor the Botpress web UI and API
Sign up at vigilmon.online (free, no card required).
Add monitors for each Botpress surface:
Web UI (port 3000):
- Click New Monitor → HTTP
- URL:
https://botpress.yourdomain.com - Expected status:
200 - Check interval: 1 minute
API server (port 3001):
- Click New Monitor → HTTP
- URL:
https://botpress.yourdomain.com/api/v1/auth/ping - Expected status:
200 - Check interval: 1 minute
Composite health check:
- Click New Monitor → HTTP
- URL:
https://botpress.yourdomain.com:3002/health - Expected status:
200 - Check interval: 1 minute
The API ping endpoint returns {"status":"alive"} when Botpress is running. Add a keyword check for "status":"alive" in Vigilmon to catch cases where the port is open but Botpress is returning error pages.
Step 3: Monitor NLU engine inference latency
The NLU engine is critical — if inference takes too long, conversations become unusable. Botpress exposes an NLU health endpoint:
GET /api/v1/nlu/health
In Vigilmon:
- New Monitor → HTTP
- URL:
https://botpress.yourdomain.com/api/v1/nlu/health - Expected status:
200 - Response time alert threshold: 2000ms — NLU inference over 2 seconds indicates a resource problem
Add a keyword alert for "isEnabled":true to detect when the NLU engine has been disabled or failed to load its model.
Step 4: Monitor messaging channel webhook endpoints
Each messaging channel integration registers a webhook endpoint on Botpress. If these endpoints return errors, messages from that channel stop being processed.
Add HTTP monitors for each active channel:
| Channel | Endpoint pattern |
|---------|-----------------|
| Web chat | https://botpress.yourdomain.com/api/v1/bots/{botId}/converse/{userId} |
| Slack | https://botpress.yourdomain.com/api/v1/bots/{botId}/mod/channel-slack/webhook |
| Telegram | https://botpress.yourdomain.com/api/v1/bots/{botId}/mod/channel-telegram/webhook |
| WhatsApp | https://botpress.yourdomain.com/api/v1/bots/{botId}/mod/channel-whatsapp/webhook |
For channel webhooks, use 405 Method Not Allowed as the expected status code when monitoring with GET requests — the webhook itself expects POST, but a 405 confirms the route is registered and the server is routing correctly. A 404 means the channel integration failed to load.
Step 5: Monitor WebSocket connections
Botpress uses WebSockets for real-time web chat. A dead WebSocket layer means chat widgets freeze silently.
Create a WebSocket probe script:
// ws-probe.js
const WebSocket = require('ws')
const ws = new WebSocket('wss://botpress.yourdomain.com/socket.io/?EIO=4&transport=websocket')
let ok = false
ws.on('open', () => { ok = true; ws.close() })
ws.on('error', () => process.exit(1))
setTimeout(() => {
if (!ok) process.exit(1)
process.exit(0)
}, 5000)
Wrap it in a cron-driven heartbeat:
# /etc/cron.d/botpress-ws-probe
*/5 * * * * node /opt/botpress/ws-probe.js && curl -fsS "https://vigilmon.online/heartbeat/YOUR_HEARTBEAT_ID"
In Vigilmon, create a Heartbeat Monitor with a 10-minute expected interval. If the WebSocket probe fails, the heartbeat ping never fires and Vigilmon alerts you.
Step 6: Heartbeat monitoring for background jobs
Botpress runs background jobs for training NLU models, syncing bot configs, and processing queued messages. These run invisibly — no HTTP endpoint to probe.
Add a heartbeat ping to each critical job:
// In your custom Botpress action or hook
const axios = require('axios')
async function runBackgroundJob() {
try {
await doTheWork()
// Ping heartbeat on success
await axios.get(process.env.VIGILMON_JOB_HEARTBEAT)
} catch (err) {
logger.error('Background job failed', err)
// No ping → Vigilmon alerts on missed heartbeat
}
}
In Vigilmon:
- New Monitor → Heartbeat
- Set expected interval to match your job schedule
- Copy the ping URL into
VIGILMON_JOB_HEARTBEAT
Step 7: Slack alerts and status page
Slack alerts:
- Go to Notifications → New Channel → Slack
- Paste your Slack incoming webhook URL
- Enable on all Botpress monitors
You'll get alerts like:
🔴 DOWN: botpress.yourdomain.com/api/v1/nlu/health
Response time: timeout (>10s)
Region: EU-West
Status page:
- Status Pages → New Status Page
- Add all monitors
- Name it "Botpress Platform Status"
- Share the URL in your support docs
What you've built
| What | How |
|------|-----|
| Web UI monitoring | Vigilmon HTTP → port 3000 |
| API server monitoring | Vigilmon HTTP → /api/v1/auth/ping |
| NLU engine latency | Vigilmon HTTP → /api/v1/nlu/health + 2s threshold |
| Database + Redis health | Custom health sidecar on port 3002 |
| Messaging channel webhooks | Vigilmon HTTP → channel webhook paths |
| WebSocket health | Heartbeat from ws-probe cron |
| Background jobs | Heartbeat ping in job handlers |
| Slack alerts | Vigilmon Slack notification channel |
| Status page | Vigilmon public status page |
Self-hosted Botpress is powerful — pair it with monitoring that matches its complexity.
Next steps
- Add SSL certificate expiry monitoring for your Botpress domain in Vigilmon
- Set response time alerts at 1s for the web chat endpoint — conversation latency is UX-critical
- Monitor disk space on the Botpress host; NLU model files can grow large over time
Get started free at vigilmon.online.