Blog

Parallel Mailbox Migration: Running 50+ At Once Safely

A working guide to parallel mailbox migration: concurrency math, throttle awareness, bandwidth, when to throttle yourself, and monitoring at scale.

DO

Dan Okafor

MSP Practice Lead

Reviewed by Alex Kerr
· 13 min read
Server room with racks of equipment

You have 500 mailboxes to move and a weekend to do it. Serial migration is not going to finish in time. Parallel migration introduces a different problem: providers throttle, networks saturate, and a migration that runs 32 mailboxes concurrently can be slower than one that runs eight, because half of the connections are sitting in backoff. This post is about how to do parallel mailbox migration well: how to pick a concurrency number, how to read the early warning signs of throttling, and what to monitor while the run is in flight.

Skip the manual setup — let Mailbox Taxi handle it

One desktop app, every IMAP provider, zero data leaving your machine.

What "parallel" actually means

There are at least three things people mean when they say a migration runs in parallel:

  1. Mailbox-level parallelism: multiple users' mailboxes move simultaneously.
  2. Folder-level parallelism: within a single mailbox, multiple folders move in parallel.
  3. Connection-level parallelism: multiple IMAP connections per folder pulling different message ranges.

Most tools support mailbox-level parallelism out of the box. Folder-level is common. Connection-level is rarer and usually only matters for the unusually large mailboxes (say, over 25 GB) where a single connection's throughput is the bottleneck.

For a 500-mailbox project, mailbox-level parallelism is the dominant lever. The other two help on edge cases.

If you have not yet looked at the wider operational pattern, the MSP email migration playbook covers the project structure that wraps around the concurrency choices below.

The concurrency math

A useful mental model: total throughput is the minimum of (per-mailbox throughput x concurrency, provider rate limits, your bandwidth, your CPU). You pick concurrency to push throughput up until one of the other limits becomes the bottleneck.

Per-mailbox throughput

A typical IMAP fetch over a single connection moves 5–30 messages per second, with most of the variation coming from average message size. For an average size of 50 KB and a fetch rate of 15 messages per second, a single connection moves about 750 KB/s, or 6 Mbit/s.

For larger mailboxes with bigger average messages (many attachments), throughput per connection rises as the connection spends more time on payload and less on header overhead.

Total throughput at scale

At a concurrency of 16, with the numbers above, you are doing roughly 96 Mbit/s of inbound mail and a similar amount outbound. That fits comfortably inside a 1 Gbit/s office link.

At a concurrency of 64, you are pushing 384 Mbit/s. Still fits in 1 Gbit/s but you have less headroom for everything else (Slack, video calls, regular admin work). Plan the migration window so this matters less.

Provider rate limits

The hard limits depend on provider:

  • Gmail / Workspace: roughly 15 simultaneous IMAP connections per account, with per-user per-day data caps that rarely bite for normal-sized mailboxes. IP-level limits exist but are not formally published.
  • Microsoft 365 / Exchange Online: 20 connections per app per mailbox; tenant-level throttling kicks in if you exceed roughly 25 EWS calls per second across all migrating users. Modern Microsoft migrations use the Mailbox Migration API rather than EWS or IMAP where possible.
  • Yahoo, AOL: about 10 simultaneous connections per account; aggressive backoff if you exceed.
  • iCloud: low limits, tight throttling, app-specific passwords required.
  • ProtonMail Bridge: bound by local Bridge throughput, usually a few hundred messages per second total.

Treat these numbers as guidelines. Providers tune them based on load and account history.

The fix IMAP throttling errors post covers what to do when you hit limits; the fix too many IMAP connections post is the specific failure mode for connection-count caps.

Picking your concurrency number

For most MSP migrations, a sensible starting point is 8 to 16 mailboxes in parallel per migration host. That fits comfortably under the per-provider limits, leaves room for retries, and rarely saturates a normal office or datacentre link.

Bump higher only if you have measured headroom in three places:

  1. Provider side: source and destination are accepting connections without throttling.
  2. Network: you are not pegging your uplink.
  3. Tool side: the migration tool itself has CPU and memory to spare.

A pattern that works well in practice:

  • Calibration batch: run 4 representative mailboxes in parallel for the first 30 minutes. Capture throughput, error counts, and any throttle signals.
  • Ramp: if calibration is clean, double to 8. Watch for another 30 minutes.
  • Production batch: 16 mailboxes in parallel if everything is still healthy. Hold at 16 unless you have strong evidence the limits are higher.

The temptation to crank concurrency up to 32 or 64 to "finish faster" usually backfires. Once you are throttled, every connection's effective throughput drops, the tool spends time in backoff and retry, and total throughput goes down.

