Back to Blog
Tutorial10 min read2026-06-27

How to Deploy a Discord Bot 24/7

Keep a Discord bot online 24/7: gateway vs HTTP interactions, persistent state, graceful reconnection, secure token handling, and a always-on cloud deployment.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

A Discord bot that runs on your laptop dies the moment you close the lid. To keep one online 24/7 you need an always-on host, secure token storage, and reconnection handling for the gateway. This guide covers the architecture decisions and the deploy.

Gateway bots vs HTTP interactions

There are two fundamentally different bot architectures, and they have opposite hosting requirements:

  • Gateway bots maintain a persistent WebSocket connection to Discord and receive events in real time (messages, presence, voice). This needs a long-running process that never sleeps.
  • HTTP interaction endpoints receive slash-command interactions as webhooks over HTTPS. Discord POSTs to your URL; you respond. This can run as a request-driven service and tolerates scale-to-zero better.

Most classic bots are gateway bots. If you only handle slash commands, the HTTP interactions model is leaner. Know which you're building before you deploy.

A minimal gateway bot (discord.js)

import { Client, GatewayIntentBits } from 'discord.js'

const client = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages]
})

client.once('ready', () => console.log(`Logged in as ${client.user.tag}`))

client.on('interactionCreate', async (i) => {
  if (i.isChatInputCommand() && i.commandName === 'ping') {
    await i.reply('Pong!')
  }
})

client.login(process.env.DISCORD_TOKEN)

Never commit your token

The bot token is a full credential. If it leaks, attackers control your bot. Always load it from an environment variable and add a secret scanner to CI. If a token leaks, regenerate it in the Discord Developer Portal immediately.

Reconnection and reliability

discord.js handles gateway reconnects automatically, but you should still log disconnects and avoid crashing on unhandled rejections, which would otherwise drop the bot until a restart:

process.on('unhandledRejection', (err) => console.error('Unhandled:', err))
client.on('shardDisconnect', (e, id) => console.warn(`Shard ${id} disconnected`, e.code))

For large bots (2,500+ guilds) Discord requires sharding; discord.js can manage shards for you. Most bots never reach that threshold.

Persistent state

If your bot remembers anything — settings, scores, reminders — store it in a database, not in memory. A restart (which happens on every deploy) wipes in-memory state.

const { rows } = await pool.query('SELECT prefix FROM guilds WHERE id=$1', [guildId])

Dockerfile

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
USER node
CMD ["node", "index.js"]

A gateway bot has no inbound HTTP port — it connects out to Discord.

Deploying on PandaStack

Gateway bot (always-on): deploy as a container app, but run it on a tier that keeps one instance alive — do *not* use free-tier scale-to-zero for a gateway bot, since the WebSocket must stay connected. Store DISCORD_TOKEN as an environment secret in the [dashboard](https://dashboard.pandastack.io). If your bot has state, attach a managed PostgreSQL database and read DATABASE_URL.

HTTP interactions bot: deploy as a container app exposing your interactions endpoint. Set the endpoint URL in the Discord Developer Portal. Because it's request-driven, it tolerates scale-to-zero, and the automatic SSL PandaStack provides satisfies Discord's HTTPS requirement.

Bot typeConnectionScale-to-zero OK?PandaStack setup
GatewayPersistent WSNoAlways-on container app
HTTP interactionsInbound webhookYesContainer app + SSL endpoint

Logs and monitoring

PandaStack gives you live application logs (self-hosted Elasticsearch), so you can watch reconnects and command errors in real time — invaluable when a bot misbehaves only in production.

References

  • [Discord Developer Docs: Gateway](https://discord.com/developers/docs/topics/gateway)
  • [Discord: Receiving and responding to interactions](https://discord.com/developers/docs/interactions/receiving-and-responding)
  • [discord.js guide](https://discordjs.guide/)
  • [Discord: Sharding](https://discord.com/developers/docs/topics/gateway#sharding)

Keep your bot online around the clock with live logs and a managed database on PandaStack — get started at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also