diff --git a/cron_example/cron_example.info b/cron_example/cron_example.info
new file mode 100644
index 0000000..7470066
--- /dev/null
+++ b/cron_example/cron_example.info
@@ -0,0 +1,5 @@
+name = Cron example
+description = Demonstrates hook_cron() and related features
+package = Example modules
+core = 7.x
+;files[] = cron_example.test
diff --git a/cron_example/cron_example.module b/cron_example/cron_example.module
new file mode 100644
index 0000000..4ec7056
--- /dev/null
+++ b/cron_example/cron_example.module
@@ -0,0 +1,218 @@
+<?php
+
+/**
+ * @file
+ * Demonstrates use of the Cron API in Drupal - hook_cron()
+ */
+
+/**
+ * @ingroup examples
+ *
+ * Example using Cron API, including hook_cron() and hook_cron_queue_info().
+ *
+ * This example is part of the Examples for Developers Project
+ * which you can download and experiment with at
+ * http://drupal.org/project/examples
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function cron_example_menu() {
+
+  $items['examples/cron_example'] = array(
+    'title' => 'Cron Example',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('cron_example_form'),
+    'access callback' => TRUE,
+  );
+
+  return $items;
+}
+
+/**
+ * The form to provide a link to cron.php.
+ */
+function cron_example_form($form, &$form_state) {
+  $form['intro'] = array(
+    '#markup' => '<div>' . t('The cron example demonstrates hook_cron() and hook_cron_queue_info() processing. If you have administrative privileges you can run cron from this page and see the results.') . '</div>',
+  );
+  $form['last'] = array(
+    '#markup' => '<div>' . t('cron_example_cron() will next execute the first time cron runs after %time (%seconds seconds from now)' . '</div>',
+      array(
+        '%time' => date_iso8601(variable_get('cron_example_next_execution', time())),
+        '%seconds' => variable_get('cron_example_next_execution', time()) - time(),
+      )
+    ),
+  );
+  if (user_access('administer site configuration')) {
+    $form['cron_run'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Run cron manually'),
+    );
+    $form['cron_run']['cron_reset'] = array(
+      '#type' => 'checkbox',
+      '#title' => t("Run cron_example's cron regardless of whether interval has expired."),
+      '#default_value' => FALSE,
+    );
+    $form['cron_run']['cron_trigger'] = array(
+      '#type' => 'submit',
+      '#value' => t('Run cron now'),
+      '#submit' => array('cron_example_form_cron_run_submit'),
+    );
+  }
+
+  $form['cron_queue_setup'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Cron queue setup (for hook_cron_queue_info(), etc.)'),
+  );
+  $queue_1 = DrupalQueue::get('cron_example_queue_1');
+  $queue_2 = DrupalQueue::get('cron_example_queue_2');
+  $form['cron_queue_setup']['current_cron_queue_status'] = array(
+    '#markup' => '<div>' . t('There are currently %queue_1 items in queue 1 and %queue_2 items in queue 2',
+      array(
+        '%queue_1' => $queue_1->numberOfItems(),
+        '%queue_2' => $queue_2->numberOfItems(),
+      )) . '</div>',
+  );
+  $form['cron_queue_setup']['num_items'] = array(
+    '#type' => 'select',
+    '#title' => t('Number of items to add to queue'),
+    '#options' => drupal_map_assoc(array(1,5,10,100,1000)),
+    '#default_value' => 5,
+  );
+  $form['cron_queue_setup']['queue'] = array(
+    '#type' => 'radios',
+    '#title' => t('Queue to add items to'),
+    '#options' => array(
+      'cron_example_queue_1' => t('Queue 1'),
+      'cron_example_queue_2' => t('Queue 2'),
+    ),
+    '#default_value' => 'cron_example_queue_1',
+  );
+  $form['cron_queue_setup']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Add jobs to queue'),
+    '#submit' => array('cron_example_add_jobs_to_queue'),
+  );
+
+  $form['configuration'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Configuration of cron_example_cron()'),
+  );
+  $form['configuration']['cron_example_interval'] = array(
+    '#type' => 'select',
+    '#title' => t('Cron interval'),
+    '#description' => t('Time after which cron_example_cron will respond to a processing request.'),
+    '#default_value' => variable_get('cron_example_interval', 60*60),
+    '#options' => array(
+      60 => t('1 minute'),
+      300 => t('5 minutes'),
+      3600 => t('1 hour'),
+      60*60*24 => t('1 day'),
+    ),
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Allow user to directly execute cron, optionally forcing it.
+ */
+function cron_example_form_cron_run_submit($form, &$form_state) {
+  if (!empty($form_state['values']['cron_reset'])) {
+    variable_set('cron_example_next_execution', 0);
+  }
+
+  // We don't usually use globals in this way. This is used here only to
+  // make it easy to tell if cron was run by this form.
+  $GLOBALS['cron_example_show_status_message'] = TRUE;
+  if (drupal_cron_run()) {
+    drupal_set_message(t('Cron ran successfully.'));
+  }
+  else {
+    drupal_set_message(t('Cron run failed.'), 'error');
+  }
+}
+
+function cron_example_add_jobs_to_queue($form, &$form_state) {
+  $queue = $form_state['values']['queue'];
+  $num_items = $form_state['values']['num_items'];
+
+  $queue = DrupalQueue::get($queue);
+  for ($i=1; $i <= $num_items; $i++) {
+    $item = new stdClass();
+    $item->created = time();
+    $item->sequence = $i;
+    $queue->createItem($item);
+  }
+}
+/**
+ * Implements hook_cron()
+ *
+ * hook_cron() is the traditional hook for doing "background" processing.
+ * It gets called every time the Drupal cron runs.
+ */
+function cron_example_cron() {
+  // Default to an hourly interval. Of course, cron has to be running at least
+  // hourly for this to work.
+  $interval = variable_get('cron_example_interval', 60*60);
+  // We usually don't want to act every time cron runs (which could be every
+  // minute) so keep a time for the next run in a variable.
+
+  if (time() >= variable_get('cron_example_next_execution', 0)) {
+    // This is a silly example of a cron job.
+    // It just makes it obvious that the job has run without
+    // making any changes to your database.
+    watchdog('cron_example', 'cron_example ran');
+    if (!empty($GLOBALS['cron_example_show_status_message'])) {
+      drupal_set_message(t('cron_example executed at %time', array('%time' => date_iso8601(time(0)))));
+    }
+    variable_set('cron_example_next_execution', time() + $interval);
+  }
+}
+
+
+/**
+ * Implementation of hook_cron_queue_info().
+ *
+ * hook_cron_queue_info() and family are new since Drupal 7, and allow any
+ * process to add work to the queue to be acted on when cron runs. Queues are
+ * described and worker callbacks are provided, and then only the worker
+ * callback needs to be implemented.
+ *
+ * All the details of queue use are done by the cron_queue implementation, so
+ * one doesn't need to know much about DrupalQueue().
+ *
+ * @see queue_example.module
+ */
+function cron_example_cron_queue_info() {
+  $queues['cron_example_queue_1'] = array(
+    'worker callback' => 'cron_example_queue_1_worker', // This is the callback function for each queue item.
+    'time' => 180, // This is the max run time per cron run in seconds.
+  );
+  $queues['cron_example_queue_2'] = array(
+    'worker callback' => 'cron_example_queue_2_worker', // This is the callback function for each queue item.
+    'time' => 180, // This is the max run time per cron run in seconds.
+  );
+  return $queues;
+}
+
+/**
+ * Simple workers for the two queues.
+ * @param $item
+ *   Any object to be worked on.
+ */
+function cron_example_queue_1_worker($item) {
+  if (!empty($GLOBALS['cron_example_show_status_message'])) {
+    drupal_set_message(t('Queue 1 worker processed item %item', array('%item' => print_r($item, TRUE))));
+  }
+  watchdog('cron_example', 'Queue 1 worker processed item %item', array('%item' => print_r($item, TRUE)));
+}
+
+function cron_example_queue_2_worker($item) {
+  if (!empty($GLOBALS['cron_example_show_status_message'])) {
+    drupal_set_message(t('Queue 2 worker processed item %item', array('%item' => print_r($item, TRUE))));
+  }
+  watchdog('cron_example', 'Queue 2 worker processed item %item', array('%item' => print_r($item, TRUE)));
+}
diff --git a/examples.index.php b/examples.index.php
index dfedaea..40450ee 100644
--- a/examples.index.php
+++ b/examples.index.php
@@ -9,6 +9,7 @@
  * - @link batch_example.module Using the batch API @endlink
  * - @link block_example.module Defining blocks @endlink
  * - @link contextual_links_example.module Defining contextual links @endlink
+ * - @link cron_example.module Using hook_cron() and hook_cron_queue_info() @endlink
  * - @link dbtng_example.module Database examples (DBTNG) @endlink
  * - @link email_example.module Sending e-mail @endlink
  * - @link field_example.module Defining fields in the field API @endlink
