Blog
3 min read

How to Host a Telegram Bot: Polling vs Webhooks, and Where to Run It

Telegram bots receive messages in one of two ways: long polling (your bot asks Telegram) or webhooks (Telegram calls your URL). How each works, which hosting fits each — a VPS, serverless functions, a container platform — with setup steps, token safety and the common mistakes.

A Telegram bot is a program that receives messages from Telegram and replies. Before choosing where to host it, you need to decide how it gets messages — because that decides what kind of hosting fits.

Two ways to receive updates

Long polling

Your bot repeatedly asks Telegram, "any new messages?" (getUpdates). Each request stays open until something arrives or a timeout passes, then the bot asks again.

  • ✅ Simple, works anywhere — even your laptop, with no public URL.
  • ❌ The program must run all the time.

Webhooks

You give Telegram an HTTPS URL. When a message arrives, Telegram sends it to your URL. (What is a webhook?, Webhooks vs polling)

  • ✅ Nothing runs while idle; scales well; fits serverless.
  • ❌ Needs a public HTTPS address with a valid certificate.

You can't use both at once — setting a webhook disables getUpdates.

Which hosting fits which

Hosting Polling Webhook
VPS / always-on server ✅ ✅ (with HTTPS)
Serverless functions (Cloudflare Workers, Vercel, Lambda) ❌ ✅
Container platform worker ✅ ✅
Free host that sleeps when idle ❌ (bot goes offline) ⚠ slow first reply

Keep the token safe

Create your bot with @BotFather to get its token. Treat it like a password:

# .env — and add .env to .gitignore
TELEGRAM_TOKEN=123456:ABC...

If it leaks, revoke it with BotFather (/revoke) and update your app. (Environment variables explained)

Option 1: polling on a server

The simplest reliable setup. With python-telegram-bot:

import os
from telegram.ext import ApplicationBuilder, CommandHandler

async def start(update, context):
    await update.message.reply_text("Hello!")

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

Run it as a systemd service with Restart=always so it survives crashes and reboots — the same setup as a Discord bot or any long-running Python script.

Option 2: webhook on a server

Your bot runs a small web server, behind a reverse proxy with HTTPS:

bot.example.com {
    reverse_proxy 127.0.0.1:8443
}

Then tell Telegram where to send updates, with a secret token so you can verify requests really come from Telegram:

curl "https://api.telegram.org/bot$TELEGRAM_TOKEN/setWebhook" \
  -d "url=https://bot.example.com/telegram" \
  -d "secret_token=$WEBHOOK_SECRET"

Telegram then sends the header X-Telegram-Bot-Api-Secret-Token with each update — check it and reject anything else. (What is Caddy?)

Option 3: webhook on serverless

A function receives the update, handles it, replies. Cheap and zero maintenance for simple bots. Limits to know: function time limits (long tasks need a queue), cold starts, and no in-memory state between requests — store state in a database. (What is serverless?)

Common mistakes

  • Webhook set, then trying to poll (or the reverse) — check with getWebhookInfo; remove a webhook with deleteWebhook.
  • Two copies running with polling — you get Conflict: terminated by other getUpdates request. Stop the old one (often still running on your laptop).
  • Self-signed or expired certificate on the webhook URL.
  • Slow handlers — reply quickly and move long work to a background job, or Telegram retries and you process messages twice. (Background jobs)
  • Bot's data in memory — gone on restart. Use a database.

Debugging

curl "https://api.telegram.org/bot$TELEGRAM_TOKEN/getWebhookInfo"

shows the current webhook, pending updates and the last error Telegram saw.


EasySpawn gives your bot an always-on server with a public HTTPS address — polling or webhook both work — plus a database for its state and automatic restarts. See how it works or join the waitlist.

Related: How to Host a Discord Bot 24/7 · Webhooks vs Polling · How to Run a Python Script 24/7 · What Is a Webhook?

Keep reading