all posts

The best Discord bot hosting platforms in 2026

Ajay Kumar··9 min read

Most hosting guides can stay vague because most apps are flexible. A Discord bot is not. It has hard requirements imposed by a protocol you do not control, and a platform either meets them or your bot appears offline while your logs insist everything is fine.

So this guide starts with the requirements, which are unusually concrete, and then sorts the platforms by whether they satisfy them.

First, decide which kind of bot you are building

There are two ways to receive events from Discord, and they have completely different hosting profiles.

The gateway model is the default and what every library does by default. Your bot opens a WebSocket to Discord, identifies, and then receives events on that connection for as long as it stays open, sending heartbeats at an interval Discord specifies. This gives you everything — message events, presence, voice state, member updates — and it requires a process that runs continuously.

The HTTP interactions model is the alternative. You register an interactions endpoint URL, and Discord POSTs to it when someone uses a slash command. No connection is held. That makes it hostable on functions and at the edge, and it also limits you to interactions: no message events, no presence, no voice. For a bot that is entirely slash commands, this is genuinely the simpler deployment, and it is underused.

If your bot only has slash commands, seriously consider HTTP interactions. You must verify every request's Ed25519 signature and respond to the PING type, and Discord will reject your endpoint at registration if you get that wrong — but in exchange the whole always-on problem disappears.

The three-second rule, and how it shapes your code

Discord gives you three seconds to acknowledge an interaction. Miss it and the user sees a failure message that no later reply can undo. Any real work — an API call, a database query, an image render — will not reliably fit.

The fix is to defer immediately and edit the reply when the work is done. This is one line, and it is the difference between a bot that feels solid and one that intermittently fails under load.

// discord.js: acknowledge first, work second.
client.on("interactionCreate", async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  // Buys you up to 15 minutes. Do this before anything that can block.
  await interaction.deferReply();

  const data = await slowThing();          // API call, query, render
  await interaction.editReply({ content: data.summary });
});

// Without deferReply(), any command slower than ~3s fails visibly for the
// user even though your handler eventually completes.

This matters for hosting because it interacts with cold starts. On a platform where your process may be starting when the interaction arrives, the startup time comes out of the same three seconds, and a bot that works fine warm fails for the first user after an idle period.

Scale to zero is the wrong tool here

Elsewhere on this site we spend a lot of time arguing that idle workloads should not bill. A gateway bot is the honest exception. It has no idle state to detect — the connection is the workload — and a bot that is asleep is a bot that is offline. Anything that suspends the process on inactivity will break it.

That reframes what to optimise for. You are not looking for the platform with the cleverest sleep behaviour; you are looking for the cheapest reliable always-on process with a sane restart policy. Small and boring beats elastic and clever.

Restarts and reconnects are the operational reality

Your bot will disconnect. Discord restarts gateway nodes, networks blip, and your own deploys interrupt the connection. Libraries handle resume automatically when they can, but you should know two things.

First, IDENTIFY is rate limited. A crash loop that reconnects aggressively can get you temporarily blocked, turning a small bug into an outage. Make sure your restart policy backs off rather than restarting instantly forever.

Second, events during a disconnect can be lost. If your bot does something that must not be missed — logging moderation actions, tracking joins — reconcile on startup by fetching current state rather than assuming the event stream was complete. Bots that store state purely from events drift quietly over months.

The platforms

  • A small VPS — Still the default answer, and still a good one. A one-to-two-gigabyte instance runs most bots with room to spare, systemd handles restarts with backoff, and the cost is predictable. You own OS updates and monitoring.
  • Railway — Very popular for bots: git push, a long-running process, environment variables, a managed Postgres if you need one. Usage-based, and a bot that idles cheaply on CPU stays cheap.
  • Fly.io — A real VM per instance with a persistent process, straightforward regions, and volumes if you need local state. Good for bots that also expose a small HTTP service.
  • Render — Deploy as a background worker rather than a web service so nothing expects an open port or a health-check endpoint. Predictable and simple.
  • Heroku — The historical answer. Fine, but be careful with dyno sleeping on lower tiers, which is exactly the behaviour a gateway bot cannot tolerate.
  • Cloudflare Workers — Only for HTTP-interactions bots, where it is excellent: signature verification, near-zero latency, and no server at all. Cannot hold a gateway connection.
  • Oracle Cloud free tier or similar — Genuinely free always-on compute if you are willing to operate it. Popular in hobbyist communities; the caveat is that free tiers get reclaimed and nobody backs up a bot they forgot about.
  • PandaStack — Git-driven with no Dockerfile: it detects the Node or Python build, starts your process, and keeps it running. Each bot is a Firecracker microVM with its own kernel, which matters most if the bot executes anything on behalf of users — a code-eval command, an image pipeline, a user-supplied URL fetch. Billing is metered on active CPU and working-set memory rather than a flat instance hour, so a bot that mostly waits on a socket bills close to its memory footprint. Best for bots doing untrusted or heavy work; a plain VPS is fine for a bot that only posts messages.

Sharding: later than you think

