tutorial

Monitoring Your Self-Hosted Botpress Platform with Vigilmon

Production-grade uptime monitoring for self-hosted Botpress — web UI, NLU engine, dialogue manager, bot runtime, PostgreSQL, Redis, messaging channels, WebSockets, and background jobs.

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):

  1. Click New Monitor → HTTP
  2. URL: https://botpress.yourdomain.com
  3. Expected status: 200
  4. Check interval: 1 minute

API server (port 3001):

  1. Click New Monitor → HTTP
  2. URL: https://botpress.yourdomain.com/api/v1/auth/ping
  3. Expected status: 200
  4. Check interval: 1 minute

Composite health check:

  1. Click New Monitor → HTTP
  2. URL: https://botpress.yourdomain.com:3002/health
  3. Expected status: 200
  4. 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:

  1. New Monitor → HTTP
  2. URL: https://botpress.yourdomain.com/api/v1/nlu/health
  3. Expected status: 200
  4. 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:

  1. New Monitor → Heartbeat
  2. Set expected interval to match your job schedule
  3. Copy the ping URL into VIGILMON_JOB_HEARTBEAT

Step 7: Slack alerts and status page

Slack alerts:

  1. Go to Notifications → New Channel → Slack
  2. Paste your Slack incoming webhook URL
  3. 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:

  1. Status Pages → New Status Page
  2. Add all monitors
  3. Name it "Botpress Platform Status"
  4. 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.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →