Network hiccups, rate limits, unhandled API rejections, and memory leaks can occasionally crash even the best-written Discord or Telegram bots. If a crash occurs at 3:00 AM while you are asleep, your bot could remain offline for hours.
Automating process recovery ensures your bot recovers instantly from transient crashes. In this guide, we explore how to configure automated restart policies using PM2 and Systemd on your RivinCloud VPS.
1. Automated Restarts with PM2
PM2 includes automatic crash recovery by default. However, tuning restart parameters prevents infinite crash loops when your code contains a syntax error.
A. Delaying Restarts to Prevent API Throttling
If a bot crashes due to a network outage, restarting it 100 times in 5 seconds will result in API rate-limiting or IP bans from Discord.
Configure exponential backoff restart delays using ecosystem.config.js:
module.exports = {
apps: [{
name: 'discord-bot',
script: 'index.js',
autorestart: true,
exp_backoff_restart_delay: 100, // Waits 100ms, then 200ms, 400ms, 800ms... up to 15s
max_restarts: 10
}]
};
B. Setting Memory Caps (max_memory_restart)
If your bot leaks memory over time, instruct PM2 to restart it automatically when RAM exceeds a threshold:
pm2 start index.js --name "discord-bot" --max-memory-restart 250M
2. Automated Restarts with Systemd (For Python / Binary Bots)
If managing your bot using systemd, configure restart directives inside your .service file:
[Unit]
Description=24/7 Python Discord Bot
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/my-bot
ExecStart=/home/ubuntu/my-bot/venv/bin/python3 bot.py
# Restart policy configuration
Restart=on-failure
RestartSec=5s
StartLimitIntervalSec=60s
StartLimitBurst=5
[Install]
WantedBy=multi-user.target
Explanation of Directives:
Restart=on-failure: Restarts the process only if it exits with a non-zero exit code or is killed by a signal.RestartSec=5s: Waits 5 seconds before attempting a restart.StartLimitBurst=5: Stops attempting restarts if the app crashes more than 5 times within 60 seconds (prevents CPU lockup on permanent syntax errors).
Command of the Day: pm2 restart
The pm2 restart command restarts a specified process or all processes managed by PM2.
Syntax
pm2 restart [process_name|id|all]
Practical Examples
# 1. Restart a single bot by name
pm2 restart discord-bot
# 2. Restart all managed processes
pm2 restart all
Explanation
Unlike pm2 reload (which attempts zero-downtime cluster swapping), pm2 restart immediately terminates the process and starts a fresh instance, clearing volatile memory states.
Common Mistakes
- Configuring instant unthrottled restarts: Setting
RestartSec=0without backoff can get your server IP temporarily blocked by Discord or Telegram API gateways due to rapid reconnect spam. - Not handling
unhandledRejectionin code: You should log global errors gracefully before crashing:process.on('unhandledRejection', (error) => { console.error('Unhandled promise rejection:', error); });
Troubleshooting
- PM2 shows status
erroredorstopped: The application exceeded its maximum allowed restarts (max_restarts). Check logs withpm2 logs --err, fix the code error, then runpm2 restart <name>.
Best Practices
- Combine process managers (PM2/Systemd) with global exception handlers in your bot code.
- Monitor restart counts with
pm2 statusto identify hidden bugs.
Frequently Asked Questions
Will my bot lose data during an automatic restart?
Any transient data stored only in volatile RAM variables will be lost. Save persistent state (such as user warnings or economy balances) into a database (MySQL, SQLite, MongoDB) immediately when changes occur.
Conclusion
Automating crash recovery with PM2 or Systemd guarantees maximum uptime for your bots. Configure restart policies on your RivinCloud VPS today!