ADR-0012 — Use long-polling (not webhooks) for Telegram updates in MVP-1
Status
Section titled “Status”Accepted — 2026-04-28
Context
Section titled “Context”Telegram offers two delivery modes for bot updates: long-polling
(getUpdates) and webhooks (Telegram POSTs to your HTTPS endpoint).
MVP-1 hosts on a single VPS (ADR-0013) without a public-facing domain or TLS termination. Traffic is sub-100 messages/day, latency budget is “user doesn’t notice” (a couple of seconds is fine).
Considered alternatives
Section titled “Considered alternatives”| Option | Summary | Pros | Cons | Outcome |
|---|---|---|---|---|
| A — Webhook | Telegram POSTs to https://bot.example.com/... | Lowest latency; no polling overhead | Requires public domain, TLS cert (Let’s Encrypt + renew), reverse proxy or aiohttp TLS, firewall rule, hardening against abuse — none of which add value at 100 msg/day | rejected |
| B — Long-polling | Bot calls getUpdates with timeout=30 | Works behind NAT; no domain or cert needed; trivial to develop locally; aiogram defaults | Slightly more wasted CPU on idle polling; one extra second of latency in the worst case | accepted |
Decision
Section titled “Decision”We will use Dispatcher.start_polling(bot) with aiogram’s default
long-polling (timeout 30 s, skip_updates=False). Telegram queues
updates for up to 24 h if the bot is offline; on restart we fetch
the backlog and dedupe via app.processed_update.update_id.
Webhook is a future ADR when:
- the bot must respond in < 1 s (currently no SLO requires it), OR
- the bot fans out to many users (current scope: 2), OR
- we add a web companion that already needs HTTPS (deferred to v1).
Consequences
Section titled “Consequences”Positive
Section titled “Positive”- Zero infrastructure beyond the VPS + Telegram.
- Local development is identical to production: same
start_pollingloop, no need for ngrok or local TLS proxy. - No surface area for inbound abuse (no public HTTP endpoint).
Negative / trade-offs
Section titled “Negative / trade-offs”- Continuous outbound HTTPS connection from VPS to api.telegram.org. Acceptable.
- ~30 s of update backlog is possible after a restart; idempotency
via
processed_update.update_idmakes redelivery safe.
Neutral / follow-ups
Section titled “Neutral / follow-ups”- When traffic > 1 msg/sec sustained or external onboarding ships in MVP-2, write a successor ADR proposing webhooks and revisit.
References
Section titled “References”- aiogram 3 docs —
Dispatcher.start_polling. - Telegram Bot API —
getUpdatessemantics, including 24 h queue.