HYEHOST

How to Host a Telegram Bot 24/7 with Python

Host a Python Telegram bot 24/7 with BotFather, long polling and secure tokens. Deploy on bot hosting or an Ubuntu VPS, with restart and troubleshooting steps.

Explore Bot HostingBuild the Python bot
HYEHOST bear mascot running a Python Telegram bot beside a server and blue chat panel

A Telegram bot can deliver service notifications, answer community questions or provide a chat interface for an existing application. The first local test is usually easy. Keeping that same bot available after closing a terminal, protecting its credentials and understanding why it stopped responding take a little more care.

We will build a small private-chat bot with /start and /ping, deploy it on HYEHOST Bot Hosting, and show an Ubuntu VPS alternative for people who want full operating-system control. The sample does not store conversations, execute chat messages as commands or require a public web server.

1. Choose bot hosting or a VPS

Choose the environment around your application, not just the headline price. A managed runtime is convenient when you want to upload code and operate it through a panel. A VPS is useful when your bot needs custom system packages, several cooperating services or deeper control over networking and scheduling.

OptionGood fitWhat to check
Free Bot HostingLearning and very small experiments128 MB RAM is tight; check dependencies and renew every 30 days.
Paid Bot HostingA lightweight Python bot with panel-based deploymentChoose sufficient memory, storage and CPU for peak activity.
Cloud VPSCustom packages, databases and operating-system controlYou manage updates, service supervision, security and backups.

HYEHOST Bot Hosting supports Python, Git deployment, live metrics and automatic recovery, with placement in Wolverhampton, UK or Ashburn, US. Place the bot near its other dependencies where practical. That is especially useful when a bot repeatedly calls your own application or database; it is not a promise that every Telegram user will see lower latency.

The paid plans currently provide:

PlanMonthlyCPURAMStorage
Starter$10.5 vCPU1 GB20 GB
Standard$21 vCPU2 GB30 GB
Pro$3.502 vCPU4 GB50 GB

Free Bot Hosting includes 0.05 CPU, 128 MB RAM, 512 MB storage, a 10 Mbps connection, one NAT port and a dedicated IPv6 address. It requires manual renewal every 30 days. Treat it as a measured starting point, not a guarantee that every Python dependency stack will fit. The polling example below does not need to listen on the NAT port.

2. Create the bot with BotFather

Open the official @BotFather account in Telegram, send /newbot, and follow the prompts for the bot name and username. Save the generated token in a password manager. Telegram's BotFather documentation explains registration and token management.

The token is a credential, not a public identifier. Anyone who obtains it may be able to operate the bot through the API. Do not paste it into a public repository, support screenshot or blog comment. If it has already been exposed, revoke it through BotFather and replace it in the deployment. Removing it from the latest Git commit does not remove it from history.

Open a private chat with the new bot so it is ready for testing. It will not reply yet: BotFather has registered the account, but your Python process is not running.

3. Start with long polling, not an exposed webhook

With long polling, your process asks Telegram for updates over outbound HTTPS. With a webhook, Telegram delivers updates to your reachable HTTPS endpoint. They are alternatives, not two features to turn on together. See Telegram's webhook guide for the delivery model.

Polling is a sensible first choice for one continuously running bot: you do not need a domain, reverse proxy or public inbound port. You still need working outbound access to Telegram and any APIs your bot uses. Do not assume that an IPv6 address alone guarantees reachability to every external dependency.

Run only one polling process per token. Stop a local test before starting the hosted copy. If you are moving an existing webhook bot, stop the old deployment and deliberately switch delivery methods; the library's polling startup removes the webhook. Keep pending updates unless you intentionally want to discard that backlog. Telegram documents the relationship between getUpdates and webhooks in its bot FAQ.

4. Build a minimal Python Telegram bot

Use a supported Python runtime; Python 3.12 is a suitable choice for this example. We pin python-telegram-bot to version 22.8 for reproducibility. Its package metadata requires Python 3.10 or newer. Review release notes and test before changing the pinned version later.

Create a project directory with bot.py and requirements.txt. Put this single dependency in requirements.txt:

python-telegram-bot==22.8

Save the following as bot.py. It deliberately responds only to commands in private chats, reads its token from the environment, and avoids printing incoming messages or full HTTP request URLs.

import logging
import os

from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes, filters

# HTTP request logs can contain the bot token in the URL.
logging.basicConfig(level=logging.WARNING)
logging.getLogger("httpx").setLevel(logging.CRITICAL)
logging.getLogger("httpcore").setLevel(logging.CRITICAL)


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    if update.effective_message:
        await update.effective_message.reply_text(
            "Hello! I am running. Send /ping to check my response."
        )


