Move e-mail accounts to new server

Move e-mail accounts to new server


The simplest way to move e-mail from one machine to another is to simply create the account on the new machine, then copy the entire message store from the old machine to the new one. You can then set a .forward from the old machine to forward all new e-mail to the new one. This is fast, efficient, but has some problems.

When moving from one type of store to another (even between IMAP servers) the structure is not always identical. Also, what permissions and ownerships need to be set. If you do not know any of this, or if you do not have admin access to the servers in question, the best way is to use imapsync Since we do this fairly regularly, and we need to repeat the process several times, I have written a set of scripts to control the imapsync executable. I called it to separate it from the actual application.

NOTE: The basic script comes from

NOTE: I just found out that the author still considers newer versions of imapsync to be open source, but is charging for it now. He has made some fantastic updates, but you can still get the free version in many Linux distribution repositories or by searching the internet.

The scripts can be downloaded at


This script has usernames and passwords in clear text. The output log file has information about your users accounts such as folders, number of messages, and how they log in. This is sensitive information.

This should be installed in a protected folder, owned by root:root, and permissions 0700. The scripts should be owned by root and permissions 0700. The output log file should stay in the protected folder.


The script will run from any directory, but assumes all its little files are in that same directory. However, the sample cron job assumes the directory is /root/bin/imapsync. You will need to modify this if you put it someplace else.


This is a wrapper around imapsync that allows you to rapidly and repeatedly get e-mail from one server to another. I use it to transfer e-mail accounts from one machine to another. There are tools that let you see when the DNS has changed over (no new traffic on source machine, but new traffic on the new one)


  1. Create a folder, owned by root, with permissions 0700
  2. Copy all files into it
  3. chmod 0700 checkTraffic getStats
  4. chmod 0600 users.list.example imapsync.include etc_cron.d_imapsync
  5. mv etc_cron.d_imapsync /etc/cron.d/imapsync
  6. Edit /etc/cron.d/imapsync to set the amount of time between runs, and the location of the scripts. Note, it will not run until a later step.


Following is suggested usage for moving one or more e-mail accounts from one server to another. We usually move a domain at a time, so the instructions are for that.

  • Set your TTL (time to live) to 6 hours on the DNS MX record for the domain you are moving. That means the "world" will check every six hours to see if that entry has changed.
  • Copy users.list.example to users.list.someidentifier. I generally name it after the domain I'm working on, so for, I'd call it I'll use that in the following instructions
  • Edit, adding a few lines. Each line is a four field record, separated by colons (:). The first column is the login on the source machine, the second column is the password, the third column is the login on the target machine, and the last column is the password on the target machine. See users.list.example for an, guess what, example :)
  • Run in testing mode. Since this can take a while for any large e-mail account, I usually do a nohup and background. Since you are not using the default data file name, you will need to pass it in as the first parameter, with the second (and last) parameter containing literally anything to turn on test mode:
  nohup ./ TEST &
  • At this point, the process is running, and you can follow the process by tail -f imapsync.log
  • When the process stops, look at your stats:

The number of messages is meaningless (well, kinda), but what we are looking for is valid logins, making sure you have the correct usernames and passwords. You can look at the logins via the output of getStats, but a simple way is to run these two commands:

  ./getStats | grep Success | wc

The output of the second command (number of e-mail accounts you are checking) should be HALF the number from the first command (each account has two logins, the source and the target). If these numbers match, you are likely configured correctly. If not, go figure out which ones are messing up and fix them.

  • Once getStats shows that you are working, you are ready to do a seed run. This will copy all e-mail from the source machine to the target machine. It will take a long time, depending on your connection speed, the speed of the machines, amount of memory, and number of e-mail messages. It will also likely saturate your network. Best done in the middle of the night. Do this run as:
  nohup ./ &

this will overwrite your log file, and will do actual transfers. NOTE: I have specifically excluded any e-mail over 20 Meg (--maxsize 20971520) as this really puts a strain on things.

  • When the process is done, do a getStats to see what happened. The top part of the summary tells you how many messages you have transferred. NOTE: it is safe to run getStats while the process is running, and it give you an idea of which accounts have been done (and thus your progress).
  • At this point, you can change the DNS to point to the new server. Change your DNS record to point the MX to the new server (and any other records your clients use to check mail such as mail or smtp aliases). Be sure to reset the TTL to some reasonable value, like 24 or 48 hours.
  • You must update the new message store occasionally. For 84,000 messages, it takes about two hours to do a sync (gigabit network, two medium level machines). If you have configured your cron job correctly, simply copy to users.list
  cp users.list

the cron job will note that users.list exists, and run a sync every four hours. The summary (from getStats) will be e-mailed to the user in the MAILTO assignment near the top of the cron file.

  • Theoretically, after six hours (your TTL) the move will be complete. However, some large mail servers will not honor that. I usually run this for 24 hours. After that time, I feel only spammers will be still trying to use the old server. You can see the number of messages coming in on the old server via getStats, but NOTE: if a user deletes or moves an e-mail message on the new server, it will be copied over again on the next sync run.

You can also check the number of messages coming in on the new server. The script checkTraffic accepts one parameter, the domain name. It will look in /var/log/mail.log for any entry matching that domain name. Usually there is a simple word or phrase that the mail server uses to show that a message has been delivered, which is defined as KEYPHRASE at the top of the script. '(delivered via dovecot service)' is used on my DoveCot/Postfix server, so I use that.


Should return the number of e-mails received in the day.

  • At the end of 24 hours, see if any new mail is coming in on the old server. If you are comfortable, you may now delete the old accounts. You should also delete users.list so the cron job will no longer run:

Move e-mail accounts to new server

Last update:
2013-04-30 02:29
Average rating:0 (0 Votes)

You cannot comment on this entry

Chuck Norris has counted to infinity. Twice.