El bot responde a cada mensaje hasta que cierras la tapa del portátil; entonces los usuarios dejan de recibir respuestas. Un VPS pequeño lo soluciona por unos dólares al mes. El mejor VPS para un bot de Telegram depende de cómo recibe las actualizaciones el bot: puede pedírselas a Telegram o recibirlas cuando Telegram las envía.
Esa elección determina los puertos, el certificado y la necesidad de conectividad IPv4 pública.
La versión corta
- Para un bot en un VPS, usa long polling. No necesita dominio, certificado ni puerto abierto.
- Los webhooks necesitan HTTPS en el puerto 443, 80, 88 o 8443 y una IPv4 pública. Telegram no entrega webhooks por IPv6.
- 512 MB of RAM is a workable start for one bot with no local database.
- Mantén el bot activo con systemd o la política de reinicio de Docker si ya usas contenedores.
- Elige según la IPv4 y el margen de RAM, además del precio anunciado.
Polling o webhooks: la decisión que define los requisitos del servidor
Un bot recibe actualizaciones de dos formas. Con long polling llama a getUpdates y Telegram mantiene la petición abierta hasta recibir una actualización o agotar el plazo; todas las conexiones parten del servidor. Con webhooks registras una URL una vez con setWebhook y Telegram envía cada actualización mediante POST por HTTPS.
| Requisito | Long polling (getUpdates) |
Webhook (setWebhook) |
|---|---|---|
| Puerto entrante | Ninguno; solo peticiones salientes | HTTPS en 443, 80, 88 o 8443 |
| IPv4 pública | No necesaria | Necesaria; los webhooks no admiten IPv6 |
| Dominio y certificado | No necesarios | Certificado necesario; suele usarse un dominio, pero un certificado autofirmado puede usar la IP como CN |
| Proceso | Se ejecuta continuamente | Responde continuamente a peticiones HTTPS |
La columna de webhooks sigue los requisitos de Telegram para webhooks.
Para saber qué método usa tu bot, consulta la Bot API:
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getWebhookInfo"
Si la respuesta contiene "url":"", no hay webhook configurado y el bot puede usar long polling. bot.start() de grammY usa long polling por defecto; python-telegram-bot usa run_polling() o run_webhook().
Para un bot con su propio VPS elegiría polling, también la recomendación predeterminada de grammY. Los webhooks convienen si ya hay un proxy inverso (un servidor web que reenvía peticiones HTTPS al bot), varios bots comparten una entrada HTTPS o se usa una plataforma serverless. En ese caso, Caddy obtiene y renueva el certificado sin tareas cron.
Una interrupción breve retrasa los mensajes sin perderlos. Según las reglas de actualizaciones de la Bot API, Telegram guarda las actualizaciones hasta 24 horas hasta que el bot las recibe, con ambos métodos, y reintenta las peticiones webhook fallidas antes de desistir.
Si el webhook ocupa su puerto directamente, limita el acceso a los rangos de origen publicados por Telegram. Si el puerto 443 lo comparte un proxy inverso con otros sitios, restringe solo la ruta del webhook o usa el token secreto de Telegram sin bloquear el resto del tráfico HTTPS. La guía de webhooks enumera dos rangos de origen y advierte que pueden cambiar. Con UFW como cortafuegos del host:
sudo ufw allow 22/tcp # keep SSH open before you enable the firewall
sudo ufw allow proto tcp from 149.154.160.0/20 to any port 443
sudo ufw allow proto tcp from 91.108.4.0/22 to any port 443
sudo ufw allow 80/tcp # if your HTTPS setup uses HTTP validation or redirects HTTP to HTTPS
sudo ufw enable
Cambia 443 si el webhook escucha en 80, 88 o 8443. Estas reglas protegen un bot ejecutado directamente en el host. La documentación del cortafuegos de Docker indica que un puerto publicado evita UFW, por lo que un contenedor iniciado con -p 443:443 sigue abierto a todos. Configura también secret_token en setWebhook. Telegram lo devuelve en la cabecera X-Telegram-Bot-Api-Secret-Token de cada petición; tu manejador rechaza las que no lo incluyan.
Mantener el bot activo: systemd o Docker
Ejecutar un bot 24/7 exige reiniciarlo tras fallos y reinicios del sistema. En un VPS lo hace systemd, o Docker si distribuyes el bot como imagen.
Una unidad de systemd es un archivo de configuración corto que indica al sistema de inicio cómo arrancar y reiniciar un programa. Crea /etc/systemd/system/telegram-bot.service:
[Unit]
Description=Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
User=bot
WorkingDirectory=/opt/bot
EnvironmentFile=/opt/bot/.env
ExecStart=/opt/bot/venv/bin/python bot.py
# Node: ExecStart=/usr/bin/node bot.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Guarda el token en un archivo .env del proyecto como BOT_TOKEN=... y léelo con os.environ["BOT_TOKEN"] (Node: process.env.BOT_TOKEN) para dejarlo fuera del código. Después copia el proyecto a su ubicación y arráncalo:
sudo mkdir -p /opt/bot
sudo cp -r ~/your-bot/. /opt/bot/ # your project, after git clone or scp from your machine; include .env and requirements.txt
sudo apt install -y python3-venv # Debian/Ubuntu
sudo useradd --system --no-create-home bot
sudo chown -R bot:bot /opt/bot
sudo -u bot python3 -m venv /opt/bot/venv
sudo -u bot /opt/bot/venv/bin/pip install -r /opt/bot/requirements.txt
# Node: skip the venv and pip commands above, then run:
cd /opt/bot && sudo -u bot npm ci
sudo chmod 600 /opt/bot/.env
sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot
systemctl status telegram-bot # look for: Active: active (running)
sudo journalctl -u telegram-bot -f # follow the bot's logs
Restart=always reinicia el bot tras una salida normal o un fallo; on-failure omite las salidas normales, según el manual de systemd.service. RestartSec=5 espacia los intentos y WantedBy=multi-user.target junto con enable inicia el bot al arrancar. Si se reinicia continuamente, sudo journalctl -u telegram-bot -n 50 muestra la traza. Comprueba primero si falta BOT_TOKEN.
El equivalente en Docker es una opción:
docker run -d --name telegram-bot --restart unless-stopped --env-file .env your-bot-image
docker logs -f telegram-bot
En Compose, la línea es restart: unless-stopped. La documentación de reinicio de Docker indica que el contenedor vuelve tras salir o reiniciarse el daemon, pero no tras detenerlo manualmente. Eso cubre los reinicios si Docker arranca con el sistema, como ocurre por defecto en Debian y Ubuntu. En otros sistemas, ejecuta sudo systemctl enable docker.service.
Mi regla: un script en una máquina pequeña usa systemd, sin otro daemon en memoria. Si ya creas imágenes o ejecutas contenedores, usa Docker y cuenta con la RAM que consume su daemon.
Ninguna herramienta avisa de que el bot está caído. Un monitor push de Uptime Kuma en otro servidor sí puede. El bot llama periódicamente a su URL y Uptime Kuma avisa por Telegram cuando las llamadas cesan.
Dónde fallan el alojamiento gratuito y los servidores domésticos
Render suspende un servicio web gratuito tras 15 minutos sin tráfico entrante y su documentación del nivel gratuito sitúa la reactivación en aproximadamente un minuto. Un bot en polling no recibe tráfico entrante y acaba detenido. Telegram reactiva un bot webhook con su POST, con un arranque en frío tras periodos tranquilos. La utilidad del alojamiento gratuito depende del método del bot.
La guía de grammY enumera las plataformas serverless como adecuadas para webhooks; long polling necesita una máquina siempre encendida. Fly.io factura por uso y exige una tarjeta registrada.
Un Raspberry Pi o un PC antiguo puede ejecutar un bot en polling mientras funcionen la máquina, la electricidad y la conexión. Los webhooks desde casa también necesitan una dirección pública y redirección de puertos. Para un bot de aficionado, cualquiera de esas opciones gratuitas puede bastar.
Un VPS sirve para ambos métodos por un precio mensual fijo.
Cinco proveedores de VPS comparados para un bot de Telegram
La tabla compara cinco planes básicos de pago para bots de Telegram con precios mensuales anunciados, vigentes en octubre de 2026 y antes de impuestos. Se indican las promociones aplicables.
| Proveedor | Especificaciones del plan básico | Precio mensual | IPv4 pública | Facturación |
|---|---|---|---|---|
| Cloudzy | 1 vCPU (AMD EPYC), 512 MB DDR5, 20 GB NVMe, 1 TB de transferencia | 2,48 $ en promoción (4,95 $ habitual) | Incluida, junto con IPv6 | Por hora o mes |
| DigitalOcean | 1 vCPU, 512 MiB, 10 GiB SSD, 500 GiB de transferencia | Desde 4 $ | Incluida | Por segundo, con tope en el precio mensual |
| Vultr | 1 vCPU, 512 MB, 10 GB SSD, 512 GB de transferencia | Desde 2,50 $ solo IPv6; desde 3,50 $ con IPv4 | Solo en el plan de 3,50 $ | Por hora o mes |
| Hetzner (Alemania/Finlandia) | 2 vCPU, 4 GB, 40 GB SSD, 20 TB de transferencia | Desde 5,49 € sin IVA | Extra, desde 0,50 €/mes sin IVA (IPv6 gratis) | Por hora, con un límite igual al precio mensual |
| Linode (Akamai) | 1 vCPU, 1 GB, 25 GB de almacenamiento, 1 TB de transferencia | Desde 5 $ | Incluida | Por hora o mes |
El plan solo IPv6 de Vultr no tiene IPv4 y el precio de Hetzner excluye la dirección IPv4. Sin ella ninguno recibe webhooks.
Un bot en polling puede usar solo IPv6, ya que api.telegram.org tiene dirección IPv6. Todos los destinos que contacte también deben tenerla: registros de paquetes, host Git y cada API. Comprueba cada host antes de elegir:
dig +short AAAA api.telegram.org
dig +short AAAA github.com
dig +short AAAA pypi.org # repeat for every host your bot or its installs reach
Una respuesta vacía significa que ese host no tiene dirección IPv6.
¿Bastan 512 MB para un bot de Telegram?
Empezaría con 512 MB para un bot sin base de datos local. La documentación de python-telegram-bot no especifica un requisito de memoria. Depende de qué comparta el servidor: el sistema operativo, el daemon de Docker si se utiliza y cualquier base de datos local. Mide el uso.
free -m # "available" is your headroom; the Swap row shows swap use
ps -o rss,cmd -p "$(systemctl show -p MainPID --value telegram-bot)" # bot's resident memory, in KB
docker stats --no-stream # per-container memory, if the bot runs in Docker
journalctl -k | grep -i "out of memory" # kernel OOM kills
Un cierre por falta de memoria (OOM) ocurre cuando el kernel termina un proceso para liberar RAM. systemd reinicia el bot; esa línea del registro puede ser la única evidencia. Pasa a 1 GB si aparecen cierres OOM, se usa swap constantemente o antes de añadir una base local o un segundo bot.
Cuál elegir
Para un bot elegiría 512 MB con IPv4 pública incluida. Después importan el precio, el margen de recursos y la ubicación de los usuarios.
- Menor precio mensual actual: Cloudzy a 2,48 $ durante su promoción del 50 %, con IPv4 e IPv6 incluidas.
- Menor precio actual con IPv4: Cloudzy a 2,48 $ durante la promoción, con IPv4 dedicada e IPv6 incluidas.
- 1 GB of headroom for Docker or a small database: Linode, from $5 a month.
- Varios bots o una base y usuarios en Europa: Hetzner ofrece más recursos por euro en esta tabla cuando el plan está disponible (en octubre de 2026 figuraba como no disponible). Añade la tarifa IPv4 para webhooks.
- Más disco y transferencia con 512 MB: Cloudzy. Entre estos planes de 512 MB tiene más almacenamiento (20 GB NVMe frente a 10) y transferencia (1 TB frente a unos 500 GB), con IPv4 e IPv6 incluidas. Su precio promocional actual también es inferior al de los otros planes básicos comparados.
Al precio promocional actual, Cloudzy combina el menor coste mensual de esta comparación con más almacenamiento y transferencia que los otros planes de 512 MB. Su plan de 512 MB se factura por hora y ofrece una garantía de devolución del dinero de 14 días, para probar el bot unos días antes de comprometerte. Elige la ubicación más cercana a los usuarios, despliega un VPS Linux de Cloudzy y añade la unidad systemd anterior.
Preguntas frecuentes
¿Cuál es el VPS más barato para ejecutar un bot de Telegram?
Con los precios vigentes en octubre de 2026, el plan de Cloudzy de 512 MB es el más barato de los cinco: 2,48 $ al mes durante la promoción del 50 %, con IPv4 dedicada e IPv6 incluidas. Su precio habitual es 4,95 $ al mes. La opción Vultr solo IPv6 cuesta un poco más, desde 2,50 $.
¿Por qué necesitan HTTPS los webhooks de Telegram?
Telegram exige SSL/TLS para los webhooks independientemente del puerto, según su guía de webhooks. Rechaza HTTP sin cifrar y acepta TLS 1.2 o posterior. Sin TLS, cada POST llevaría los mensajes de los usuarios sin cifrar. Sirve un certificado Let's Encrypt o un certificado autofirmado cargado con setWebhook.
¿Puede un bot de Telegram funcionar con 512 MB de RAM?
Normalmente sí, para un bot sin base local. Vigila los cierres por falta de memoria en el registro del kernel y pasa a 1 GB si aparecen o al añadir una base.
¿Cómo mantengo el bot funcionando después de reiniciar?
Activa su servicio systemd con sudo systemctl enable --now telegram-bot o ejecuta el contenedor con --restart unless-stopped y activa docker.service para que Docker arranque con el sistema.
¿Telegram limita los bots por dirección IP?
La FAQ de Telegram sobre límites de bots los describe por bot y por chat; cambiar de servidor no debe considerarse una forma de eludirlos. Al superar un límite, la API devuelve HTTP 429 con retry_after. Espera esos segundos antes de reintentar.
¿Qué región elijo para un bot de Telegram?
Elige la región más cercana a los usuarios y servicios que contacta el bot y mide la conexión desde cada candidata con curl -o /dev/null -s -w '%{time_connect}\n' https://api.telegram.org.
Debate
Comentarios
Inicia sesión para unirte al debate.