Migrate Emails from Gmail to Another IMAP Server
If you decided that you want to move away from Gmail, you can migrate all emails from Gmail to a different
IMAP server. Using the tool imapsync
that’s an easy task. It transfers emails
from one IMAP server to another and preserves all email data including headers, attachments, timestamps, and folder structure.
In this guide, I’m using imapsync
version 1.977 on Linux. Find a list of installation guides for different
Linux systems in this directory on GitHub.
There’s already a good official
guide on how to use imapsync with Gmail.
I encourage you to read that guide first, I’ll only describe some of the additional information I consider to be useful
in this blog post. Server 1 is Gmail and server 2 is your destination IMAP server. The destination IMAP server can
already contain emails, imapsync
does not delete any email on the destination server by default.
Instead of using the --password1
/--password2
arguments, you should provide the passwords for the two IMAP servers
through a text file so that it’s not saved in the Shell history.
First the Gmail server: The IMAP server is imap.gmail.com
and the username [email protected]
. For the password you
have to generate an app password, it will not work with your Gmail account password. Google provides instructions for
generating app passwords. Generate an App Password for the app
Mail and store the 16-character password in a text file called password1.txt
. Remember to remove the app password
from your Google account after the email migration is complete. For the destination IMAP server, figure out the server
host, the username, and your password. Store the password in a file called password2.txt
.
Gmail is not exposing system folders (e.g. sent emails, trash, drafts, etc.) with the [Gmail]/
prefix anymore (the
version of imapsync
I’m using assumes that) but with [Google Mail]/
. You can see that in this output from a dry run:
Host1 folder 16/22 [[Google Mail]/All Mail] Size: 6769848488 Messages: 71145 Biggest: 31498222
Host2 folder 16/22 [[Google Mail].All Mail] does not exist yet
Host2-Host1 -6769848488 -71145 -31498222
The command --regextrans2 "s,\[Google Mail\].,,"
will overwrite the default behavior and replace the [Google Mail]/
prefix instead of the [Gmail]/
prefix.
If you have emails that have more than one label in Gmail, you have to pay special attention to this situation. The
IMAP protocol only supports folders, but not labels. Gmail will expose the labels as folders, so emails with multiple
labels will be shown in multiple folders and essentially be duplicated. Note that emails that are starred or marked as
important are also exposed through respective folders. The imapsync --gmail1
argument includes the
--skipcrossduplicates
argument which will copy every email only once, even when it is contained in multiple folders.
It will only copy it in the first listed folder, so pay attention to the order of folders when you perform the dry run.
Use the arguments --folderfirst
/--folderlast
to change the order. I use the argument --folderlast "Starred"
to
copy all starred emails in the end, so that only starred emails without labels will be copied (all others will be copied
to the respective label folder).
I use the --exclude "All Mail"
argument because I only want to copy emails with at least one label. To check which
emails I leave behind in Gmail, I use the Gmail search has:nouserlabels -label:sent -label:chats -label:trash
.
It will list all emails that don’t have any labels, are not in the Sent folder, and are not in the trash. If you want
to transfer unlabeled emails, use --folderlast "[Google Mail]/All Mail"
instead, which will copy all unlabeled emails
to the All Mail
folder.
Before you copy the emails, perform a dry run with --dry
which will describe what imapsync
would do without actually
copying any emails. Carefully check the output to make sure it’s exactly what you want to do.
./imapsync --host1 imap.gmail.com --user1 [email protected] --passfile1 password1.txt \
--host2 imap.example.com --user2 [email protected] --passfile2 password2.txt \
--gmail1 \
--regextrans2 "s,\[Google Mail\].,," \
--folderfirst "INBOX" \
--exclude "All Mail" \
--exclude "Important" \
--exclude "Spam" \
--folderlast "Starred" \
--addheader --dry
Once you started the actual copy process without the --dry
argument, this might take a long time. For my setup, I
averaged around 1 message per second (average message size was 160 KB). That resulted in 20 hours of copy time
for my 70,000 emails. I recommend running this command from a server, Raspberry Pi, or computer that will not be turned
off.