Host a Python Discord bot
A Python Discord bot uses discord.py and a persistent connection to the gateway. It exposes no HTTP port, but it must stay connected, handle reconnection and protect its token. On app hosting, the platform restarts the process when it exits: stability therefore comes from the code and the intent configuration.
Minimal bot
import os
import logging
import discord
from discord.ext import commands
logging.basicConfig(level=logging.INFO)
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="!", intents=intents)
@bot.event
async def on_ready():
print(f"logged in as {bot.user}")
@bot.command()
async def ping(ctx):
await ctx.send("pong")
bot.run(os.environ["DISCORD_TOKEN"])bot.run blocks and maintains the connection. The token comes from an environment variable, never from the file. message_content is privileged: enable it in the developer portal, otherwise the connection is refused with PrivilegedIntentsRequired.
Intents and commands
Ask only for what you need. Intents.default() covers guilds and messages, but not members. Enable members only if you must iterate over them. For slash commands, sync once and avoid repeating it on every restart.
@bot.tree.command(name="ping", description="Replies pong")
async def ping_slash(interaction: discord.Interaction):
await interaction.response.send_message("pong")Command sync scopes to a guild or globally; too many calls can hit API limits.
Stability and memory
- Member and message caches can grow; do not enable
memberswithout need. - Do not block the loop with long synchronous code: use
asyncio.to_threadfor blocking calls. - Exceptions in an event must not kill the bot: log and continue.
discord.pyhandles reconnection, but a fast reconnect loop often means an invalid token or a refused intent.- Watch RAM: a 512 MB plan is enough for a small server, not for thousands of members with caches.
Security
The token grants control of the bot. If it leaks, reset it immediately in the developer portal and restart the service with the new value. Never log it, even on a connection error. Limit the bot's permissions on the server and check rights before a sensitive action (ban, message deletion).
Check
The log shows logged in as ..., the bot appears online and a command replies. Let it run for thirty minutes and confirm memory does not grow continuously. If the bot disconnects in a loop, compare error timestamps with a recent token or intent change.
Advertisement
Was this article helpful?
Read next
- Deploy a FastAPI APIStart Uvicorn correctly, expose a health route and control the documentation.
- Configure Python environment variablesRead variables with os.environ, set them in the panel and rotate secrets.
- Deploy a Flask applicationRun Flask on the provided port, without debug, with a health route.