diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc
index 4f3d350..a55ddc5 100644
--- a/core/modules/comment/comment.admin.inc
+++ b/core/modules/comment/comment.admin.inc
@@ -161,7 +161,10 @@ function comment_admin_overview_submit($form, &$form_state) {
   $cids = $form_state['values']['comments'];
 
   if ($operation == 'delete') {
-    comment_delete_multiple($cids);
+    $deleted = comment_delete_multiple($cids);
+    if ($deleted != count($cids)) {
+      drupal_set_message(format_plural(count($cids) - $deleted, 'Removal of 1 comment was enqueued to be run in background. Run cron to finish removal.', 'Removal of @count comments was enqueued to be run in background. Run cron to finish removal.'), 'warning');
+    }
   }
   else {
     foreach ($cids as $cid => $value) {
@@ -228,11 +231,16 @@ function comment_multiple_delete_confirm($form, &$form_state) {
  */
 function comment_multiple_delete_confirm_submit($form, &$form_state) {
   if ($form_state['values']['confirm']) {
-    comment_delete_multiple(array_keys($form_state['values']['comments']));
+    $deleted = comment_delete_multiple(array_keys($form_state['values']['comments']));
     cache_clear_all();
     $count = count($form_state['values']['comments']);
-    watchdog('content', 'Deleted @count comments.', array('@count' => $count));
-    drupal_set_message(format_plural($count, 'Deleted 1 comment.', 'Deleted @count comments.'));
+    watchdog('content', 'Deleted @count comments.', array('@count' => $deleted));
+    drupal_set_message(format_plural($deleted, 'Deleted 1 comment.', 'Deleted @count comments.'));
+
+    // In case the jobs get enqueued, we warn user.
+    if ($count != $deleted) {
+      drupal_set_message(format_plural($count - $deleted, 'Removal of 1 comment was enqueued to be run in background. Run cron to finish removal.', 'Removal of @count comments was enqueued to be run in background. Run cron to finish removal.'), 'warning');
+    }
   }
   $form_state['redirect'] = 'admin/content/comment';
 }
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index ae9278c..15ebd7b 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1598,8 +1598,14 @@ function comment_delete($cid) {
  *
  * @param $cids
  *   The comment to delete.
+ *
+ * @return
+ *   The number of deleted comments.
  */
 function comment_delete_multiple($cids) {
+  // Enqueue larger operations.
+  $cids = system_workers_bulk_split(__FUNCTION__, $cids);
+
   $comments = comment_load_multiple($cids);
   if ($comments) {
     $transaction = db_transaction();
@@ -1624,7 +1630,9 @@ function comment_delete_multiple($cids) {
       watchdog_exception('comment', $e);
       throw $e;
     }
+    return count($cids);
   }
+  return 0;
 }
 
 /**
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index 8f46df4..1a9e50f 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -587,10 +587,15 @@ function node_multiple_delete_confirm($form, &$form_state, $nodes) {
 
 function node_multiple_delete_confirm_submit($form, &$form_state) {
   if ($form_state['values']['confirm']) {
-    node_delete_multiple(array_keys($form_state['values']['nodes']));
+    $deleted = node_delete_multiple(array_keys($form_state['values']['nodes']));
     $count = count($form_state['values']['nodes']);
-    watchdog('content', 'Deleted @count posts.', array('@count' => $count));
-    drupal_set_message(format_plural($count, 'Deleted 1 post.', 'Deleted @count posts.'));
+    watchdog('content', 'Deleted @count posts.', array('@count' => $deleted));
+    drupal_set_message(format_plural($deleted, 'Deleted 1 post.', 'Deleted @count posts.'));
+
+    // In case the jobs get enqueued, we warn user.
+    if ($count != $deleted) {
+      drupal_set_message(format_plural($count - $deleted, 'Removal of 1 post was enqueued to be run in background. Run cron to finish removal.', 'Removal of @count posts was enqueued to be run in background. Run cron to finish removal.'), 'warning');
+    }
   }
   $form_state['redirect'] = 'admin/content';
 }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 0c3cfb7..e83e7d9 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1189,10 +1189,16 @@ function node_delete($nid) {
  *
  * @param $nids
  *   An array of node IDs.
+ *
+ * @return
+ *   The number of deleted nodes.
  */
 function node_delete_multiple($nids) {
   $transaction = db_transaction();
   if (!empty($nids)) {
+    // Enqueue larger operations.
+    $nids = system_workers_bulk_split(__FUNCTION__, $nids);
+
     $nodes = node_load_multiple($nids, array());
 
     try {
@@ -1234,7 +1240,11 @@ function node_delete_multiple($nids) {
 
     // Clear the page and block and node_load_multiple caches.
     entity_get_controller('node')->resetCache();
+
+    // Return the number of nodes deleted
+    return count($nids);
   }
+  return 0;
 }
 
 /**
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index e2e16ae..b38acad 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3031,6 +3031,50 @@ function system_cron() {
 }
 
 /**
+ * Implements hook_cron_queue_info().
+ */
+function system_cron_queue_info() {
+  $queues['system_workers'] = array(
+    'worker callback' => 'system_queue_worker',
+    'time' => 15,
+    'reliable' => TRUE,
+  );
+  return $queues;
+}
+
+/**
+ * Simple job queue worker.
+ */
+function system_queue_worker($data) {
+  return call_user_func_array($data['callback'], $data['arguments']);
+}
+
+/**
+ * Helper function. Conditionally splits big sets of data into chunks before
+ * processing them. In case they are bigger than the allowed threshold -
+ * variable 'queue_bulk_threshold', we add the remaining to the queue and
+ * return just the first set.
+ *
+ * @param $callback - The callback for the job being added
+ * @param $items - An array of items to be processed
+ *
+ * @return chunk with items to be processed, not bigger than the threshold
+ */
+function system_workers_bulk_split($callback, $items) {
+  $threshold = variable_get('queue_bulk_threshold', 20);
+
+  if (count($items) > $threshold) {
+    $jobs = array_chunk($items, $threshold);
+    $items = array_shift($jobs);
+    foreach ($jobs as $job) {
+      DrupalQueue::addJob($callback, array($job));
+    }
+  }
+
+  return $items;
+}
+
+/**
  * Implements hook_flush_caches().
  */
 function system_flush_caches() {
diff --git a/core/modules/system/system.queue.inc b/core/modules/system/system.queue.inc
index 00d3940..e6c85c7 100644
--- a/core/modules/system/system.queue.inc
+++ b/core/modules/system/system.queue.inc
@@ -94,6 +94,18 @@ class DrupalQueue {
     }
     return $queues[$name];
   }
+
+  /**
+   * Add a simple job to the queue.
+   *
+   * @param $callback
+   *   The name of the function to be called when the queue is processed next.
+   * @param $arguments
+   *   The arguments to the callback.
+   */
+  public static function addJob($callback, $arguments = array()) {
+    return DrupalQueue::get('system_workers', TRUE)->createItem(array('callback' => $callback, 'arguments' => $arguments));
+  }
 }
 
 interface DrupalQueueInterface {
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 2b5952d..512c98d 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -2414,9 +2414,15 @@ function user_delete($uid) {
  *
  * @param $uids
  *   An array of user IDs.
+ *
+ * @return
+ *   The number of deleted users.
  */
 function user_delete_multiple(array $uids) {
   if (!empty($uids)) {
+    // Enqueue larger operations.
+    $uids = system_workers_bulk_split(__FUNCTION__, $uids);
+
     $accounts = user_load_multiple($uids, array());
 
     $transaction = db_transaction();
@@ -2444,7 +2450,9 @@ function user_delete_multiple(array $uids) {
       throw $e;
     }
     entity_get_controller('user')->resetCache();
+    return count($uids);
   }
+  return 0;
 }
 
 /**
