← back to blog

Keeping a Telegram connection up when the server reboots

The support ticket that never changes

Almost every hosting problem we get asked about starts the same way: “everything was working, I rebooted the server, and now the bot or client won’t reconnect.” Nine times out of ten, Telegram itself did nothing wrong. The reboot took something with it that nobody was watching, and the client just quietly failed to come back.

This isn’t a Telegram-specific quirk. It’s what happens to any long-lived network service running on a machine that gets restarted, and it’s worth understanding the mechanics instead of just restarting things until it works again.

What a Telegram connection actually is

A Telegram client, whether it’s the desktop app, a userbot script, or something built on MTProto directly, holds a persistent TCP connection to one of Telegram’s data centers. That connection carries an authenticated session, tied to an auth_key generated once during login and stored locally in a session file (or in memory for some client libraries, but written to disk periodically).

The connection itself is not fragile. MTProto clients are built to expect drops. Mobile networks flap constantly, so every reasonable client library has reconnect logic with backoff built in. If your laptop’s wifi cuts out for ten seconds, Telegram Desktop reconnects on its own and you never notice.

A server reboot is a different kind of event. It’s not a network blip the client can ride out, because the process that holds the connection stops existing entirely. The question isn’t “will the client reconnect,” it’s “will anything start the client again, and will it start in an environment that’s actually ready.”

The three things that usually go wrong

When someone tells us their Telegram service “doesn’t survive reboots,” it’s almost always one of these three problems, not the connection layer.

The process was never told to restart

If you started your client by hand, SSH’d in, ran python bot.py, and left it running in a terminal, a reboot kills that process and nothing brings it back. This is the most common cause, and it has nothing to do with Telegram. Any process run this way behaves identically.

The fix is process supervision. On a Linux VPS that means a systemd unit, not a background shell job. A minimal unit for a Telegram client or proxy process looks like this:

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

[Service]
ExecStart=/usr/bin/python3 /opt/telegram/bot.py
Restart=always
RestartSec=5
User=telegram

[Install]
WantedBy=multi-user.target

Two lines matter more than the rest. After=network-online.target and Wants=network-online.target tell systemd not to start the process until the network stack is actually usable, not just until the network service has been enabled. Restart=always with a RestartSec means if the process crashes for any reason, including a bad reconnect, systemd brings it back without you touching the server.

The network wasn’t ready when the process started

This one is sneakier. Some distributions bring up network.target before DNS or DHCP has actually finished, which is why network-online.target exists as a separate, stricter target. If a service starts before DNS resolution works, and the client tries to resolve Telegram’s data center hostname before that’s possible, you get a connection failure that looks identical to a broken client, except it’s a timing problem that only shows up on cold boot.

This is also why RestartSec=5 matters instead of Restart=always with no delay. If the first attempt fails because the network genuinely wasn’t ready yet, the built-in delay gives the network a few seconds to finish coming up before the second attempt.

Firewall rules didn’t come back

If you’re running your own MTProto proxy, or you’ve hardened the box with iptables rules for the ports Telegram uses, remember that raw iptables rules live in memory. They do not persist across a reboot unless something reloads them at boot. This trips people up constantly because the rules were correct, tested, and working right up until the reboot, at which point the box comes back with a clean, empty ruleset (or whatever the distro default is) and the proxy port is unreachable from outside even though the proxy process itself is running fine.

On Debian-based systems the usual fix is iptables-persistent, which saves the current ruleset and reloads it on boot. On systems using nftables, the equivalent is enabling and configuring the nftables systemd service so it loads /etc/nftables.conf at startup. Whichever you use, the test is simple: reboot the box on purpose, then check the ruleset from a cold boot rather than trusting that it survived because it worked yesterday.

Proxies and the IP problem

If you’re running a personal MTProxy instance, the proxy link you hand out (or configure in a client) encodes an IP address and port. That’s fine as long as the server’s public IP doesn’t change. On most VPS providers it won’t, because you’re paying for a static allocation. But on some smaller providers, or on a home connection behind DHCP, a reboot can trigger a new IP lease, which silently invalidates every proxy link that was built around the old address.

If your hosting setup uses a dynamic IP for any reason, the practical fix is a DNS name with a short TTL pointed at the box, updated automatically on boot or on IP change, rather than distributing raw IP addresses in proxy links. It adds one moving part, but it’s a moving part you control, instead of a manual re-share every time the address changes.

Session files and why shutdown order matters

The auth_key and session state for a client library get written to a session file on disk. Most libraries write to this file periodically, not on every single message, which means an ungraceful kill (a hard power cut, or a reboot that doesn’t let the process shut down cleanly) can catch the file mid-write.

A corrupted session file doesn’t just cause a reconnect failure, it can force a full re-authentication, which for account safety reasons is exactly the kind of event you want to avoid triggering unnecessarily. Repeated forced logins on the same account raise the account’s risk profile with Telegram’s anti-abuse systems, especially if they happen from different IPs.

Two things reduce this risk. First, give the process a real chance to shut down cleanly. Systemd sends SIGTERM before SIGKILL by default, with a timeout you can configure via TimeoutStopSec, so a graceful reboot (as opposed to a hard power-off) generally gives the client time to flush its session file if the library handles SIGTERM correctly. Second, if you’re running the client in Docker or another container, make sure the container’s stop signal is actually forwarded to the client process and not swallowed by an init shim that doesn’t propagate it.

A practical boot sequence

Put together, a setup that reliably survives a reboot looks like this: systemd unit with Restart=always, dependency on network-online.target, firewall rules persisted through iptables-persistent or the nftables service, and a session file path on a disk that mounts before the service starts (this matters more than it sounds like it should if you’re using a separate data volume). None of these are Telegram-specific configurations. They’re standard Linux service hygiene, applied to a service that happens to be a Telegram client.

What none of this fixes

Solid process supervision gets your client running again after a reboot. It doesn’t protect the underlying account from the normal consequences of unstable infrastructure, like flood waits triggered by reconnecting too aggressively, or scrutiny triggered by logging in from a new IP after a proxy’s address changes. Reliability and account safety are related but separate problems, and a setup that’s good at one isn’t automatically good at the other.

If you’re weighing whether to keep managing this yourself or hand the infrastructure side to someone who does it full time, that’s exactly the gap we built telegramvault.org to close: telegramvault.org.

Get new guides and videos first — join the Telegram channel.

need infra for this today?