EQVPS

How to host a Telegram bot on a VPS (and keep it running)

Jun 15, 2026 · 3 min read · EQVPS Team

A Telegram bot that only runs while your laptop is open isn't really running — it's demoing. To have it actually online, answering at 3am, surviving your reboots and its own crashes, it needs to live on a server. Here's the whole path, start to finish, with the commands.

Good news first: a bot is a tiny workload. It mostly sits idle waiting for messages, so the cheapest box runs it fine — no dedicated IP, no domain, nothing fancy.

1. Get a token from BotFather

In Telegram, message @BotFather, send /newbot, pick a name and username. It hands you a token that looks like 12345:AAH.... Treat it like a password — anyone with it controls your bot.

2. A minimal bot

SSH into the server, set up Python and the library:

sudo apt update && sudo apt install -y python3-venv
mkdir ~/mybot && cd ~/mybot
python3 -m venv venv && source venv/bin/activate
pip install python-telegram-bot

A bot that replies — ~/mybot/bot.py:

import os
from telegram.ext import ApplicationBuilder, CommandHandler

async def start(update, ctx):
    await update.message.reply_text("Alive and on a server. 🟢")

app = ApplicationBuilder().token(os.environ["BOT_TOKEN"]).build()
app.add_handler(CommandHandler("start", start))
app.run_polling()

Note it reads the token from an environment variable — not hardcoded. That matters in the next step.

3. The part that actually keeps it running: systemd

If you just run python bot.py, it dies the moment you close SSH. A systemd service is what makes it survive logout, crashes, and reboots. Create /etc/systemd/system/mybot.service:

[Unit]
Description=Telegram bot
After=network-online.target

[Service]
WorkingDirectory=/home/youruser/mybot
Environment=BOT_TOKEN=12345:AAH...your-token
ExecStart=/home/youruser/mybot/venv/bin/python bot.py
Restart=always
RestartSec=5
User=youruser

[Install]
WantedBy=multi-user.target

Then:

sudo systemctl daemon-reload
sudo systemctl enable --now mybot
sudo systemctl status mybot      # should say active (running)
journalctl -u mybot -f           # live logs

Restart=always is the line doing the real work — crash, and it's back in 5 seconds. enable means it comes up after a reboot. That's the whole difference between "I ran a bot once" and "my bot is up."

4. Why no domain or open ports

The bot uses long polling — it reaches out to Telegram for updates, so nothing needs to reach in. No public URL, no inbound firewall rule, no dedicated IP. This is exactly why a NAT VPS (shared IP, SSH on a port) is a fine and cheap home for a bot. Webhooks exist for very high volume, but you almost certainly don't need them to start.

Honest caveats

That's it. Lock the box down first with the security checklist, drop the service in, and your bot stays online whether or not you do. On a crypto-paid VPS you can have it running a minute after you decide to.

FAQ

What VPS do I need for a Telegram bot?

The smallest one. A Telegram bot is mostly idle, waiting on updates, so 1 GB RAM and 2 cores is plenty for most bots — even fairly busy ones. You only need more if the bot does heavy work itself (image processing, a local model, a big database).

How do I keep a Telegram bot running after I close SSH?

Run it as a systemd service. Unlike launching it in your terminal, systemd keeps it alive after you log out, restarts it if it crashes, and starts it again after a reboot. That's the difference between a toy and something that stays up.

Why does my bot stop when I disconnect?

Because you started it in your SSH session, so it dies when that session ends. Wrap it in a systemd service (or tmux for a quick test) and it runs independently of your login.

Do I need a domain or webhook for a Telegram bot?

No. Long polling (getUpdates) needs no public URL, no domain, no inbound port — the bot reaches out to Telegram. That's why a NAT VPS with no dedicated IP is perfectly fine for a bot. Webhooks are an optional optimization for high volume.

Is it safe to put my bot token on a VPS?

Yes, if you treat it like a password: keep it in an environment variable or a file readable only by the bot's user, never commit it to git, and lock the server down with SSH keys. If a token leaks, revoke it in BotFather and issue a new one.

← Back to blogSee plans & pricing →