limits - WireCatLabs/tg-cli GitHub Wiki
Use this page when a command waits, stops with a rate-limit error, or when you plan to download a lot
of history or run several commands at once. It explains how fast tg talks to Telegram, why it
sometimes waits, and what to do when it stops. By the end you will know which waits are normal, how
to change the pace, and when to try again.
Words this page uses:
-
Pace: how many requests a profile may send to Telegram per minute.
tgkeeps every profile under it. - FLOOD_WAIT: Telegram's answer "wait N seconds". If you keep asking during the wait, the waits grow.
- Spam limit (PEER_FLOOD): Telegram limits an account that writes to too many strangers.
- Background job: a download that keeps running after the command that started it ends.
tg waits out short waits from Telegram and stops when a wait is long.
Every request tg makes for a profile — from a command, tg personal mcp, tg personal serve or a background job —
takes a turn in one pace for that profile:
- a burst of 20 requests goes at once, so ordinary commands never wait;
- after the burst, one request a second (60 a minute), until the allowance refills while idle.
Two commands at once share the same pace. The turns are kept in a file under the state folder
(pace/<profile>.json), so two terminals, several messages sync --background jobs and serve line up
behind each other instead of each going at full speed. Running five fetches in parallel is no faster
than running them one after another, and it is no riskier either. Different profiles — different
Telegram accounts — have their own pace each.
A command that has to wait more than 5 seconds for its turn says so on stderr:
waiting 12 s to keep this profile's pace with Telegram
Change the pace in the config file, or for one shell with an environment variable:
{ "defaults": { "requests_per_minute": 30 } }TG_REQUESTS_PER_MINUTE=30 tg personal messages sync "Book club"0 turns the pace off. Do that only for a profile you can afford to have limited.
| How long Telegram asks | What tg does |
|---|---|
| up to 10 s, in a one-shot command | waits, at most twice, and says so on stderr |
up to 2 min, in serve and watch
|
waits, at most three times |
| longer | stops with exit code 8 (rate_limited) and retryAfterMs in the JSON |
messages sync and messages download --all wait out a wait of up to 5 minutes between pages and go on;
a longer one stops the run, and the next run resumes from what was already saved. messages sync --all
also waits through short Telegram waits while listing chats.
A wait holds the whole profile. Until it ends, every process's next request waits past it, and one
that would have to wait more than 5 minutes fails at once with exit code 8 without asking Telegram.
tg personal doctor and tg personal server status list what is held under flood. Once the wait is over, nothing needs
to be done; tg personal flood clear lifts it early if you know Telegram no longer limits the account.
-
30 sends an hour per profile by default (
sends_per_hour), counted across processes; see the send guard. - Spam limit (PEER_FLOOD) and a frozen account hold every write; reads still work. See troubleshooting.
- A send that may or may not have arrived is never repeated by
tg; see when the outcome is unknown.
-
messages sync: pages of up to 100 messages,--pausebetween pages (1 s by default), 1000 messages a run unless--limitsays otherwise.--dry-runcounts the requests first and sends none. -
messages download --all: one request per page and per file; files are paced too. -
messages sync --alllists the chats a page of 100 at a time, one turn of the pace each. -
chats list --allreads every chat in one turn: one request per 100 chats, back to back. -
chats members list --all: pages of 200 members, 1 s apart, up to Telegram's cap of 10,000. - Gap repair reads page by page with a 1 s pause, as
messages syncdoes.
messages sync --background and store gaps repair --background start a job that outlives the command:
one job per chat at a time, each in its own process, all on the profile's one pace. tg personal store jobs list shows them, tg personal store jobs cancel <job> stops one after its current page. See
downloading in the background.
A bot's own Bot API limits are separate from the account's. tg respects the retry_after Telegram
sends back; a long one ends the run. See bots.
Each tg process opens its own connection with the profile's login. Several at once work, but every
one of them is a request source for the same account — which is why they share the pace.