Learning objectives
After reading this article you will be able to:
- Understand what actually keeps a bot online
- Set up automatic restarts with pm2, systemd or Docker
- Verify the bot survives crashes and reboots
On this page
A Discord bot only answers while its process is running and connected to the Discord Gateway. Close the terminal, let the PC go to sleep, or let the program crash, and the bot shows as offline. Keeping it online 24/7 means solving two things: where the process runs, and what restarts it when it dies. The examples use Node.js and discord.js v14, but the logic applies to any language.
What does it mean to keep a bot online 24/7?#
Your bot opens a WebSocket connection to the Gateway and keeps it alive by sending heartbeats. According to the Gateway documentation, if a heartbeat goes unacknowledged the connection is considered "zombied" and the client should close it and reconnect. The same page says disconnects are expected and can happen at any time, and that clients should try to resume the session.
Popular libraries handle that reconnection. What they cannot do is bring back a process that has died. So "24/7" rests on three layers:
- An always-on machine with a stable connection.
- A supervisor that starts the bot at boot and restarts it after any crash.
- Code that does not kill the process over predictable errors.
Where can I run the bot?#
| Option | Online without your PC? | What you maintain |
|---|---|---|
| Your computer | No | Everything, and the bot drops when the machine turns off |
| VPS | Yes | Operating system, updates, firewall, supervisor |
| Bot hosting platform | Yes | The code and the memory; the environment comes ready |
Running on your PC is for development; what happens when the PC is off explains why. No-cost tiers usually come with hour limits or suspension, as covered in the limits of no-cost bot hosting. To compare prices, see how much it costs to host a Discord bot.
Step 1: how do I prepare the code so it does not crash for no reason?#
Keep the token in an environment variable, never in the code (see how to protect your bot token). Also register handlers for errors that would otherwise end the Node.js process:
// index.js (discord.js v14)
const { Client, Events, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once(Events.ClientReady, (readyClient) => {
console.log(`Online as ${readyClient.user.tag}`);
});
client.on(Events.Error, (err) => console.error('Client error:', err));
process.on('unhandledRejection', (err) => console.error('Rejected promise:', err));
client.login(process.env.DISCORD_TOKEN).catch((err) => {
console.error('Login failed:', err);
process.exit(1); // exit with an error so the supervisor notices and restarts
});The unhandledRejection handler only logs the error and keeps the process alive, so use it for one-off failures. A failed login (invalid token, disabled intent) cannot fix itself: the catch ends the process with exit code 1 instead of leaving the bot silently idle. If Node.js hits an unhandled exception, the process exits too. That is why the supervisor in the next step is essential, even with good error handling. For a walkthrough of the bot itself, see how to host a discord.js bot or a discord.py bot.
Step 2: how do I restart the bot automatically?#
Pick a supervisor. They all do the same job: start the bot at boot and bring it back after a crash.
pm2 (Node.js)#
npm install -g pm2
DISCORD_TOKEN=your_token pm2 start index.js --name my-bot
pm2 startup # prints a sudo command; copy and run it
pm2 save # stores the list so it returns after a rebootAccording to the pm2 documentation, pm2 startup detects your init system and prints the command to run, and pm2 save stores your apps so they respawn after a reboot. After upgrading Node.js, run pm2 unstartup and pm2 startup again. To keep the token out of your shell history, use a pm2 config file or load a .env.
systemd (any language, Linux)#
Create /etc/systemd/system/my-bot.service:
[Unit]
Description=Discord bot
After=network-online.target
Wants=network-online.target
[Service]
WorkingDirectory=/opt/my-bot
EnvironmentFile=/opt/my-bot/.env
ExecStart=/usr/bin/node index.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now my-botRestart=always restarts the service whatever the reason it exited, and stops doing so only if you stop it with systemctl stop (or the exit code is listed in RestartPreventExitStatus=), per the systemd manual. RestartSec=5 waits 5 seconds between attempts (the default is 100 ms, too fast for a bot with an invalid token).
Docker#
docker run -d --name my-bot --restart unless-stopped --env-file .env my-botPer the Docker documentation, unless-stopped restarts the container if it exits or the daemon restarts, but respects a manual docker stop.
How do I verify the bot survives crashes?#
Do not stop at "it started". Test the failure cycle:
- Check the logs (
pm2 logs my-botorjournalctl -u my-bot -f) and confirm the "Online as ..." line. - Kill the process on purpose (
pm2 stopdoes not count; usekill -9 <pid>) and watch the supervisor start another within seconds. - Reboot the machine and confirm the bot comes back by itself.
- Close your SSH session and check the bot still shows online in Discord.
What mistakes keep a bot offline?#
- Running
node index.jsin an SSH session. Closing the session kills the process. Use a supervisor. - Restart loops. An invalid token or a disabled intent makes the bot exit on login, and the supervisor restarts it forever. Read the error in the log. Causes are listed in why a Discord bot goes offline.
- Running out of memory. The system kills the process when RAM runs out. Measure peak usage and leave headroom.
- Forgetting
pm2 saveor systemdenable. The bot works until the first reboot. - Token in the code. It leaks through the repository and Discord may reset it.
How to do this on Square Cloud#
On Square Cloud, the three layers from this article change hands. The always-on machine is the container, with no sleep mode and no inactivity rule. The supervisor is automatic restart, on by default for dashboard deploys: when the process exits with an error, the application comes back on its own, so you do not install pm2 or write a systemd unit. The code stays your job, and the process.exit(1) from step 1 is exactly the signal that restart waits for. An exit with code 0 leaves the application stopped.
Two limits are worth knowing up front. If the bot runs out of memory, the application stops and does not come back on its own: raise the RAM in its settings and start it again. And an invalid token makes the bot exit at login on every attempt, so read the error in the logs instead of waiting for it to fix itself. Logs stream in real time in the dashboard, the CLI and the mobile app, and lines from before a restart stay visible.
The token goes in as an application environment variable and applies on the next restart. You deploy by ZIP upload, CLI, GitHub or the VS Code extension, with discord.js, discord.py, JDA, Discord.Net or another Gateway library. Hobby costs R$12.49 per month for 1 GB of RAM, and a bot starts at 256 MB. See the details at Discord bot hosting.
Bot hosting
Keep your bot online 24/7 with automatic restarts
FAQs
How do I keep a Discord bot online 24/7 without leaving my PC on?
Run the bot on another machine that stays on: a VPS or a bot hosting platform. You upload the code, set the token as an environment variable, and the process keeps running even when your computer is off.
Why does my Discord bot go offline by itself?
The usual causes are the computer or terminal closing, an unhandled exception that kills the process, running out of memory, and an invalid or reset token. A process supervisor that restarts the bot fixes most of them.
Does the bot need to reconnect to Discord when the connection drops?
Yes. Discord states that Gateway disconnects are expected and can happen at any time, and clients should try to resume the session. Libraries such as discord.js and discord.py do this for you, but the process has to stay alive.
pm2 or systemd: which should I use to keep the bot running?
If the bot is Node.js and you want something quick, pm2. If you want a native Linux service that works for any language, systemd. Both restart the bot after a crash and start it with the server.
More in Bots
See all 33 articles- How much does it cost to host a Discord bot?The cost of hosting a Discord bot depends on RAM, uptime, database and outside services. Learn how to estimate your own bill and where the money goes.
- Running a bot on your phone or PC vs hosting itA bot on your PC or phone (Termux) goes offline when the device shuts down, sleeps or loses its network. Compare the three options and when each one fits.
- Why your Discord bot keeps going offline (and how to fix it)A Discord bot goes offline when the process dies, the token is invalid, an intent is disabled or memory runs out. Learn to diagnose each cause and fix it.
- How to host a Telegram bot 24/7To keep a Telegram bot online 24/7, run its process on an always-on server using long polling or a webhook. See working code and the common errors.