On this page 8 sections
A Discord bot is a long-running process. It opens a WebSocket connection to Discord’s gateway, keeps it alive with heartbeats, and reacts to events as they arrive. That shape is different from a website, and it is why so many bots go offline a few minutes after you close your laptop or after a free host decides the “app” is idle.
This guide covers what a bot actually needs, what the common hosts charge for it (list prices checked 2026-10-13), and how to run one on Ownkube as a worker.
TL;DR
- A gateway bot needs a process that runs all the time. Hosts that sleep idle web apps will put a bot to sleep, because a bot rarely receives inbound HTTP traffic.
- Run it as a background worker: a long-running process with no public URL that restarts if it crashes.
- A typical small bot uses a sliver of CPU and 100 to 250 MB of memory. On metered pricing that is about $2 a month.
- On Ownkube: push the repo, choose Worker, add the bot token as a secret variable, deploy. Logs stream in the dashboard.
What does a Discord bot need from a host?
A bot needs three things from a host, and none of them involves serving web pages.
A process that never stops
The gateway connection is outbound from your bot to Discord. If the process stops, the bot shows as offline.
Automatic restarts
Bots crash on unhandled promise rejections, rate limits and library bugs. The host should start the process again without you noticing.
A place for secrets
The bot token is a password. It belongs in an environment variable, never in the repo.
A database is optional. Many bots keep state in memory or in a small Postgres or Redis-compatible cache once they need to remember settings per server.
Why do bots on free hosting go offline?
Most free and low-cost web hosting is built around HTTP requests. When no request arrives for a while, the platform stops the app to save resources, and it wakes on the next request. A gateway bot rarely receives HTTP requests at all, so the platform sees it as idle and stops it.
- Render spins down a free web service after 15 minutes without inbound traffic. Render runs bots as background workers, and background workers have no free instance type.
- Heroku Eco dynos ($5 a month) sleep after 30 minutes of inactivity.
- Railway has an optional Serverless setting that sleeps a service after about 5 to 10 minutes without outbound traffic. A connected bot sends heartbeats, so leave Serverless off for bots to be safe.
The fix is to deploy the bot as a worker on a plan that keeps workers running.
How much does Discord bot hosting cost?
The same small bot (average 0.05 vCPU, 0.25 GB of memory) on each platform, from list prices checked 2026-10-13:
| Host | How the bot runs | Monthly cost for a small bot |
|---|---|---|
| Ownkube | Worker, metered per minute | about $2 of usage, from a $5 wallet load |
| Railway | Service on Hobby, metered | about $3.50 of usage, inside the $5 Hobby plan |
| Fly.io | A Machine with no HTTP service | Fly’s own example prices a 24/7 bot at $2.21 |
| Render | Background worker | $7 for the smallest paid instance |
| Heroku | Basic worker dyno | $7 (Eco $5 sleeps) |
| A small VPS | A process you supervise yourself | the server price, plus your time on updates and restarts |
The gap between them is a few dollars. What tends to matter more is whether the bot stays online, how quickly you can see why it crashed, and whether the bill can grow without warning.
How do I deploy a Discord bot on Ownkube?
1. Prepare the bot
Read the token from the environment. A minimal discord.js bot:
import { Client, GatewayIntentBits } from "discord.js";
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once("ready", () => console.log(`Logged in as ${client.user.tag}`));
client.on("interactionCreate", async (interaction) => { if (interaction.isChatInputCommand() && interaction.commandName === "ping") { await interaction.reply("pong"); }});
process.on("unhandledRejection", (err) => console.error(err));
client.login(process.env.DISCORD_TOKEN);Add "start": "node index.js" to the scripts in package.json. The Python equivalent with discord.py:
import osimport discord
intents = discord.Intents.default()client = discord.Client(intents=intents)
@client.eventasync def on_ready(): print(f"Logged in as {client.user}")
client.run(os.environ["DISCORD_TOKEN"])Push the code to a GitHub or GitLab repository. Ownkube builds Node.js and Python automatically, so a Dockerfile is optional.
2. Create a worker
Sign in to Ownkube, choose New, pick Worker as the resource type, and select the repository. A worker is a long-running background process with no public endpoint, which is exactly the shape of a gateway bot.
The form asks for a port. If your bot serves a small status page, use that port. If it serves nothing, any value such as 8080 works: health checks are off by default, so nothing has to listen on it.
3. Add the token as a secret
On the Variables tab, add DISCORD_TOKEN and turn on Secret. A secret is masked in the dashboard and redacted from logs, and the container gets the real value.
4. Deploy and watch the logs
Deploy the worker. The build streams in the dashboard, and once the process starts, the Logs tab shows the “Logged in as” line. If the process exits, Ownkube starts it again, and a restarts alert can email you when that happens repeatedly.
5. Size it
Small bots run comfortably on a small memory request. Keep metered billing so you pay for what the bot uses each minute, or switch the worker to a Spark 1 reserved box ($5 a month, 0.25 vCPU, 0.5 GiB) if you prefer a flat price.
Should a bot use slash command webhooks instead?
Discord also supports an HTTP interactions endpoint: Discord sends each slash command to a URL you host, and you reply over HTTP. That suits a web app instead of a worker.
Discord expects an initial response within three seconds, so keep that app awake. A web app that sleeps when idle has to start before it can answer, so leave sleep off for an interactions endpoint.
Can I add a database to my bot?
Yes. Create a managed Postgres database (from $4 a month on the DB 0.5 box plus $0.25 per GB of storage) and link it to the worker, and DATABASE_URL appears in its environment. For per-server settings or rate-limit counters, a Valkey cache box starts at $2 a month and speaks the Redis protocol.
FAQ
What is the cheapest way to host a Discord bot 24/7?
A metered worker is the cheapest managed option for a small bot, because you pay for the little CPU and memory it actually uses. On Ownkube a small bot runs for about $2 a month of usage. The Personal plan loads $5 of credit a month, and unused credit rolls over and never expires.
Can I host a Discord bot for free?
Free web tiers put bots to sleep when no HTTP request arrives, and free background workers are rare. A free tier works for testing, but a bot that has to stay online belongs on a worker you pay a few dollars for.
Why does my Discord bot go offline after a few minutes?
The host is stopping the process because it looks idle. Gateway bots receive events over an outbound WebSocket instead of inbound HTTP requests, so platforms that sleep idle web apps treat them as inactive. Run the bot as a background worker instead.
Do I need a Dockerfile to host a Discord bot?
No. Ownkube detects Node.js and Python projects and builds them automatically. Add a Dockerfile if you want control over the base image or system packages.
How much memory does a Discord bot need?
A small discord.js or discord.py bot in a few servers typically uses 100 to 250 MB. Large bots with many guilds and cached members need more, and sharding spreads them across processes.
Where Ownkube fits
Ownkube runs your bot as a worker that stays up and restarts on a crash, with logs and metrics in the same dashboard as your web apps and databases. Usage draws a prepaid wallet per minute, so a forgotten bot can never run up a bill past what you loaded.
When the bot grows a dashboard or an API, add a web app next to it in the same environment. See the worker and job queue guide for queue-backed workers, and the Python hosting page for more Python shapes. Deploy my first app.