Fixing a bot that keeps going offline after a few minutes on free hosting — the real cause (no HTTP port) and a one-line python fix.
Why Does My Bot Go Offline After a Few Minutes on Free Hosting?
You deploy a Telegram or Discord bot to a free host, it works for a bit, then it just... stops. No crash log, no obvious error — it just goes quiet, and sometimes comes back after you push a new commit or manually restart the service. If this sounds familiar, you're not dealing with a bug in your bot's code. This is almost always one specific, well-understood cause, and it has a one-line fix.
Table of Contents
- The Symptom
- The Real Cause
- How to Confirm This Is Your Problem
- The Fix
- Why This Isn't a Code Bug
- If Self-Ping Is Also Needed
- Full Working Fix
- FAQs
- Conclusion
The Symptom
Your bot runs fine when you test it locally. You deploy it to Render, Railway, Koyeb, or a similar platform, and it works — for a while. Then, with no error in your bot's own logs, it stops responding to commands entirely. Checking the platform's dashboard, you might see the deployment marked as "unhealthy," "crashed," or repeatedly restarting, even though nothing in your bot's own code changed.
The Real Cause
Discord bots (via discord.py) and Telegram bots (via Pyrogram, python-telegram-bot, etc.) connect outward to Discord's or Telegram's servers — they don't open an HTTP port of their own. That's completely normal, correct behavior for a bot.
The problem is that most modern hosting platforms are built around web services, and they health-check your deployment by trying to reach it over HTTP. If nothing is listening on the port they expect, the platform assumes the process is broken or idle, and either restarts it or marks it unhealthy — even though your bot's actual logic never failed at all.
How to Confirm This Is Your Problem
A quick way to check: does your main.py or entry point ever call anything that binds to a port, like app.run(), socket.bind(), or similar? If your entry point goes straight into bot.run(token) or an async event loop with no HTTP server anywhere in the process, this is almost certainly what's happening.
The Fix
The fix isn't to change your bot's logic at all — it's to run a tiny HTTP server alongside it, purely so the platform has something to check. StayPresent does this in one line:
import staypresent
staypresent.web.json({"status": "running"})
staypresent.run("bot.py")
This starts an HTTP server on the port your platform expects and launches your existing bot script (bot.py) as a managed subprocess — your bot's code doesn't need to change at all.
Why This Isn't a Code Bug
It's worth being explicit about this because it's a common source of wasted debugging time: developers often spend hours reviewing their bot's event handlers, checking for memory leaks, or adding try/except blocks everywhere, when the actual issue has nothing to do with the bot's logic. The platform simply never sees an HTTP response from the process, and reacts accordingly. Once the HTTP server is in place, the exact same bot code that was "randomly" going offline typically runs without interruption.
If Self-Ping Is Also Needed
Some free tiers go a step further and sleep a service after a period with no incoming traffic, even with a valid open port. If that's also happening, staypresent.cron() generates that traffic itself by pinging your own public URL on a schedule:
staypresent.cron("https://my-app.onrender.com", interval=240)
This must target your actual public URL — pinging 0.0.0.0 or 127.0.0.1 never leaves the machine and won't count as activity.
Full Working Fix
import os
import staypresent
staypresent.web.json({"status": "running"})
staypresent.cron("https://my-app.onrender.com", interval=240)
staypresent.run(
"bot.py",
port=int(os.getenv("PORT", 8080)),
restart_on_crash=True,
max_restarts=5,
)
Install it with:
pip install staypresent[prod]
FAQs
Why did my bot work fine for the first few minutes, then stop?
Many platforms give a grace period before their first health check, or before an inactivity timer kicks in — this is why the failure often looks delayed rather than immediate.
Does this affect bots hosted on a VPS too?
Only if you're using a hosting layer (Docker health checks, a managed platform on top of the VPS) that also expects an HTTP port. A bare VPS with no such layer generally doesn't have this issue, though it also won't automatically restart a crashed bot without something like StayPresent or a system service managing it.
Is this the same issue as "my bot's dyno/container keeps restarting"?
Usually yes — a restart loop is often the platform repeatedly trying to health-check a process that never opens the expected port, giving up, and restarting it, over and over.
Conclusion
A bot that mysteriously goes offline after a few minutes on free hosting is very rarely a bug in the bot itself — it's almost always a missing HTTP port that the hosting platform expects but never receives. Wrapping your existing bot script in staypresent.run() fixes it without touching your bot's own logic at all.
pip install staypresent[prod]
Top comments (0)