Reliability

DC migrations

Every account lives on one DC. The first time you talk to the wrong one, the server tells you which DC owns the account; the client migrates and retries. All transparent unless something goes wrong.

What migrations are

Migration errors all have the shape *_MIGRATE_X where * says what kind of resource lives elsewhere and X is the destination DC:

  • PHONE_MIGRATE_X — the phone number is registered on DC X (returned during login).
  • USER_MIGRATE_X — the current session lives on DC X.
  • NETWORK_MIGRATE_X — the IP you connected from belongs to DC X's region.
  • FILE_MIGRATE_X — a specific file is stored on DC X.
  • STATS_MIGRATE_X — channel statistics live on DC X.

Automatic handling

gogram intercepts every *_MIGRATE error before it reaches your code. The sequence is:

  1. Open a fresh connection to DC X.
  2. Run the obfuscation handshake.
  3. Use auth.exportAuthorization on the home DC + auth.importAuthorization on DC X to copy the session.
  4. Cache the new sender so subsequent calls do not re-handshake.
  5. Retry the original call against the new DC.

From your side the call just succeeded — possibly with a slight extra latency the first time it touches a new DC. With CacheSenders: true (default), the per-DC sender stays alive for the rest of the process.

client, _ := telegram.NewClient(telegram.ClientConfig{
	// ...
	OnMigration: func() {
		log.Println("migrated; now on DC", client.GetDC())
	},
})
client, _ := telegram.NewClient(telegram.ClientConfig{
	// ...
	OnMigration: func() {
		log.Println("migrated; now on DC", client.GetDC())
	},
})

Manual migration

You almost never need this, but the building blocks are exposed: SwitchDC(n)on the MTProto layer forces the client onto DC n, doing the handshake and export/import. ExportNewSender(dc, mem) returns a child MTProtobound to that DC so you can issue raw methods against it.

FILE_MIGRATE_X

File migrations work the same way but on a per-call basis — the next download call for a file not on the home DC routes through the cached non-home sender. File DC selection is fully transparent. The only thing you might notice is a small first-chunk latency compared to subsequent chunks of the same file.