Higher concurrency is not always faster

At a certain point, increasing concurrency past the provider's limit costs you throughput. The tool keeps reaching for new connections, the provider keeps rejecting them, and the connections that did get through start sharing limited per-account bandwidth.

When to throttle yourself

Self-throttling is unintuitive. It feels like leaving performance on the table. In practice, self-throttling is usually a net win.

Signs you should throttle yourself

  • The provider is sending occasional but persistent throttle responses. Each one costs you 30 seconds to a few minutes of backoff.
  • Average throughput per connection is below half of what calibration showed.
  • The migration tool's queue depth is consistently maxed out.
  • Other applications on the network are slow.

How to throttle

Most tools expose at least these controls:

  • Maximum concurrent mailboxes per host.
  • Maximum connections per mailbox.
  • Maximum messages per second per connection.
  • Maximum bytes per second per host.

Lower one or two of these and observe. The right one to lower depends on which limit you are hitting. If you are getting Too many simultaneous connections, lower per-mailbox concurrency. If you are getting generic rate-limit responses, lower the per-host total.

Bandwidth: where the bytes go

A migration moves mail from source to destination through the migration tool. The tool is either running on a local workstation (in which case the bytes go in and out of your office network) or in a cloud (in which case they go in and out of the cloud region).

For a local-first tool like Mailbox Taxi running on a workstation:

  • Inbound bandwidth: from source provider to your workstation.
  • Outbound bandwidth: from your workstation to destination provider.
  • Both legs are simultaneous, so your effective link load is roughly equal to your migration throughput, in each direction.

For a 1 Gbit/s symmetric link, a sustained 400 Mbit/s of migration traffic is fine. If your link is 100 Mbit/s, the migration itself can saturate it and you will need to schedule outside business hours or move the workstation to a better link.

For VPN connections, throughput is often the bottleneck before anything else. Migrate from a workstation on the office LAN, not from a remote-working laptop over a consumer ISP and a corporate VPN.

Cloud egress fees

If your migration tool runs in a cloud, the provider charges egress on the outbound leg. For a 500-mailbox project at 20 GB average mailbox size, that is 10 TB of egress. At typical cloud egress rates, that adds a meaningful line item. Local-first tools avoid the cloud egress entirely because the bytes leave your office or datacentre directly to the destination provider.

Per-host versus multi-host

A single migration host can usually handle 50 to 100 concurrent mailboxes if it has the CPU, memory, and bandwidth. Past that, you start running into:

  • Single-host bandwidth limits (a workstation NIC is usually 1 Gbit/s).
  • Source-side IP-level throttling (some providers throttle per source IP regardless of account).
  • Operational fragility (one workstation failure stalls the project).

Multi-host migrations distribute concurrent mailboxes across two or more workstations. The advantages:

  • Higher aggregate throughput.
  • Different source IPs for the same provider, reducing IP-level throttling.
  • Failover if one host hangs.

The disadvantages:

  • Coordination overhead. Two hosts running overlapping batches will produce duplicate writes if you are not careful.
  • More log consolidation work.
  • More credentials in more places.

For most MSP migrations under 1,000 mailboxes, a single well-provisioned host is enough. Past that, plan for two or three coordinated hosts.

Monitoring while the run is in flight

A 50-mailbox parallel migration generates enough events that watching the tool's log scroll past is not a strategy. You need real-time visibility on a handful of metrics.

What to watch

  • Concurrent mailbox count: should be at your configured target. Drops below target mean mailboxes are finishing faster than new ones are being scheduled, or worse, that the tool is hung.
  • Per-connection throughput: messages per second or bytes per second. Sudden halving usually means throttling.
  • Error rate: errors per minute, by type. A spike in AUTHENTICATIONFAILED or Too many simultaneous connections is your throttle alarm.
  • Queue depth: mailboxes waiting to start. If this is zero and you still have mailboxes in scope, something is wrong with batching.
  • Estimated time remaining: usually a moving average of recent throughput.

A simple monitoring stack

You do not need Grafana for this. A migration tool that exports a status page or an exportable per-minute log is enough. Plot the last 60 minutes of throughput in a spreadsheet during the run; you will see throttling visually before you see it in errors.

For larger MSPs running migrations week after week, a more permanent monitoring setup pays off. The best tools for MSPs post discusses which tools have built-in dashboards versus which need wrapping.

Watch for the throttle plateau

A migration that hits a throttle limit shows a characteristic shape on a throughput graph: rises smoothly, then plateaus, then sometimes drops as the provider tightens. If your graph is showing a plateau and you are still adding concurrency, you are wasting work.

