Telethon and Pyrogram Session Files: Keep Your Userbot Logged In
How Telethon and Pyrogram session files work, how to create them safely, keep them across restarts and redeploys, and avoid the dreaded re-login loop.
On this page
Bots built with the Bot API authenticate with a token. Clients built on MTProto — Telethon and Pyrogram — authenticate differently: they log in once and store the result in a session. If that session isn’t kept safe and persistent, your client asks for a login code again after every restart, or stops working entirely. This article explains how sessions work and how to host MTProto clients so they stay logged in.
Why MTProto clients need sessions
Telethon and Pyrogram talk to Telegram’s servers using the same protocol as the official apps. They can act as a bot (with a bot token) or as a user account — often called a userbot. Logging in as a user requires your phone number, a code sent by Telegram and, if enabled, your two-step verification password.
After a successful login, the library stores an authorisation key and related data in a session. Next time it starts, it reuses the session instead of logging in again. Lose the session, and you’re back to entering a code — which is impossible on a headless server with nobody to type it.
What a session file is
- Telethon stores sessions in an SQLite file named after the session, such as
mybot.session, via its defaultSQLiteSession. - Pyrogram also stores an SQLite file named after the client, such as
my_account.session, in its working directory by default.
Both libraries also support string sessions — the same authorisation data encoded as a single string you can keep in an environment variable.
Important: A session is equivalent to being logged in to that account. Anyone with the file or string has full access — messages, contacts, groups — without needing a code or password. Guard it like a password, never commit it to git, and never share it when asking for help.
Getting API credentials
MTProto clients need an API ID and API hash, created at my.telegram.org under “API development tools”. These identify your application, not your account. Keep them in environment variables too.
Create the session locally, then deploy it
The first login is interactive, so do it on your own computer, not on the server.
Telethon: generate a string session
from telethon.sync import TelegramClient
from telethon.sessions import StringSession
api_id = int(input("API ID: "))
api_hash = input("API hash: ")
with TelegramClient(StringSession(), api_id, api_hash) as client:
print(client.session.save()) # copy this string somewhere safe
On the server, load it from an environment variable:
import os
from telethon import TelegramClient
from telethon.sessions import StringSession
client = TelegramClient(
StringSession(os.environ["TG_SESSION"]),
int(os.environ["TG_API_ID"]),
os.environ["TG_API_HASH"],
)
Pyrogram: export a session string
from pyrogram import Client
with Client("my_account", api_id=API_ID, api_hash=API_HASH) as app:
print(app.export_session_string())
On the server:
app = Client("my_account", session_string=os.environ["TG_SESSION"],
api_id=int(os.environ["TG_API_ID"]), api_hash=os.environ["TG_API_HASH"])
Development of the original Pyrogram project has slowed in recent years, and several community forks keep it current; the session concepts are the same across them.
String session or session file?
| String session in an env var | Session file on disk | |
|---|---|---|
| Survives redeploys | Yes — it’s configuration | Only if storage persists |
| Easy to rotate | Replace the variable | Replace the file |
| Stores entity cache | No (lost on restart) | Yes |
| Risk of committing to git | Low | Higher — add *.session to .gitignore |
String sessions are the most robust choice for deployment. Session files have one advantage: they also cache entities (users, chats and their access hashes), which reduces lookups after a restart. If you use files, make sure they’re on persistent storage.
Keeping session files across restarts
On Kerit Cloud, your server’s disk is persistent NVMe — session files, SQLite databases and downloaded media survive restarts, redeploys and plan upgrades. That’s one of the main reasons Telegram bot hosting is built around persistent processes rather than ephemeral containers.
A few rules keep file-based sessions healthy:
- Use an absolute or well-known path. If your code runs from a different working directory, the library creates a new, empty session somewhere else — and asks to log in again. Point the session at a fixed path, such as
sessions/mybot. - Add
*.sessionand*.session-journalto.gitignore. Otherwise a git deploy could overwrite the live session with a stale one — or publish it. - Never run two processes on one session file. SQLite allows only one writer; a second process produces
sqlite3.OperationalError: database is locked. This often happens when an old copy is still running on your PC. - Stop the client cleanly. Disconnect on SIGTERM so the session file is written completely before the process exits.
Using MTProto clients as bots
Telethon and Pyrogram can also log in with a bot token, which gives bots features the Bot API doesn’t — such as downloading large files directly. Sessions still apply: the first start(bot_token=...) creates a session, and later runs reuse it. Persisting the session avoids re-authorising the bot on every restart, which Telegram rate-limits.
Handling flood waits
MTProto enforces its own limits. When you exceed them, Telegram responds with a flood wait telling you how many seconds to pause. Telethon raises FloodWaitError (with a seconds attribute) and can sleep automatically for short waits via the flood_sleep_threshold setting. Pyrogram raises FloodWait. Respect these waits — ignoring them makes limits stricter and can lead to account restrictions.
A word on userbots and the rules
Automating a personal account is subject to Telegram’s Terms of Service. Accounts used for spam, bulk messaging or scraping are regularly limited or banned, and a banned account can’t be recovered by your host. Use userbots for legitimate personal automation, move anything public-facing to a proper bot token, and keep activity at a human pace.
Troubleshooting
“Please enter your phone” on the server. The session wasn’t found. Check the path, the working directory, or that TG_SESSION is set.
AuthKeyUnregisteredError / AUTH_KEY_UNREGISTERED. The session was revoked — for example, from “Active sessions” in Telegram settings. Generate a new one locally.
database is locked. Two processes share one session file. Stop the duplicate.
Session works locally but not on the server. Make sure you’re passing the same API ID and hash that created the session.
Summary
MTProto clients like Telethon and Pyrogram stay logged in through sessions, which are full access credentials for the account. Create them interactively on your own machine, then deploy them as a string session in an environment variable — or as a file on persistent storage at a fixed path, excluded from git. Run one process per session, disconnect cleanly, respect flood waits, and your client will survive every restart without asking for a code.