Telegram Bots

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
  1. Why MTProto clients need sessions
  2. What a session file is
  3. Getting API credentials
  4. Create the session locally, then deploy it
  5. String session or session file?
  6. Keeping session files across restarts
  7. Using MTProto clients as bots
  8. Handling flood waits
  9. A word on userbots and the rules
  10. Troubleshooting
  11. Summary

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 default SQLiteSession.
  • 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 *.session and *.session-journal to .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.