async def ping(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    if update.effective_message:
        await update.effective_message.reply_text("Pong! The bot is responding.")


async def report_error(update: object, context: ContextTypes.DEFAULT_TYPE) -> None:
    # Do not dump updates, tokens or request URLs into production logs.
    logging.error("Bot error type: %s", type(context.error).__name__)


def build_application() -> Application:
    token = os.environ.get("TELEGRAM_BOT_TOKEN", "").strip()
    if not token:
        raise SystemExit("Set TELEGRAM_BOT_TOKEN before starting the bot.")
    application = Application.builder().token(token).build()
    application.add_handler(CommandHandler("start", start, filters=filters.ChatType.PRIVATE))
    application.add_handler(CommandHandler("ping", ping, filters=filters.ChatType.PRIVATE))
    application.add_error_handler(report_error)
    return application


if __name__ == "__main__":
    build_application().run_polling(allowed_updates=["message"])

The asynchronous handlers send a reply through the library's application and command-handler interfaces. The project maintains official examples for more advanced conversations and integrations. This starter is intentionally narrow: it is not a group moderation bot, an authentication system or a durable task queue.

For a local test on Linux or macOS, create a virtual environment and install the dependency:

python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements.txt

In Bash, enter the token without placing its value directly in shell history. Run these commands in the same terminal:

read -r -s -p "Telegram bot token: " TELEGRAM_BOT_TOKEN
printf "\n"
export TELEGRAM_BOT_TOKEN
python bot.py

Send /start and /ping in the bot's private chat. You should receive the two responses defined above. Stop the local process with Ctrl+C before deploying elsewhere, then clear the shell variable with unset TELEGRAM_BOT_TOKEN. The example uses an environment variable; it does not automatically load a .env file.

5. Deploy on HYEHOST Bot Hosting

  1. Choose a location and resources. Select Wolverhampton or Ashburn, then a plan with room for the Python runtime, dependency installation and workload. Starter is a practical paid starting point for testing this small bot.
  2. Select a compatible Python runtime. Use Python 3.12 where available, or another supported version compatible with the dependency.
  3. Upload or deploy your project. Include bot.py and requirements.txt. If deploying through Git, keep credentials and local virtual environments out of the repository.
  4. Install the requirements. Use the platform's dependency installation workflow for requirements.txt. Check installation output for failed packages before troubleshooting the bot itself.
  5. Set the environment variable. Add TELEGRAM_BOT_TOKEN with the BotFather token in the service configuration, not in a public startup script.
  6. Set the startup command. Use python bot.py from the project directory, then start the service.
  7. Test from Telegram. Check /start and /ping, inspect live resource metrics, restart the service through the panel and confirm it responds again.

No web-server port needs to be exposed for this polling deployment. If a later feature accepts external webhooks, it becomes a different network requirement and should be configured and secured separately.

A process labelled “running” is only one check. A bot can remain alive while an upstream API is failing or a handler is stuck. Test a real interaction after releases, review recurring errors, and investigate sustained memory or CPU pressure before increasing traffic.

6. Alternative: run the bot on an Ubuntu VPS

Choose Cloud VPS when you want to manage the operating system or run other services alongside the bot. The example below targets Ubuntu 24.04 with systemd and a sudo-capable administrator. Keep your existing firewall rules; polling does not require opening a new inbound port.

Install Python tooling and create a dedicated service account on a fresh deployment. If that account or directory already exists, inspect it rather than repeating setup blindly.

sudo apt update
sudo apt install python3-venv
sudo useradd --system --create-home --home-dir /opt/telegram-bot --shell /usr/sbin/nologin telegrambot
sudo -u telegrambot python3 -m venv /opt/telegram-bot/.venv

Upload your reviewed bot.py and requirements.txt to your administrator's current directory. Copy those two files into the application directory and install the pinned dependency as the service user:

sudo install -o telegrambot -g telegrambot -m 0640 bot.py requirements.txt /opt/telegram-bot/
sudo -u telegrambot /opt/telegram-bot/.venv/bin/python -m pip install -r /opt/telegram-bot/requirements.txt

Create a root-only environment file, then edit it without putting the token in a command argument:

sudo install -m 0600 -o root -g root /dev/null /etc/telegram-bot.env
sudoedit /etc/telegram-bot.env

Add TELEGRAM_BOT_TOKEN=your_actual_token as the file's single line. The install command above is for a new file; do not rerun it over existing credentials. Systemd reads this file before starting the process as the unprivileged user. Environment variables are convenient here, but are not a secret vault: restrict administrator access and never dump the service environment into support logs.

Use sudoedit /etc/systemd/system/telegram-bot.service to create:

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

[Service]
Type=simple
User=telegrambot
Group=telegrambot
WorkingDirectory=/opt/telegram-bot
EnvironmentFile=/etc/telegram-bot.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/telegram-bot/.venv/bin/python /opt/telegram-bot/bot.py
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
UMask=0077

[Install]
WantedBy=multi-user.target

Enable the service and inspect its status:

sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot
sudo systemctl status telegram-bot --no-pager
sudo journalctl -u telegram-bot -n 50 --no-pager

Restart=on-failure handles unsuccessful exits; it does not repair faulty code or guarantee availability. Repeated startup failures can hit systemd's start-rate limit. Fix the cause, then use sudo systemctl reset-failed telegram-bot and sudo systemctl restart telegram-bot. The upstream systemd service reference describes restart behaviour.

During an appropriate maintenance window, reboot the VPS and test the bot again. Closing SSH is not the same as testing boot recovery. For future updates, stop the service, deploy reviewed code and dependencies, restart it and verify a real reply. Keep a known-working release so you can roll back.

7. Make the deployment useful beyond the first reply

Measure the workload before choosing bigger resources

A command bot that mostly waits for messages is different from a bot that downloads large attachments, renders images or analyses files. Watch peak memory during startup and dependency installation as well as normal operation. Limit attachment sizes, concurrent jobs and log retention so one request cannot fill the disk or exhaust the process.

If you add an AI integration, distinguish calling an external model API from running a model locally. The latter needs separately sized compute and memory; a low-cost bot runtime is not a substitute for an inference server. For paid APIs, add an allowlist, per-user limits and spending controls before opening access.

Keep permissions and stored data deliberate

The sample commands reveal no private account information. A real admin bot needs server-side authorisation based on Telegram user or chat IDs; a private chat by itself does not make someone an administrator. Never pass user messages directly to a shell or interpolate them into database queries.

The sample is stateless. If you add reminders, subscriptions or application records, persist them in a database or files on persistent storage, not just a Python dictionary. Back up that state and practise restoring it. Re-running a startup command does not recover information that existed only in RAM.

Monitor the service and its dependencies

Use the panel's metrics for bot resources. On a VPS, our Beszel monitoring guide shows how to watch host and container health. Combine resource monitoring with application-level checks and error alerts. Avoid sending the only failure alert through the same bot that might be broken.

One process with automatic restart is not a highly available system. Do not attempt to achieve failover by starting a second polling copy with the same token. More complex worker and delivery architectures need deliberate coordination and duplicate-safe job handling.

8. Troubleshoot a Telegram bot that is not responding

SymptomLikely checkNext step
Missing token at startupThe environment variable is absent or empty.Set TELEGRAM_BOT_TOKEN in the environment used by the actual service, then restart.
401 or invalid tokenThe token is incorrect, revoked or copied with extra characters.Verify it privately in BotFather and update the deployment without logging its value.
409 conflictAnother poller is running, or delivery configuration conflicts.Stop old copies and check webhook state before retrying.
ModuleNotFoundErrorDependencies were installed into another Python environment.Install requirements with the same interpreter used by the startup command.
Works privately, not in a groupThis sample intentionally uses private-chat filters.Design group handlers and permissions explicitly; also review Telegram privacy mode.
429 / RetryAfterThe application is sending too quickly.Respect the returned retry delay and queue work; do not retry in a tight loop.
Killed or repeatedly restartingMemory pressure, dependency errors or process failures.Inspect resource peaks and logs before changing the plan.
Running but silentWrong bot, wrong command, failed outbound access or a blocked handler.Test /ping in the correct private chat and inspect errors without exposing credentials.

For a bot previously using webhooks, the Bot API's getWebhookInfo method reports its webhook configuration; deleteWebhook switches away from it. Use a trusted local tool or library call with the token kept out of shared logs. Do not paste a token-bearing API URL into a public diagnostic service.

Before you call it finished

  • The bot responds to a real command after deployment and restart.
  • Only one polling process uses its token.
  • Credentials are outside Git and logs; exposed tokens have been revoked.
  • Dependencies are pinned and the Python runtime is compatible.
  • Resource use has been measured under representative activity.
  • Persistent application data has a tested backup and recovery path.
  • External API calls have timeouts, access controls and sensible limits.
  • Free plans have a reminder for manual renewal every 30 days.

Telegram bot hosting FAQs

How do I keep a Telegram bot running 24/7?

Run its code on an always-on bot hosting service or VPS, configure restart behaviour and check that it responds after deployment and reboots. Creating the bot in BotFather alone does not host your program.

Can I host a Telegram bot for free?

A very small bot may fit HYEHOST Free Bot Hosting: 0.05 CPU, 128 MB RAM, 512 MB storage and a 10 Mbps connection. You must renew manually every 30 days. Test actual memory use; larger dependencies or workloads may need a paid plan.

Does a Telegram bot need a domain or public port?

Not when using long polling. The process makes outbound HTTPS requests to Telegram. A webhook deployment instead needs an HTTPS endpoint that Telegram can reach.

Can I run two copies of the same polling bot?

Do not run two getUpdates pollers with the same token. Stop the laptop or old deployment before starting the replacement. A second poller can cause conflict errors rather than provide failover.

Which HYEHOST plan should I use for a Python Telegram bot?

Bot Starter provides 0.5 vCPU, 1 GB RAM and 20 GB storage for $1/month, making it a practical starting point to test a lightweight bot. Use measured resource consumption to choose a larger plan, or choose a VPS when you need root access and system packages.

Is a Telegram API bot suitable for local AI models?

Calling an external AI API and running a model locally are different workloads. A lightweight bot can act as an API client, but local inference needs separately sized compute and memory. Add user authentication, request limits and spending controls before exposing paid APIs.