Skip to main content
An account can move from one Xitter instance to another, federated or not. Both sides use the Move account page: Settings > Move account, or /account/migrate.
1

Make a migration code on the old instance

The account makes a code with its password. The code works for 24 hours and lets one other instance read the account’s data. A new code replaces the old one.
2

Check on the new instance

On the new instance, the account it moves into enters the old instance’s address and the code, then presses Check. Nothing is copied yet: the new instance asks the old one what it runs and what the account holds, and shows both side by side.
3

Import

The import runs in the background, with its progress and a report on the same page.
4

Finish

The old instance records where the account went and cancels its scheduled posts there. If asked, it leaves “Moved to @name@instance” as the profile’s bio and deactivates the account.

What moves

Files, polls, articles, posts with their threads, quotes, edit history and original times, drafts and scheduled posts, the profile, follows, follow requests, blocks, mutes, muted words, lists, likes, reposts, bookmarks and their folders. Other accounts and posts are matched to ones the new instance already knows (its own, or copies from federation). The report lists accounts it couldn’t find. Every object brought over is recorded, so an import that failed or is run again only adds what’s missing.

What stays behind

  • Followers can’t be moved for them.
  • Encrypted chats stay behind, since their keys never leave the browser.

Refusals and warnings

The new instance refuses when:
  • the old instance exports a newer archive format than it reads;
  • the address is its own;
  • another import is running.
It warns, and starts only once the warnings are accepted, when:
  • the two run different versions, or the same version with a different database schema (one is modified);
  • the two don’t federate with each other, so follows, likes, replies and the like involving accounts there can’t be matched;
  • the account already has posts or follows;
  • files are over the new instance’s size limits.
The old instance must answer over HTTPS on the public internet, unless MIGRATION_ALLOW_HTTP and MIGRATION_ALLOW_PRIVATE are set. Use those for test instances only.

Testing migrations

docker/migration-test.yaml runs two throwaway instances on ports 3101 and 3102. bun scripts/test-migration.ts moves a seeded account between them and checks what arrived. Its first lines give the variables.