How to Run a Telegram Bot on a VPS 24/7 (Python + Systemd Guide)
A Telegram bot running on your laptop shuts down the moment you close the lid. A Telegram bot running on a VPS runs 24/7, responds to messages instantly at any hour, and doesn’t depend on your local machine being on. For any bot that needs to be reliably available β customer service bots, notification systems, automation tools, community management bots β a VPS is the right home.
This guide covers building a Python Telegram bot with python-telegram-bot, deploying it to Ubuntu VPS, and setting it up as a systemd service that restarts automatically on crashes and reboots.
What You’ll Build
- A Python Telegram bot using the
python-telegram-botlibrary - A systemd service that keeps it running 24/7
- Automatic restart on crash
- Log management so you can monitor bot activity
- Environment variable management for the bot token
Requirements
- Ubuntu VPS 22.04 or 24.04 LTS
- Python 3.10+ installed
- A Telegram bot token from @BotFather
π‘ VPS.DO Tip: A Telegram bot runs comfortably on VPS.DO’s entry-level plans β it uses minimal CPU and RAM. View Plans β
Step 1: Get Your Bot Token from BotFather
- Open Telegram and search for @BotFather
- Send
/newbot - Follow prompts to name your bot
- Copy the API token β it looks like:
7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
Step 2: Set Up the VPS Environment
sudo apt update && sudo apt upgrade -y
sudo apt install python3 python3-pip python3-venv -y
# Create app directory
mkdir -p /var/bots/mybot
cd /var/bots/mybot
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install python-telegram-bot
pip install python-telegram-bot --upgrade
Step 3: Create Your Bot
nano /var/bots/mybot/bot.py
import logging
import os
from telegram import Update
from telegram.ext import (
Application, CommandHandler, MessageHandler,
filters, ContextTypes
)
# Configure logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO,
handlers=[
logging.FileHandler('/var/log/mybot.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# Get token from environment variable
BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN')
# βββ Command Handlers βββββββββββββββββββββββββββββββββββββββ
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /start command"""
user = update.effective_user
await update.message.reply_html(
f"π Hi {user.first_name}! I'm running 24/7 on VPS.DO.\n\n"
f"Available commands:\n"
f"/start - Show this message\n"
f"/help - Get help\n"
f"/status - Check bot status"
)
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /help command"""
await update.message.reply_text(
"I'm a Telegram bot running on a VPS.\n"
"Use /status to check if I'm alive."
)
async def status(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /status command"""
import platform, psutil
cpu = psutil.cpu_percent(interval=1)
ram = psutil.virtual_memory().percent
await update.message.reply_text(
f"β
Bot is online\n"
f"π₯οΈ OS: {platform.system()} {platform.release()}\n"
f"π CPU: {cpu}%\n"
f"πΎ RAM: {ram}%"
)
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Echo all non-command messages"""
await update.message.reply_text(
f"You said: {update.message.text}\n"
f"(Add your logic here)"
)
async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE):
"""Log errors"""
logger.error("Exception while handling update:", exc_info=context.error)
# βββ Main ββββββββββββββββββββββββββββββββββββββββββββββββββββ
def main():
if not BOT_TOKEN:
logger.error("TELEGRAM_BOT_TOKEN not set!")
return
app = Application.builder().token(BOT_TOKEN).build()
# Register handlers
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("help", help_command))
app.add_handler(CommandHandler("status", status))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
app.add_error_handler(error_handler)
logger.info("Bot starting...")
app.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == '__main__':
main()
Install psutil for the /status command
pip install psutil
Test the bot manually first
export TELEGRAM_BOT_TOKEN="your-bot-token-here"
python bot.py
Send /start to your bot in Telegram. If it responds, the bot works. Press Ctrl+C to stop.
Step 4: Create a Systemd Service
sudo nano /etc/systemd/system/mybot.service
[Unit]
Description=My Telegram Bot
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/bots/mybot
Environment="TELEGRAM_BOT_TOKEN=YOUR_BOT_TOKEN_HERE"
ExecStart=/var/bots/mybot/venv/bin/python bot.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
sudo chown -R www-data:www-data /var/bots/mybot
sudo systemctl daemon-reload
sudo systemctl enable mybot
sudo systemctl start mybot
sudo systemctl status mybot
You should see active (running). Your bot is now running 24/7. β
Step 5: Monitor the Bot
View live logs
# Via systemd journal
sudo journalctl -u mybot -f
# Via log file
tail -f /var/log/mybot.log
Check if it’s running
sudo systemctl status mybot
Restart after code changes
sudo systemctl restart mybot
Step 6: Deploying Code Updates
nano ~/deploy-bot.sh
#!/bin/bash
echo "Deploying bot update..."
cd /var/bots/mybot
git pull origin main
source venv/bin/activate
pip install -r requirements.txt --quiet
sudo systemctl restart mybot
echo "Bot restarted β
"
sudo systemctl status mybot --no-pager
chmod +x ~/deploy-bot.sh
Step 7: Webhook Mode (Alternative to Polling)
Polling has the bot constantly check Telegram for updates. Webhook mode has Telegram push updates to your VPS β more efficient for high-traffic bots.
# In bot.py, replace app.run_polling() with:
app.run_webhook(
listen="0.0.0.0",
port=8443,
url_path=BOT_TOKEN,
webhook_url=f"https://yourdomain.com/{BOT_TOKEN}",
cert='/etc/letsencrypt/live/yourdomain.com/fullchain.pem',
key='/etc/letsencrypt/live/yourdomain.com/privkey.pem',
)
Webhook mode requires a domain with valid SSL. For most personal and small business bots, polling mode is simpler and perfectly adequate.
Popular Telegram Bot Use Cases on VPS
| Use Case | What it does |
|---|---|
| Customer support bot | Auto-respond to FAQs, route to human agent |
| Server monitoring bot | Send CPU/RAM/disk alerts to a Telegram channel |
| Price alert bot | Monitor prices and notify when thresholds hit |
| Content scheduler | Post scheduled messages to channels/groups |
| File conversion bot | Accept files, process them, return results |
| VPS management bot | Start/stop services, check status via Telegram |
Final Thoughts
A Telegram bot on a VPS is one of the most practical automation tools you can build. It costs almost nothing to run (under 50 MB RAM, negligible CPU for most bots), is immediately accessible from any Telegram client, and with systemd managing the process, it runs reliably without any manual intervention.
VPS.DO’s entry-level KVM VPS plans are perfectly sized for hosting multiple Telegram bots alongside other applications.
- πΊπΈ USA VPS β from $20/month
Related articles: