diff --git a/metatags_quick.module b/metatags_quick.module
index 20e81c3..3f93aad 100644
--- a/metatags_quick.module
+++ b/metatags_quick.module
@@ -37,7 +37,8 @@ function metatags_quick_menu() {
   );
 
   $items['admin/config/search/metatags_quick/upgrade'] = array(
-    'page callback' => 'metatags_quick_upgrade',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('metatags_quick_upgrade'),
     'title' => 'Upgrade from nodewords',
     'access arguments' => array('administer content types'),
     'file' => 'nodewords_upgrade.inc',
@@ -163,6 +164,11 @@ function metatags_quick_menu_local_tasks_alter(&$data, $router_item, $root_path)
     return;
   }
   
+  // Don't add meta tags editing links if path based meta tags are disabled.
+  if (!variable_get('metatags_quick_use_path_based', 0)) {
+    return;
+  }
+  
   if (!_metatags_quick_path_based_page()) {
     return;
   }
diff --git a/nodewords_upgrade.inc b/nodewords_upgrade.inc
index a4b2ec9..0ef05ca 100644
--- a/nodewords_upgrade.inc
+++ b/nodewords_upgrade.inc
@@ -11,6 +11,11 @@ function metatags_quick_upgrade() {
       '#type' => 'markup',
       '#markup' => '<p>' . t('This utility will convert the keywords and description from Nodewords table to the Meta tags quick table.') . '</p>'
     );
+    $form['batch_size'] = array(
+      '#type' => 'textfield',
+      '#default_value' => '100',
+      '#description' => t('How many nodes to process during one iteration'),
+    );
     $form['submit'] = array(
       '#type' => 'submit',
       '#value' => t('Convert'),
@@ -25,46 +30,13 @@ function metatags_quick_upgrade() {
 }
 
 function metatags_quick_upgrade_submit($form, &$form_state) {
-  $_SESSION['http_request_count'] = 0;
-  $batch = metatags_quick_upgrade_batch();
+  $batch = metatags_quick_upgrade_batch($form_state['values']['batch_size']);
   batch_set($batch);
 }
 
-function metatags_quick_upgrade_batch() {
-  $num_operations = metatags_quick_get_node_count();
-  drupal_set_message(t('Converting metatags for @num nodes', array('@num' => $num_operations)));
-  $operations = array();
-  $select = db_select('node', 'n')->fields('n', array('nid'));
-  $nids = $select->execute()->fetchAll(PDO::FETCH_ASSOC);
-  if (!empty($nids)) {
-    $rows = array();
-    foreach ($nids as $nid) {
-      $operations[] = array('metatags_quick_convert_metatags', array($nid, t('(Operation @operation)', array('@operation' => $nid))));
-    }
-  }
-  $batch = array('operations' => $operations, 'finished' => 'metatags_quick_convert_metatags_finished');
-  return $batch;
-}
-
-function metatags_quick_convert_metatags($nid, $operation_details, &$context) {
-  $select = db_select('nodewords', 'n')->fields('n', array('content'))->condition('n.name', 'keywords')->condition('n.id', $nid)->range(0, 1);
-  $keywords = $select->execute()->fetchField();
-  $keywords = unserialize($keywords);
-  $select = db_select('nodewords', 'n')->fields('n', array('content'))->condition('n.name', 'description')->condition('n.id', $nid)->range(0, 1);
-  $description = $select->execute()->fetchField();
-  $description = unserialize($description);
-  $node = node_load($nid);
-  $node->meta_keywords['und'][0]['metatags_quick'] = substr($keywords['value'], 0, 255);
-  $node->meta_description['und'][0]['metatags_quick'] = substr($description['value'], 0, 255);
-  node_save($node);
-  $context['message'] = t('Converting node "@title"', array('@title' => $node->title)) . ' ' . $operation_details;
-  _metatags_quick_update_http_requests();
-}
-
-function metatags_quick_convert_metatags_finished($success, $results, $operations) {
+function metatags_quick_upgrade_finished($success, $results, $operations) {
   if ($success) {
-    drupal_set_message(t('@count results processed in @requests HTTP requests.', array('@count' => count($results), '@requests' => _metatags_quick_get_http_requests())));
-    drupal_set_message(t('The final result was "%final"', array('%final' => end($results))));
+    drupal_set_message(t('@node_count results processed in @requests iterations.', array('@node_count' => $_SESSION['nodewords_upgrade_total'], '@requests' => count($results))));
   }
   else {
     $error_operation = reset($operations);
@@ -72,12 +44,66 @@ function metatags_quick_convert_metatags_finished($success, $results, $operation
   }
 }
 
-function _metatags_quick_update_http_requests() {
-  $_SESSION['http_request_count']++;
+
+function metatags_quick_upgrade_batch($batch_size) {
+  if ($batch_size < 2) {
+    $batch_size = 1;
+  }
+  $num_operations = metatags_quick_get_node_count();
+  $_SESSION['nodewords_upgrade_total'] = $num_operations;
+  $_SESSION['nodewords_upgrade_processed'] = 0;
+  drupal_set_message(t('Converting metatags for @num nodes', array('@num' => $num_operations)));
+  $operations = array();
+  $nid_result = db_select('node', 'n')
+    ->fields('n', array('nid'))
+    ->execute();
+  $nids = array();
+  foreach ($nid_result as $node) {
+    $nids[] = $node->nid;
+    if (count($nids) >= $batch_size) {
+      $operations[] = array('metatags_quick_convert_metatags', array($nids));
+      $nids = array();
+    }
+  }
+  if (count($nids)) {
+    $operations[] = array('metatags_quick_convert_metatags', array($nids));
+  }
+  $batch = array(
+    'operations' => $operations,
+    'progress_message' => t('Completed :nodes_completed of :nodes_total', array(
+      ':nodes_completed' => $_SESSION['nodewords_upgrade_processed'], ':nodes_total' => $_SESSION['nodewords_upgrade_total'])),
+    'finished' => 'metatags_quick_upgrade_finished',
+    'file' => drupal_get_path('module', 'metatags_quick') . '/nodewords_upgrade.inc',
+  );
+  return $batch;
 }
 
-function _metatags_quick_get_http_requests() {
-  return !empty($_SESSION['http_request_count']) ? $_SESSION['http_request_count'] : 0;
+function metatags_quick_convert_metatags($nids) {
+  $processed_nodes = node_load_multiple($nids);
+  $select = db_select('nodewords', 'n')
+    ->fields('n', array('id', 'name', 'content'))
+    ->condition('n.name', array('keywords', 'description'), 'IN')
+    ->condition('n.id', $nids, 'IN')
+    ->execute();
+  foreach ($select as $row) {
+    $keywords[$row->id][$row->name] = unserialize($row->content);
+  }
+  
+  foreach ($processed_nodes as $node) {
+    $_SESSION['nodewords_upgrade_total']++;
+    $node_changed = FALSE;
+    if (!empty($keywords[$node->nid]['keywords'])) {
+      $node_changed = TRUE;
+      $node->meta_keywords[$node->language][0]['metatags_quick'] = substr($keywords[$node->nid]['keywords']['value'], 0, 255);
+    } 
+    if (!empty($keywords[$node->nid]['description'])) {
+      $node_changed = TRUE;
+      $node->meta_description[$node->language][0]['metatags_quick'] = substr($keywords[$node->nid]['description']['value'], 0, 255);
+    }
+    if ($node_changed) {
+      node_save($node);
+    }
+  }
 }
 
 function metatags_quick_get_node_count() {
