A Crash-Looping Discord Bot Can Get Its Token Reset

·5 min read·Updated
discordbotsrate-limitscrash-looptroubleshooting

A crash loop isn't just noise in your logs — for a Discord bot it's a countdown. Every restart that gets far enough to connect spends one IDENTIFY, and Discord's documentation is explicit about the ceiling: "Clients are limited to 1000 IDENTIFY calls to the websocket in a 24-hour period." Exceed it and the consequence is severe — "all active sessions for the app will be terminated, the bot token will be reset, and the owner will receive an email notification" (Discord docs). A bot restarting every five seconds makes roughly 720 connection attempts an hour, so it can burn a full day's allowance in well under two hours. If your bot is crash-looping, stop the app first and debug second.

The arithmetic

Restarts are fast here, which is usually a feature and in this one case a hazard. On a zip deploy the supervisor waits about five seconds and starts your process again; with your own image, Docker's restart policy does something similar.

Restart interval Identifies per hour Time to 1000
5 seconds ~720 ~1.4 hours
30 seconds ~120 ~8 hours
5 minutes 12 ~3.5 days

The limit resets on a rolling 24-hour basis, so a bot that has been looping overnight can be deep into the allowance before you've opened the panel.

There's a second, tighter limit in the same area: max_concurrency is the "number of identify requests allowed per 5 seconds", and for most bots that value is 1. A five-second restart loop sits right on that edge.

Which crashes actually cost you

This is the part worth internalising, because not every crash loop is equally dangerous.

Crashes before the connection are free. A syntax error, a missing dependency, a None token that fails validation — the process dies before it ever opens a websocket. It burns nothing but your patience.

Crashes after connecting cost one IDENTIFY each. Your bot authenticates, receives READY, and then dies — an exception in an on-ready handler, a failed slash-command registration, a database connection that times out during startup, an out-of-memory kill a few seconds in. Every cycle spends one.

The dangerous version is the one that looks healthiest: the bot briefly appears online, so you assume the token and network are fine and go hunting elsewhere while the loop keeps running.

Notice it quickly

Two things conspire against you here. First, a crash-looping app can still report as running — on a zip deploy the supervisor keeps the container alive, so nothing turns red. Second, container logs are capped and rotate, so a fast loop scrolls the original stack trace out of retention and leaves you with the last hundred identical failures.

So check for the loop directly rather than waiting to notice it:

  • Look for !!! Process exited with code repeating on a zip deploy, or a container restart count climbing in the event history if you brought your own image.
  • Watch for a bot that flickers online and offline in the member list. That flicker is the identify loop.

What to do right now

Stop the app. Not redeploy — stop. Every minute it keeps looping spends more of a budget you can't top up, and stopping costs you nothing you weren't already losing while the bot was broken.

Then debug against a stopped app: read the exit code, fix the cause, and start it again once. If you need several attempts, that's fine — a handful of manual restarts is nothing against 1000. It's the unattended loop that hurts.

Prevent the next one

  • Don't wrap your bot in your own retry loop. The platform already restarts you. A while True: try: client.run() inside your code turns one restart into many, and each one identifies. This is the single most common way people accelerate the problem while trying to be resilient.
  • Exit on unrecoverable errors, and let the restart be the retry. Handle transient failures inside the connection your library already manages; don't reconnect from scratch on every error.
  • Register slash commands deliberately, not on every startup. Global command registration on each boot adds API calls to a loop that's already in trouble. Register when commands change, not when the process starts.
  • Do slow, failure-prone startup work after you're connected and stable — or better, lazily. A database migration in your on-ready handler makes every transient DB hiccup cost an identify.
  • Add a backoff if you must reconnect yourself. Immediate retries are what turns a brief outage into a rate-limit incident.
  • Watch memory. An out-of-memory kill shortly after startup produces a textbook post-connection loop. Exit code 137 in the event history confirms it — check your sizing.

The other gateway limit

While you're here: Discord also allows "120 gateway events per connection every 60 seconds, meaning an average of 2 commands per second", and apps that exceed it "are immediately disconnected from the Gateway."

That matters because a disconnect leads to a reconnect, and if your code reconnects aggressively you've built the same loop by a different route. Bulk presence updates and mass channel edits on startup are the usual culprits.

If your token does get reset

Treat it exactly like a leaked token, because the remedy is identical: get the new token from the Developer Portal, update the environment variable on your app, and restart. The bot will be offline until you do — the reset is not something you can appeal or wait out.

Worth noting the failure mode this creates: your bot is down, and the reason is an email rather than anything visible in your logs. If your bot has been offline since roughly the time a crash loop was running, check the inbox on the developer account.

FAQ

Can a crash loop get my Discord bot token reset?

Yes. Exceeding 1000 IDENTIFY calls in 24 hours terminates all sessions and resets the token, and the owner is emailed.

How many restarts does that take?

About 1000 connections. At a five-second restart interval that's roughly an hour and a half.

Do all crashes count toward the limit?

No. Only restarts that reach the gateway and identify. A crash before the connection opens costs nothing.

What should I do first if my bot is crash-looping?

Stop the app, then debug. Leaving it looping while you investigate spends the allowance.

Should my bot retry connecting on its own?

No. The platform restarts your process already, and your own retry loop multiplies the identify count.

My bot went offline and I didn't change anything — why?

If it had been crash-looping, the token may have been reset. Check the developer account's email, then regenerate and update your environment variable.

Wrapping up

Automatic restarts are one of the better things about running a bot on a container platform — a transient failure fixes itself instead of leaving you dead until someone notices. The catch is that Discord counts connections, and a tight loop turns a self-healing feature into a self-inflicted rate limit with an unusually harsh penalty. The habit that avoids all of it is small: when you see a crash loop, stop the app before you start investigating.