Handling failures gracefully

At 16+ mailboxes in parallel, some mailboxes will fail intermittently. Common patterns:

  • A single mailbox hits a corrupt message it cannot fetch. Tool retries, fails, moves on.
  • A whole batch hits a transient provider error. Tool backs off and retries.
  • A specific folder type (Sent, Drafts, or Spam) fails on one provider's interpretation of the IMAP spec. Tool needs configuration to skip or treat differently.

Good practice:

  • Allow the tool to skip and continue rather than halting the whole run on a single mailbox.
  • Capture failed-mailbox lists separately so you can rerun them at the end.
  • Keep retries bounded (3 to 5 attempts per mailbox is reasonable).
  • Look at failures in batch at the end of the run, not one by one during it.

The delta vs cutover migration pattern helps here too. A first parallel pass moves the bulk; a smaller second pass catches the failures and the messages that arrived after the first pass started.

Pre-flight checks before kicking off a parallel run

Before pressing start on a parallel batch of 50+ mailboxes:

  • Provider quotas confirmed. Have you verified the concurrent connection limits for the source and destination?
  • Bandwidth available. Is the network link going to be quiet for the duration?
  • Workstation provisioning. Enough CPU (4+ cores), memory (16 GB+), and disk space (200 GB+ free for logs and any local cache).
  • Credentials prepared. OAuth tokens or app passwords for every mailbox in the batch, ideally pre-validated with a 1-message test.
  • Source filters set. Date ranges, folder exclusions, size limits.
  • Logging set up. Per-message, per-mailbox, per-batch detail going to disk.
  • Monitoring open. Throughput and error rate visible on a screen the operator is watching.
  • Communication ready. End users know the window; help desk knows to expect questions.

Most of these are obvious in isolation. Skip any of them and the parallel run will be harder to recover from when something does go wrong.

A worked example: 240 mailboxes over a weekend

A small MSP moves 240 mailboxes for a client from one Microsoft 365 tenant to another over a Friday evening to Sunday evening window.

  • Concurrency: 16 mailboxes in parallel, single workstation.
  • Average mailbox size: 8 GB.
  • Expected throughput per mailbox: 90 minutes for a typical 8 GB mailbox, including retries.
  • Wall-clock estimate: 240 mailboxes / 16 concurrent = 15 sequential slots. 15 x 90 minutes = 22.5 hours of run time. Add 25% buffer for the long-tail mailboxes (20 GB+ users) and you get 28 hours. Fits in a Friday-evening to Sunday-morning window comfortably.

The MSP runs a calibration batch of 4 mailboxes on Thursday evening to verify per-mailbox throughput. Confirms 16 is safe. Starts production at 6pm Friday. By midnight Saturday the bulk is done; 12 mailboxes have failed transient errors and get rerun on Sunday morning. Delta sync catches messages that arrived during the run on Sunday afternoon. MX cutover at 5pm Sunday.

The throughput graph for the weekend shows the characteristic shape: rises in the first 30 minutes as connections warm, holds steady through most of the run, dips for an hour on Saturday morning when the provider applied a tighter rate limit (the tool's automatic backoff handled it), and tails off on Sunday morning as the queue empties.

When to drop concurrency mid-run

Sometimes the right move during a parallel migration is to lower concurrency, not raise it.

Drop concurrency when:

  • Throttling errors are sustained over more than 10 minutes despite the tool's automatic backoff.
  • Other people on the network are complaining.
  • Per-connection throughput has been below 30% of calibration for over 20 minutes.
  • The destination provider is logging warnings about resource use on the destination tenant.

Raising concurrency mid-run is rarely worth it; you have already passed the smooth-ramp phase. Lowering it is a normal operational move. Most tools allow live concurrency adjustment; if yours does not, lower the limit in configuration and restart batches that have not yet started.

Putting it together

Running 50+ mailboxes in parallel is a routine MSP task, not a heroic feat, provided you have done the math, set up monitoring, and built a habit of calibrating before scaling. The teams who struggle with parallel migrations are usually the ones who start with high concurrency and try to debug the throttling that results. The teams who do it well start low, calibrate, and only push higher when the data says it is safe.

For the wider operational context, read the MSP email migration playbook alongside this post. It covers batching strategy, customer communication, and the rest of the project structure that turns a parallel-run capability into a repeatable practice.

Try Mailbox Taxi

Migrate your mailbox the easy way

Join the waitlist for early access and lock in launch pricing.

Related reading

Try Mailbox Taxi

Migrate your mailbox the easy way

Join the waitlist for early access and lock in launch pricing.