diff --git a/addons/nodequeue_service/nodequeue_service.inc b/addons/nodequeue_service/nodequeue_service.inc
index 2fcf3db..62c0262 100644
--- a/addons/nodequeue_service/nodequeue_service.inc
+++ b/addons/nodequeue_service/nodequeue_service.inc
@@ -16,7 +16,7 @@
 function nodequeue_service_get_nodequeues() {
   if (module_exists('nodequeue')) {
     // Fetch all of the queues.
-    $queues = nodequeue_load_queues(nodequeue_get_all_queues(0));
+    $queues = nodequeue_load_multiple(nodequeue_get_all_queues(0));
     if (empty($queues)) {
       return services_error(t('Nodequeue available, but no nodequeues exist.'));
     }
diff --git a/includes/nodequeue.actions.inc b/includes/nodequeue.actions.inc
index 703f615..6a1699d 100644
--- a/includes/nodequeue.actions.inc
+++ b/includes/nodequeue.actions.inc
@@ -40,7 +40,7 @@ function nodequeue_add_action_form($context) {
     $context['queues'] = '';
   }
 
-  $queues = nodequeue_load_queues(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
+  $queues = nodequeue_load_multiple(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
   foreach ($queues as $name => $queue) {
     $options[$name] = $queue->title;
   }
@@ -76,7 +76,7 @@ function nodequeue_add_action_submit($form, &$form_state) {
  * Action to add a node to a queue.
  */
 function nodequeue_add_action($node, $context) {
-  $queues = nodequeue_load_queues($context['queues'], TRUE);
+  $queues = nodequeue_load_multiple($context['queues'], TRUE);
   // Filter out queues by node type. We choose not to use nodequeue_get_queues()
   // because it checks for access control which only matters if we administering
   // a queue.
@@ -116,7 +116,7 @@ function action_nodequeue_add($op, $edit = array(), $node) {
       break;
 
     case 'do':
-      $queues = nodequeue_load_queues($edit['queues'], TRUE);
+      $queues = nodequeue_load_multiple($edit['queues'], TRUE);
       // Filter out queues by node type. We choose not to use
       // nodequeue_get_queues() because it checks for access control which only
       // matters if we administering a queue.
@@ -147,7 +147,7 @@ function action_nodequeue_add($op, $edit = array(), $node) {
       if (!isset($edit['queues'])) {
         $edit['queues'] = '';
       }
-      $queues = nodequeue_load_queues(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
+      $queues = nodequeue_load_multiple(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
       foreach ($queues as $name => $queue) {
         $options[$name] = $queue->title;
       }
@@ -190,7 +190,7 @@ function nodequeue_remove_action_form($context) {
     $context['queues'] = array();
   }
 
-  $queues = nodequeue_load_queues(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
+  $queues = nodequeue_load_multiple(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
   foreach ($queues as $name => $queue) {
     $options[$name] = $queue->title;
   }
@@ -274,7 +274,7 @@ function action_nodequeue_remove($op, $edit = array(), $node) {
         $edit['queues'] = array();
       }
 
-      $queues = nodequeue_load_queues(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
+      $queues = nodequeue_load_multiple(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
       foreach ($queues as $name => $queue) {
         $options[$name] = $queue->title;
       }
diff --git a/includes/nodequeue.admin.inc b/includes/nodequeue.admin.inc
index 9ae8ec7..969db86 100644
--- a/includes/nodequeue.admin.inc
+++ b/includes/nodequeue.admin.inc
@@ -223,7 +223,7 @@ function nodequeue_view_queues() {
   }
 
   // Fetch all of the queues.
-  $queues = nodequeue_load_queues(nodequeue_get_all_queues(25));
+  $queues = nodequeue_load_multiple(nodequeue_get_all_queues(25));
 
   foreach ($queues as $queue) {
     if (!nodequeue_queue_access($queue)) {
@@ -306,6 +306,7 @@ function nodequeue_view_queues() {
     if (user_access('administer nodequeue')) {
       $operations[] = l(t('Edit'), "admin/structure/nodequeue/$queue->name/edit");
       $operations[] = l(t('Delete'), "admin/structure/nodequeue/$queue->name/delete");
+      $operations[] = l(t('Export'), "admin/structure/nodequeue/$queue->name/export");
     }
 
     $rows[] = array(
@@ -369,6 +370,7 @@ function nodequeue_edit_queue_form($form, &$form_state, $queue) {
   }
   else {
     drupal_set_title(t("Nodequeue '@title'", array('@title' => $queue->title)), PASS_THROUGH);
+    $queue->new = FALSE;
   }
 
   $form['description'] = array(
@@ -1114,3 +1116,69 @@ function _nodequeue_autocomplete($sqid, $string) {
   $nodes = nodequeue_api_autocomplete($queue, $subqueue, $string);
   return $nodes;
 }
+
+/**
+ * Export a node queue. Renerate export code.
+ */
+function nodequeue_export_get_code($queue, $indent = '') {
+  ctools_include('export');
+  $output = ctools_export_object('nodequeue_queue', $queue, $indent);
+  $schema = ctools_export_get_schema('nodequeue_queue');
+  $identifier = $schema['export']['identifier'];
+  $output .= $indent . '$' . $identifier . '->roles = ' . ctools_var_export($queue->roles, $indent) . ";\n";
+  $output .= $indent . '$' . $identifier . '->types = ' . ctools_var_export($queue->types, $indent) . ";\n";
+  $output .= $indent . '$' . $identifier . '->subqueues = ' .ctools_var_export($queue->subqueues, $indent). ";\n";
+  return $output;
+}
+
+function nodequeue_export_queue_form($form, &$form_state, $queue) {
+  drupal_set_title(check_plain($queue->title));
+  $code = nodequeue_export_get_code($queue);
+  $lines = substr_count($code, "\n") + 1;
+  $form['export'] = array(
+    '#title' => t('Export data'),
+    '#type' => 'textarea',
+    '#value' => $code,
+    '#rows' => $lines,
+    '#description' => t('Copy the export text and paste it into another site using the import function.'),
+  );
+  return $form;
+}
+
+function nodequeue_import_form($form, &$form_state) {
+  $form['import'] = array(
+    '#title' => t('Import data'),
+    '#type' => 'textarea',
+    '#value' => "",
+    '#rows' => 20,
+    '#description' => t('Paste the code from queue export function.'),
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit'),
+  );
+  return $form;
+}
+
+function nodequeue_import_form_submit($form, &$form_state) {
+  ctools_include('export');
+  $import = $form_state['input']['import'];
+  $queue = ctools_export_crud_import('nodequeue_queue', $import);
+
+  if (is_object($queue)) {
+    // Change boolean values to integer, to avoid SQL errors.
+    foreach (array('show_in_ui', 'show_in_tab', 'show_in_links', 'reverse', 'i18n') as $field) {
+      $queue->$field = (int) $queue->$field;
+    }
+    if (!empty($queue->subqueues)) {
+      // Need to copy values from 'subqueues' property to 'add_subqueue' as it's
+      // how it's handled by nodequeue_save() at this moment.
+      $queue->add_subqueue = $queue->subqueues;
+    }
+    nodequeue_save($queue);
+    $form_state['redirect'] = 'admin/structure/nodequeue';
+  }
+  else {
+    form_set_error('import', $queue);
+  }
+}
diff --git a/includes/views/nodequeue.views_default.inc b/includes/views/nodequeue.views_default.inc
index be21cc3..87b281b 100644
--- a/includes/views/nodequeue.views_default.inc
+++ b/includes/views/nodequeue.views_default.inc
@@ -12,7 +12,7 @@ function nodequeue_views_default_views() {
     return $views;
   }
 
-  $queues = nodequeue_load_queues(nodequeue_get_all_queues());
+  $queues = nodequeue_load_multiple(nodequeue_get_all_queues());
   foreach ($queues as $queue) {
     $view = new view;
     $view->name = "nodequeue_$queue->name";
diff --git a/includes/views/nodequeue_handler_field_all_queues.inc b/includes/views/nodequeue_handler_field_all_queues.inc
index 090e879..61bae1f 100644
--- a/includes/views/nodequeue_handler_field_all_queues.inc
+++ b/includes/views/nodequeue_handler_field_all_queues.inc
@@ -38,7 +38,7 @@ class nodequeue_handler_field_all_queues extends views_handler_field_prerender_l
     );
 
     $options = array();
-    $queues = nodequeue_load_queues(nodequeue_get_all_queues());
+    $queues = nodequeue_load_multiple(nodequeue_get_all_queues());
     foreach ($queues as $queue) {
       $options[$queue->name] = $queue->title;
     }
diff --git a/includes/views/nodequeue_handler_relationship_nodequeue.inc b/includes/views/nodequeue_handler_relationship_nodequeue.inc
index a066747..58a44d7 100644
--- a/includes/views/nodequeue_handler_relationship_nodequeue.inc
+++ b/includes/views/nodequeue_handler_relationship_nodequeue.inc
@@ -35,7 +35,7 @@ class nodequeue_handler_relationship_nodequeue extends views_handler_relationshi
     );
 
     $options = array();
-    $queues = nodequeue_load_queues(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
+    $queues = nodequeue_load_multiple(nodequeue_get_all_queues(0, 0, TRUE), TRUE);
     foreach ($queues as $queue) {
       $options[$queue->name] = $queue->title;
     }
diff --git a/nodequeue.info b/nodequeue.info
index 16da04c..c27f273 100644
--- a/nodequeue.info
+++ b/nodequeue.info
@@ -4,6 +4,9 @@ package = Nodequeue
 core = 7.x
 configure = admin/structure/nodequeue/settings
 
+; Dependencies
+dependencies[] = ctools
+
 ; Includes
 files[] = includes/views/nodequeue.views.inc
 files[] = includes/nodequeue.actions.inc
diff --git a/nodequeue.install b/nodequeue.install
index 1c22186..4fa5c09 100644
--- a/nodequeue.install
+++ b/nodequeue.install
@@ -11,6 +11,19 @@
 function nodequeue_schema() {
   $schema['nodequeue_queue'] = array(
     'description' => 'Base table for queues, storing global information for each queue',
+    'export' => array(
+      'key' => 'name',
+      'identifier' => 'queue',
+      'default hook' => 'nodequeue_default_queues',
+      'api' => array(
+        'owner' => 'nodequeue',
+        'api' => 'nodequeue_default',
+        'minimum_version' => 3,
+        'current_version' => 3,
+      ),
+      // the callback to load the subqueues, roles and node types.
+      'subrecords callback' => 'nodequeue_process_queues',
+    ),
     'fields' => array(
       'name' => array(
         'description' => 'The machine name for the queue.',
diff --git a/nodequeue.module b/nodequeue.module
index 4f7c020..ca8ff9c 100644
--- a/nodequeue.module
+++ b/nodequeue.module
@@ -84,6 +84,14 @@ function nodequeue_menu() {
     'file' => 'includes/nodequeue.admin.inc',
     'type' => MENU_LOCAL_TASK
   );
+  $items['admin/structure/nodequeue/import'] = array(
+    'title' => 'Import',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('nodequeue_import_form'),
+    'access arguments' => $admin_access,
+    'file' => 'includes/nodequeue.admin.inc',
+    'type' => MENU_LOCAL_ACTION
+  );
   $items['nodequeue/autocomplete'] = array(
     'title' => 'Autocomplete',
     'page callback' => 'nodequeue_autocomplete',
@@ -163,6 +171,14 @@ function nodequeue_menu() {
     'weight' => 5,
     'type' => MENU_CALLBACK
   );
+  $items['admin/structure/nodequeue/%nodequeue/export'] = array(
+    'title' => 'Export',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('nodequeue_export_queue_form', 3),
+    'access arguments' => $admin_access,
+    'file' => 'includes/nodequeue.admin.inc',
+    'type' => MENU_LOCAL_TASK
+  );
   $items['nodequeue/%nodequeue/add-node/%subqueue/%node'] = array(
     'page callback' => 'nodequeue_admin_add_node',
     'page arguments' => array(1, 3, 4),
@@ -223,7 +239,7 @@ function nodequeue_node_delete($node) {
     // If the queue is being tracked by translation set and the node is part
     // of a translation set, don't delete the queue record.
     // Instead, data will be updated in the 'translation_change' op, below.
-    $queues = nodequeue_load_queues(array($obj->name));
+    $queues = nodequeue_load_multiple(array($obj->name));
     $queue = array_shift($queues);
     if (!$queue->i18n || (isset($node->tnid) && empty($node->tnid))) {
       // This removes by nid, not position, because if we happen to have a
@@ -336,6 +352,17 @@ function nodequeue_views_api() {
   );
 }
 
+/**
+ * Implements hook_ctools_plugin_api().
+ *
+ * Tell CTools that we support the nodequeue_default API.
+ */
+function nodequeue_ctools_plugin_api($owner, $api) {
+  if ($owner == 'nodequeue' && $api == 'nodequeue_default') {
+    return array('version' => 3);
+  }
+}
+
 // --------------------------------------------------------------------------
 // Nodequeue Apache Solr Search Integration
 
@@ -380,7 +407,7 @@ function nodequeue_apachesolr_update_index(&$document, $node) {
     return;
   }
 
-  $queues = nodequeue_load_queues(array_keys(nodequeue_get_all_queues()));
+  $queues = nodequeue_load_multiple(array_keys(nodequeue_get_all_queues()));
   $subqueues = nodequeue_get_subqueues_by_node($queues, $node);
 
   nodequeue_set_subqueue_positions($subqueues, $node->nid);
@@ -478,7 +505,7 @@ function nodequeue_load_queues_by_type($type, $location = NULL, $account = NULL,
   if ($location) {
     nodequeue_filter_queues($queues, $location);
   }
-  return nodequeue_load_queues(array_keys($queues), $bypass_cache);
+  return nodequeue_load_multiple(array_keys($queues), $bypass_cache);
 }
 
 /**
@@ -587,80 +614,93 @@ function nodequeue_get_all_queues($page_size = 0, $pager_element = 0, $bypass_ca
 }
 
 /**
- * Load an array of $queues.
+ * Load multiple queues.
  *
- * This exists to provide a way of loading a bunch of queues with
- * the fewest queries. Loading 5 queues results in only 4 queries,
- * not 20. This also caches queues so that they don't get loaded
- * repeatedly.
- *
- * @param $queue_names
+ * @param $names
  *   An array of queue names to load.
- *
- * @param $bypass_cache
- *   Boolean value indicating whether to bypass the cache or not.
+ * @param $reset
+ *   Boolean value indicating whether to reset the cache or not.
  */
-function nodequeue_load_queues($queue_names = array(), $bypass_cache = FALSE) {
-  static $cache = array();
-  $to_load = $loaded = array();
-
-  foreach ($queue_names as $name) {
-    if ($bypass_cache || !isset($cache[$name])) {
-      $to_load[] = $name;
-    }
+function nodequeue_load_multiple($names, $reset = FALSE) {
+  // Sometimes we can expect $names to be an empty array.
+  if (empty($names)) {
+    return array();
   }
 
-  if (!empty($to_load)) {
-    $result = db_query("SELECT q.*, COUNT(s.sqid) AS subqueues FROM {nodequeue_queue} q LEFT JOIN {nodequeue_subqueue} s ON q.name = s.name WHERE q.name IN (:to_load) GROUP BY q.name", array(':to_load' => $to_load));
+  ctools_include('export');
 
-    foreach ($result as $queue) {
-      $loaded[$queue->name] = $queue;
-      // ensure valid defaults:
-      $loaded[$queue->name]->types = array();
-      $loaded[$queue->name]->roles = array();
-      $loaded[$queue->name]->count = 0;
-    }
+  if ($reset) {
+    // Clear static cache and make it load from the database again.
+    drupal_static_reset('ctools_export_load_object');
+    drupal_static_reset('ctools_export_load_object_all');
+  }
 
-    $result = db_query("SELECT name, rid FROM {nodequeue_roles} WHERE name IN (:to_load)", array(':to_load' => $to_load));
-    foreach ($result as $obj) {
-      $loaded[$obj->name]->roles[] = $obj->rid;
-    }
+  $queues = ctools_export_load_object('nodequeue_queue', 'names', $names);
 
-    $result = db_query("SELECT name, type FROM {nodequeue_types} WHERE name IN (:to_load)", array(':to_load' => $to_load));
-    foreach ($result as $obj) {
-      $loaded[$obj->name]->types[] = $obj->type;
-    }
+  $context = 'load_queues';
+  drupal_alter('nodequeue', $queues, $context);
 
-    $context = 'load_queues';
-    drupal_alter('nodequeue', $loaded, $context);
-  }
+  return array_filter($queues);
+}
 
-  if ($bypass_cache) {
-    return $loaded;
-  }
-  else {
-    if (!empty($loaded)) {
-      $cache += $loaded;
-    }
-    $queues = array();
-    foreach ($queue_names as $name) {
-      if (isset($cache[$name])) {
-        $queues[$name] = $cache[$name];
-      }
-    }
-    return $queues;
+/**
+ * Process a list of queues, adding all related data.
+ *
+ * @param $queues
+ *   An array of queuess to process.
+ */
+function nodequeue_process_queues(&$queues) {
+  foreach ($queues as &$queue) {
+    nodequeue_process_queue($queue);
   }
 }
 
 /**
+ * Add all data related to a single queue.
+ *
+ * @param $queue
+ *   A pre-loaded queue object.
+ */
+function nodequeue_process_queue(&$queue) {
+  $queue->roles = db_select('nodequeue_roles', 'nr')
+    ->fields('nr', array('rid'))
+    ->condition('nr.name', $queue->name)
+    ->execute()
+    ->fetchAll(PDO::FETCH_COLUMN);
+
+  $queue->types = db_select('nodequeue_types', 'nt')
+    ->fields('nt', array('type'))
+    ->condition('nt.name', $queue->name)
+    ->execute()
+    ->fetchAll(PDO::FETCH_COLUMN);
+
+  $queue->subqueues = db_select('nodequeue_subqueue', 'ns')
+    ->fields('ns', array('reference', 'title'))
+    ->condition('ns.name', $queue->name)
+    ->execute()
+    ->fetchAllKeyed();
+
+  // Reset queue counter.
+  $queue->count = 0;
+
+  return $queue;
+}
+
+/**
  * Load a nodequeue.
  *
  * @param $name
  *   The name of the queue to load.
+ * @return
+ *   An object representing a specific queue.
  */
 function nodequeue_load($name) {
-  $queues = nodequeue_load_queues(array($name));
-  return !empty($queues) ? array_shift($queues) : array();
+  // Use CTools export API to fetch this queue.
+  ctools_include('export');
+  $result = ctools_export_load_object('nodequeue_queue', 'names', array($name));
+  if (isset($result[$name])) {
+    return $result[$name];
+  }
 }
 
 /**
@@ -727,7 +767,6 @@ function nodequeue_load_subqueue($sqid, $bypass_cache = FALSE) {
   if ($subqueues) {
     return array_shift($subqueues);
   }
-
 }
 
 /**
diff --git a/nodequeue_generate.module b/nodequeue_generate.module
index 1e087be..f74d0b8 100644
--- a/nodequeue_generate.module
+++ b/nodequeue_generate.module
@@ -24,7 +24,7 @@ function nodequeue_generate_form() {
     '#markup' => '<p>' . t('Select which queues shall be <strong>emptied</strong> and re-populated with new nodes.') . '</p>'
   );
 
-  $queues = nodequeue_load_queues(nodequeue_get_all_queues(25));
+  $queues = nodequeue_load_multiple(nodequeue_get_all_queues(25));
 
   // Tableselect header.
   $header = array(
@@ -96,7 +96,7 @@ function nodequeue_generate_repopulate_queues($queues, $nodes_limit = 10) {
   db_query("DELETE FROM {nodequeue_nodes} WHERE name IN (:queues)", array(':queues' => $queues));
 
   // Load all queues and their subqueues.
-  $queues = nodequeue_load_queues($queues);
+  $queues = nodequeue_load_multiple($queues);
   $subqueues = nodequeue_load_subqueues_by_queue($queues);
 
   // Re-populate subqueues