Discord requires sharding once a bot is in a large number of guilds — the threshold has historically been 2,500 per shard, and Discord tells you the recommended shard count when you fetch the gateway URL. Below that, you do not need to think about it, and most bots never get there.

When you do, the hosting question changes shape: you now run multiple processes that must coordinate, and you care about whether your platform makes running N instances of the same code straightforward. That is a good problem to have and a bad one to design for prematurely. Build for one process, keep shared state in a database rather than in memory, and sharding becomes a configuration change rather than a rewrite.

Pick by situation

  • Slash commands only, no message events → HTTP interactions on Cloudflare Workers or any function platform. Skip the always-on problem entirely.
  • Hobby bot, cost matters most → a small VPS or a free-tier always-on instance, with systemd and backoff on restart.
  • Team bot people depend on → Railway, Fly.io, or Render, with a managed database and alerting on process restarts.
  • Bot that runs user-supplied code or processes user uploads → per-workload isolation, and a disposable environment per execution regardless of host.
  • Bot in thousands of guilds → whatever makes running multiple coordinated processes easy, with all shared state already out of process memory.

The short version

Pick the event model first. HTTP interactions turn this into an ordinary deployment; the gateway makes it a long-running process, and no amount of platform cleverness changes that.

If you are on the gateway, optimise for a cheap process that never sleeps, restarts with backoff, and reconciles state on startup. Those three properties account for nearly every difference between a bot that is reliably online and one that is mysteriously not.

Frequently asked questions

Can I host a Discord bot on serverless or on Vercel?

It depends entirely on which event model you use. A gateway bot cannot run on serverless: it holds a WebSocket open indefinitely and receives events on it, and function platforms freeze or terminate your process shortly after a response, which drops the connection and takes your bot offline. An HTTP-interactions bot works well on serverless, because Discord simply POSTs to your endpoint when someone uses a slash command and there is nothing to keep open — this is a supported, first-class model, not a workaround. The trade is capability: interactions give you slash commands and component callbacks, but not message events, presence updates, voice, or anything else that arrives over the gateway. If your bot is entirely slash commands, the serverless path is genuinely simpler; if it needs to react to messages, you need a process that stays alive.

Why does my bot show as offline even though it is running?

Almost always the gateway connection rather than the process. A bot appears online precisely while its WebSocket is connected and heartbeating, so a process that is technically alive but has lost the socket — or is stuck before the identify step — shows offline while your logs look healthy. Check whether heartbeats are being acknowledged, whether the library is reporting reconnect attempts, and whether a platform-level idle timeout or health check is killing the connection. Two specific causes are common: a host that suspends processes on inactivity, which a gateway bot cannot survive, and hitting the identify rate limit after a crash loop, which blocks reconnection for a while and produces exactly this symptom. Log the connect, resume, and disconnect events explicitly — libraries often swallow them by default and the silence is what makes this hard to diagnose.

How much does it cost to host a Discord bot?

Less than most people expect, because the workload is mostly waiting. A typical bot is idle on CPU almost all of the time and holds a modest amount of memory, so the cost is dominated by whatever your platform charges for keeping a small process alive. A one-to-two-gigabyte VPS in the low single-digit dollars per month runs most bots comfortably, and usage-metered platforms often land lower because the CPU genuinely is near zero. Costs rise when the bot does real work per event — image processing, audio transcoding, running user-supplied code, large database queries — and voice in particular is different, since streaming audio uses steady CPU and bandwidth rather than the near-idle profile of a text bot. Price for your busiest hour rather than your average, then check whether your platform bills provisioned capacity or actual usage, because for this workload the difference is substantial.

Do I need sharding for my Discord bot?

Not until Discord tells you so. Sharding becomes mandatory once your bot is in enough guilds that a single gateway connection cannot serve them — historically around 2,500 guilds per shard — and Discord returns a recommended shard count when you fetch the gateway endpoint, which most libraries can use automatically. The overwhelming majority of bots never reach that threshold. What is worth doing early is not sharding itself but the thing that makes sharding painless later: keep shared state in a database rather than in process memory, so that running multiple instances of the same code is a configuration change instead of a redesign. If you cache guild or member state in a module-level object, that is the assumption that will break first.

What is the safest way to add a code-eval command to a bot?

Run the code somewhere disposable, never in the bot's own process. An eval command inside the bot gives whoever can invoke it your bot token, your database credentials, and your host's network access, and language-level sandboxes such as Node's vm module do not contain that — they were never designed to. The structural answer is to send the code to a fresh isolated environment per invocation, with its own kernel, no credentials it does not need, restricted egress, and a short lifetime, then post back the captured output. That way a malicious snippet gets a throwaway machine that is destroyed seconds later instead of a foothold on the host running your bot. Add a per-user rate limit and an output size cap while you are there, since the other common failure is not a compromise but someone printing an infinite loop into your channel.

Keep reading

Run code in a microVM in one API call.

49ms p50 cold start. Fork, snapshot, and scale to zero.

Start free
Written by Ajay Kumar, Founder, PandaStack.