Last updated 13 March 2015. Created on 8 October 2012.
Edited by mikeryan, HongPong, StryKaizer. Log in to edit this page.

If at all possible, you should execute your migrations using Drush rather than the UI for all but the smallest projects. To understand why, you need to understand a bit about how each method works.

Drush runs at the command line and is not subject to any time limits (in particular, PHP's max_execution_time does not apply). So, when you start a migration process running via drush, it simply starts up and keeps running until it's done.

When running processes through a web interface, the PHP max_execution_time (typically 30 seconds if not less) applies. Thus, for long-running processes we need to use the Batch API, which manages the breaking up of a process across multiple requests. So, a migration process will start up, run for 25 seconds or so, then stop and let the Batch API issue a fresh page request, in which the migration process is restarted, ad infinitum.

So, understanding that, why is Drush better?

It's faster

The Batch API introduces a lot of overhead - shutting down and reinvoking the page requests, the migration process needs to run through all the necessary constructors again, database connections reestablished and queries rerun, etc. And, for a partial import, it needs to pick up where it left off - if the first 500 source records have been imported, it needs to find the 501st record. Depending on your source format and how its constructed, this may or not scale - if you're using highwater marks with an SQL source, the query itself can eliminate the earlier records and start right where you left off. If not, then Migrate needs to scroll through the source data looking for the first non-imported record. With, say, a big XML file as your source, after many iterations it may very well take longer than your PHP max_execution_time to get to where you can pick up, and your migration can stall.

It's more reliable

Running migrations through your browser adds your desktop, and your local Internet connection, as points of failure. A network glitch when Batch API is moving to the next page request, a browser crash, an accidental close of the wrong tab or window can all interrupt your migration. Running in drush reduces the moving parts - you eliminate your desktop and local Internet connection as factors.

It's more helpful

If something does go wrong when running in Drush, if there are any useful error messages you'll see them. Failures using the Batch API often get swallowed up and all you get to see is a completely useless message like "An AJAX HTTP request terminated abnormally. Debugging information follows. Path: /batch?id=901&op=do StatusText: ResponseText: ReadyState: 4 ".

Best of both worlds

As of Migrate 2.6, you can now configure your server to be able to trigger drush imports from the UI. You won't get the immediate feedback you would either from a normal UI import, or running drush directly at the command line, but you will gain the reliability and performance benefits of drush.

Drush memory issue while migrating?

Sometimes php in command line is configured to unlimited memory usage.
For big imports, ensure you are running drush migrations with a memory limit set for php, else drush wont spawn a new process until your entiry memory is used.
An example for doing this is:
php -dmemory_limit=256M /path/to/drush/drush.php mi YourMigrateClass

Looking for support? Visit the forums, or join #drupal-support in IRC.