A VPS for Telegram bot hosting is one of the cheapest useful servers you can run. Most chat bots spend their lives waiting for a message, doing a few milliseconds of work, and waiting again. The free tiers and laptop setups people start with usually fail on the boring parts instead: the bot dies when the terminal closes, it sleeps after inactivity, or it stops after a reboot. This guide covers the decisions that actually matter for a Telegram or Discord bot on a small server: how to receive updates, how small the server can be, how to keep the process alive, and where to put it.
First decision: polling or webhooks
How your bot receives updates shapes everything else, so settle this before choosing a server.
Telegram offers two mutually exclusive methods:
- Long polling (
getUpdates): the bot keeps asking Telegram for new messages. It needs no domain, no TLS certificate and no open port. Most libraries default to it. - Webhooks (
setWebhook): Telegram sends each update as an HTTPS POST to your URL. Telegram requires HTTPS and only accepts ports 443, 80, 88 and 8443. You need a domain (or a certificate for the IP) and a web server in front of the bot.
While a webhook is set, getUpdates does not work, so switching back means deleting the webhook first.
Discord works differently. A normal Discord bot opens an outbound WebSocket connection to Discord's gateway and keeps it open, so like polling it needs no inbound port. Discord also supports an HTTP interactions endpoint for slash commands, which behaves like a webhook and needs a public HTTPS URL.
Which to choose:
| Situation | Telegram | Discord |
|---|---|---|
| One bot, getting started | Long polling | Gateway connection |
| Many bots on one server, or a web app already running | Webhook behind Nginx | Gateway, or interactions endpoint |
| No domain yet | Long polling | Gateway connection |
| Strict firewall, no inbound ports wanted | Long polling | Gateway connection |
Polling is not "worse"; it is simpler. Webhooks become worth it when you already run a web server, host several bots behind one domain, or want updates pushed without a constantly open request.
Sizing: how small can the VPS for a Telegram bot be?
Cloudj's smallest plan is 1 vCPU, 1 GB RAM and 20 GB disk, and that is enough for a typical bot written in Python, Node.js or Go, including a small SQLite or Redis store. Live prices are on the pricing page.
Size up when the bot does more than answer messages:
- It runs an AI model locally or processes images, audio or video.
- A Discord bot streams voice or music, which uses steady CPU and bandwidth.
- It shares the server with a database, a dashboard and other bots.
- It serves very large communities with bursts of commands.
Because you can resize CPU and RAM and grow the disk later, starting on the smallest plan and watching the CPU and RAM graphs in the console is a reasonable approach. Shared ("Availability") CPU suits most bots; general purpose makes sense once the bot does real computation.
Keeping the bot alive
A bot started with python bot.py in an SSH session dies when you disconnect. Use a process manager.
Option A: systemd (any language)
systemd ships with Ubuntu, Debian, AlmaLinux and Rocky Linux, so there is nothing extra to install. Create a user and a unit file at /etc/systemd/system/mybot.service:
[Unit]
Description=My Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
User=bot
WorkingDirectory=/home/bot/app
EnvironmentFile=/home/bot/app/.env
ExecStart=/home/bot/app/.venv/bin/python bot.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Then enable it and follow the logs:
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
journalctl -u mybot -f
Keep the bot token in the .env file, readable only by the bot user (chmod 600), never in the code or the repository.
Option B: pm2 (Node.js bots)
If your bot is in Node.js, pm2 gives you restarts, log rotation and a quick status view:
sudo npm install -g pm2
pm2 start bot.js --name mybot
pm2 save
pm2 startup
pm2 startup prints one command to run with sudo; that command makes pm2 start your saved processes at boot. Running both pm2 and a custom systemd unit for the same bot leads to two copies fighting over updates, so pick one.
Setting up a Telegram webhook
If you chose webhooks, put Nginx in front of the bot with a Let's Encrypt certificate (the Nginx reverse proxy with SSL guide walks through it), proxy a secret path to the bot's local port, and register the URL:
curl -X POST "https://api.telegram.org/bot<TOKEN>/setWebhook" \
-d "url=https://bot.example.com/tg-7f3c9a" \
-d "secret_token=<random-string>"
Telegram then sends the X-Telegram-Bot-Api-Secret-Token header with every update; reject requests where it does not match. Check status anytime with getWebhookInfo, which reports the last error if delivery fails.
Where to put the server
For a chat bot, messages travel from the user to Telegram or Discord first, and only then to your server. So the distance that matters most is between your server and the services your bot calls: the platform's API, your database, and any external APIs. In practice:
- If your bot calls APIs or a database hosted in a specific region, put the bot there.
- If the bot also has a web dashboard or mini app that users open directly, place it near those users. For Vietnam and Southeast Asia, best VPS in Singapore is a common choice; for North American communities, see best VPS in the United States.
- If nothing pulls you anywhere, choose a location near you, so SSH feels responsive. Cloudj has no servers in Vietnam, so for a bot run from Vietnam or serving Vietnamese users, Singapore or Hong Kong is the nearest place to start.
The Asia VPS guide and the Americas, Oceania and Israel VPS guide compare the regions in more depth. Singapore and the United States are on the Singapore and United States pages.
Finally, follow each platform's rules: respect Telegram and Discord rate limits and terms, and do not use bots to spam users.
FAQ
Can I run several bots on one small VPS?
Yes. Give each bot its own systemd unit or pm2 process name and its own token file. Watch RAM usage as you add more.
Do I need a domain for a Telegram bot?
Only for webhooks. Long polling works with no domain and no open inbound port.
Should I pay hourly or monthly for a bot?
A bot runs all month, so a prepaid monthly term with included traffic is usually simpler. Hourly billing suits short experiments; remember an hourly server is charged until you delete it, even when stopped.
My bot stopped after a reboot. Why?
It was probably started by hand. Use systemctl enable or pm2 startup plus pm2 save so it starts at boot.
Launch your bot
Deploy the smallest plan in a location that fits your users in the Cloudj console, add your SSH key, and move the bot under systemd or pm2. You can resize later if the bot grows.