Skip to main content

gotd v0.165.0: on the wire like Telegram Desktop

· 4 min read
Aleksandr Razumov
TeamLead @ VK

gotd v0.165.0 changes how gotd talks to Telegram where it matters: fewer bytes per request, Telegram Desktop's ping rhythm, no requests the official clients never send, and server sessions and keys that survive reconnects and restarts. A local clock that is minutes off no longer breaks the client.

How we found the differences​

We recorded Telegram Desktop and gotd doing the same things on the same account (start, open a chat, send, scroll, download, sit idle) with wire traces and diffed them step by step. Most differences were app traffic: a full UI client asks for stickers, emoji and previews. The protocol ones became this release. A few numbers from the same scenarios before and after:

gotd v0.164gotd v0.165Telegram Desktop
invokeWithLayeron every request (9–32 per run)only until the connection is initedonly until the connection is inited
Pingsping_delay_disconnect(75) every 60 s(60) every 30–45 s(60) every ~35 s
Differences in a 5-minute idle (getDifference / getChannelDifference)7 / 103 / 30 / 3

Highlights​

Traffic​

  • invokeWithLayer is sent only until the connection is inited; after CONNECTION_NOT_INITED or CONNECTION_LAYER_INVALID it is sent again until the server accepts it.
  • No get_future_salts: salts come from new_session_created and bad_server_salt, as in Telegram Desktop.
  • Pings like Telegram Desktop. See Pings and salts.
  • upload.getFile sets precise only for unaligned parts, and empty entities vectors are no longer sent.

Sessions and clock​

  • The session keeps the keys of other DCs, so downloads and redirects after a restart don't run a new key exchange and authorization transfer. It also stores the key age, the server time offset and the self ID (client.SelfID() answers without a request). Old session files load unchanged. See Sessions.
  • A reconnect continues the server session. When the server starts a new one, requests it didn't see are re-sent and updates are re-fetched.
  • Server time offset like TDLib: message IDs follow the spec and use server time, so a skewed clock works. See Clock skew.
  • Received messages are deduplicated, also inside containers.
  • PFS: the permanent key is dropped only when the server confirms it's gone.

Updates and peers​

  • Failed differences are retried with backoff (1 s doubling to 60 s), flood waits are waited out, and PERSISTENT_TIMESTAMP_* resets the state. See Failed differences.
  • telegram/peers caches peers and usernames by default; usernames are normalized like TDLib and kept for a day.
  • peers.Manager can be the access hasher of the updates manager, which removes the extra differences for channels the app already knows. See Access hashes.

LogOut and documents​

  • client.LogOut logs out on every DC, returns the future auth token and wipes the session. See Logging out.
  • Uploaded documents get a MIME type from the extension (or application/octet-stream) and a file name. Before, Telegram Desktop could show such a file as an audio track.

Upgrading​

Most changes are additions. Check these:

  • Session continuity: reconnects continue the server session. Duplicate updates are filtered by pts, but after a server-side session loss a write the server already executed may be sent again.
  • Session format: new optional fields, format version unchanged; older gotd versions ignore them.
  • Duplicates: a server message re-sent after more than 100 newer ones is dropped, as the spec intends.
  • Salts: one extra round trip when a salt expires. Set SaltFetchInterval for the old periodic fetch.
  • Pings: every 30–45 s by default; an explicit PingInterval keeps a fixed interval.
  • Peers cache: peers.Options.Cache defaults to an unbounded in-memory cache; pass peers.NoopCache{} to opt out.
  • Difference retries: failures are retried instead of waiting for the 15-minute idle timer.
  • Documents: audio, video and sticker uploads without an explicit MIME type now get one from the extension.

Full list of changes: gotd/td v0.165.0.