diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index c26ec86..658fda0 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -1756,7 +1756,7 @@ function drupal_is_denied($ip) {
   // database and also in this case it's quite likely that the user relies
   // on higher performance solutions like a firewall.
   elseif (class_exists('Database', FALSE)) {
-    $denied = (bool)db_query("SELECT 1 FROM {blocked_ips} WHERE ip = :ip", array(':ip' => $ip))->fetchField();
+    $denied = blocked_ip_load($ip) !== FALSE;
   }
   return $denied;
 }
diff --git a/core/modules/statistics/statistics.admin.inc b/core/modules/statistics/statistics.admin.inc
index 6606b8b..1fc7214 100644
--- a/core/modules/statistics/statistics.admin.inc
+++ b/core/modules/statistics/statistics.admin.inc
@@ -100,8 +100,10 @@ function statistics_top_visitors() {
     array('data' => t('Total page generation time'), 'field' => 'total'),
     array('data' => user_access('block IP addresses') ? t('Operations') : '', 'colspan' => 2),
   );
+
+  $blocked_ips = config('system.blocked_ips')->get('blocked_ips');
+  $blocked_ips = is_array($blocked_ips) ? $blocked_ips : array();
   $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
-  $query->leftJoin('blocked_ips', 'bl', 'a.hostname = bl.ip');
   $query->leftJoin('users', 'u', 'a.uid = u.uid');
 
   $query->addExpression('COUNT(a.uid)', 'hits');
@@ -109,11 +111,9 @@ function statistics_top_visitors() {
   $query
     ->fields('a', array('uid', 'hostname'))
     ->fields('u', array('name'))
-    ->fields('bl', array('iid'))
     ->groupBy('a.hostname')
     ->groupBy('a.uid')
     ->groupBy('u.name')
-    ->groupBy('bl.iid')
     ->limit(30)
     ->orderByHeader($header);
 
@@ -127,7 +127,12 @@ function statistics_top_visitors() {
   $rows = array();
   $destination = drupal_get_destination();
   foreach ($result as $account) {
-    $ban_link = $account->iid ? l(t('unblock IP address'), "admin/config/people/ip-blocking/delete/$account->iid", array('query' => $destination)) : l(t('block IP address'), "admin/config/people/ip-blocking/$account->hostname", array('query' => $destination));
+    if (in_array($account->hostname, $blocked_ips)) {
+      $ban_link = l(t('unblock IP address'), "admin/config/people/ip-blocking/delete/$account->hostname", array('query' => $destination));
+    }
+    else {
+      $ban_link = l(t('block IP address'), "admin/config/people/ip-blocking/$account->hostname", array('query' => $destination));
+    }
     $rows[] = array($account->hits, ($account->uid ? theme('username', array('account' => $account)) : $account->hostname), format_interval(round($account->total / 1000)), (user_access('block IP addresses') && !$account->uid) ? $ban_link : '');
   }
 
diff --git a/core/modules/statistics/statistics.test b/core/modules/statistics/statistics.test
index 62cec24..2d75e8a 100644
--- a/core/modules/statistics/statistics.test
+++ b/core/modules/statistics/statistics.test
@@ -275,7 +275,8 @@ class StatisticsBlockVisitorsTestCase extends StatisticsTestCase {
     $edit = array();
     $edit['ip'] = $test_ip_address;
     $this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
-    $ip = db_query("SELECT iid from {blocked_ips} WHERE ip = :ip", array(':ip' => $edit['ip']))->fetchField();
+
+    $ip = blocked_ip_load($edit['ip']);
     $this->assertNotEqual($ip, FALSE, t('IP address found in database'));
     $this->assertRaw(t('The IP address %ip has been blocked.', array('%ip' => $edit['ip'])), t('IP address was blocked.'));
 
@@ -287,8 +288,7 @@ class StatisticsBlockVisitorsTestCase extends StatisticsTestCase {
     // Unblock the IP address.
     $this->clickLink('unblock IP address');
     $this->assertRaw(t('Are you sure you want to delete %ip?', array('%ip' => $test_ip_address)), t('IP address deletion confirmation found.'));
-    $edit = array();
-    $this->drupalPost('admin/config/people/ip-blocking/delete/1', NULL, t('Delete'));
+    $this->drupalPost('admin/config/people/ip-blocking/delete/' . $test_ip_address, NULL, t('Delete'));
     $this->assertRaw(t('The IP address %ip was deleted.', array('%ip' => $test_ip_address)), t('IP address deleted.'));
   }
 }
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 978b0f4..e98508b 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -1359,12 +1359,15 @@ function system_modules_uninstall_submit($form, &$form_state) {
 function system_ip_blocking($default_ip = '') {
   $rows = array();
   $header = array(t('Blocked IP addresses'), t('Operations'));
-  $result = db_query('SELECT * FROM {blocked_ips}');
-  foreach ($result as $ip) {
-    $rows[] = array(
-      $ip->ip,
-      l(t('delete'), "admin/config/people/ip-blocking/delete/$ip->iid"),
-    );
+  $blocked_ips = config('system.blocked_ips')->get('blocked_ips');
+  if (is_array($blocked_ips)) {
+    foreach ($blocked_ips as $ip) {
+      $rows[] = array(
+        $ip,
+        // Use a substring of the key - it is prefixed with 'ip_'.
+        l(t('delete'), 'admin/config/people/ip-blocking/delete/' . $ip),
+      );
+    }
   }
 
   $build['system_ip_blocking_form'] = drupal_get_form('system_ip_blocking_form', $default_ip);
@@ -1407,7 +1410,8 @@ function system_ip_blocking_form($form, $form_state, $default_ip) {
 
 function system_ip_blocking_form_validate($form, &$form_state) {
   $ip = trim($form_state['values']['ip']);
-  if (db_query("SELECT * FROM {blocked_ips} WHERE ip = :ip", array(':ip' => $ip))->fetchField()) {
+  $loaded_ip = blocked_ip_load($ip);
+  if ($loaded_ip !== FALSE) {
     form_set_error('ip', t('This IP address is already blocked.'));
   }
   elseif ($ip == ip_address()) {
@@ -1420,9 +1424,9 @@ function system_ip_blocking_form_validate($form, &$form_state) {
 
 function system_ip_blocking_form_submit($form, &$form_state) {
   $ip = trim($form_state['values']['ip']);
-  db_insert('blocked_ips')
-    ->fields(array('ip' => $ip))
-    ->execute();
+  $config = config('system.blocked_ips');
+  $config->set('blocked_ips.ip_' . system_convert_config_ip_address($ip), $ip);
+  $config->save();
   drupal_set_message(t('The IP address %ip has been blocked.', array('%ip' => $ip)));
   $form_state['redirect'] = 'admin/config/people/ip-blocking';
   return;
@@ -1433,24 +1437,24 @@ function system_ip_blocking_form_submit($form, &$form_state) {
  *
  * @see system_ip_blocking_delete_submit()
  */
-function system_ip_blocking_delete($form, &$form_state, $iid) {
+function system_ip_blocking_delete($form, &$form_state, $ip) {
   $form['blocked_ip'] = array(
     '#type' => 'value',
-    '#value' => $iid,
+    '#value' => $ip,
   );
-  return confirm_form($form, t('Are you sure you want to delete %ip?', array('%ip' => $iid['ip'])), 'admin/config/people/ip-blocking', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
+  return confirm_form($form, t('Are you sure you want to delete %ip?', array('%ip' => $ip)), 'admin/config/people/ip-blocking', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
 }
 
 /**
  * Process system_ip_blocking_delete form submissions.
  */
 function system_ip_blocking_delete_submit($form, &$form_state) {
-  $blocked_ip = $form_state['values']['blocked_ip'];
-  db_delete('blocked_ips')
-    ->condition('iid', $blocked_ip['iid'])
-    ->execute();
-  watchdog('user', 'Deleted %ip', array('%ip' => $blocked_ip['ip']));
-  drupal_set_message(t('The IP address %ip was deleted.', array('%ip' => $blocked_ip['ip'])));
+  $ip = blocked_ip_load($form_state['values']['blocked_ip']);
+  $config = config('system.blocked_ips');
+  $config->clear('blocked_ips.ip_' . system_convert_config_ip_address($form_state['values']['blocked_ip']));
+  $config->save();
+  watchdog('user', 'Deleted %ip', array('%ip' => $ip));
+  drupal_set_message(t('The IP address %ip was deleted.', array('%ip' => $ip)));
   $form_state['redirect'] = 'admin/config/people/ip-blocking';
 }
 
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 905d11d..b6a3e84 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1762,6 +1762,21 @@ function system_update_8005() {
 }
 
 /**
+ * Migrates the entries from blocked_ips into a configuration file.
+ */
+function system_update_8006() {
+  $results = db_query("SELECT ip FROM {blocked_ips}")->fetchAll();
+  if (!empty($results)) {
+    $config = config('system.blocked_ips');
+    foreach ($results as $row) {
+      $config->set('blocked_ips.ip_' . system_convert_config_ip_address($row->ip), $row->ip);
+    }
+    $config->save();
+  }
+  db_drop_table('blocked_ips');
+}
+
+/**
  * @} End of "defgroup updates-7.x-to-8.x"
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index fd571ce..706185e 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1705,16 +1705,27 @@ function system_stream_wrappers() {
 }
 
 /**
- * Retrieve a blocked IP address from the database.
+ * Retrieves a blocked IP address.
  *
- * @param $iid integer
- *   The ID of the blocked IP address to retrieve.
+ * An IP address is stored in the configuration file with its value prefixed
+ * with 'ip_' as key, and '.' replaced with '_'. The prefix is necessary
+ * because XML tags cannot start with numbers, and '.' is not a valid character
+ * in XML tag names.
+ *
+ * @param $ip string
+ *   The blocked IP address to retrieve.
  *
  * @return
- *   The blocked IP address from the database as an array.
+ *   The blocked IP address or FALSE if the IP address is not blocked.
  */
-function blocked_ip_load($iid) {
-  return db_query("SELECT * FROM {blocked_ips} WHERE iid = :iid", array(':iid' => $iid))->fetchAssoc();
+function blocked_ip_load($ip) {
+  // We can't use '.' in XML element names, so we replace it with '_'.
+  $escaped_ip = system_convert_config_ip_address($ip);
+  $blocked_ips = config('system.blocked_ips')->get('blocked_ips');
+  if (empty($blocked_ips) || !isset($blocked_ips['ip_' . $escaped_ip])) {
+    return FALSE;
+  }
+  return $blocked_ips['ip_' . $escaped_ip];
 }
 
 /**
@@ -4020,3 +4031,16 @@ function system_admin_paths() {
   );
   return $paths;
 }
+
+/**
+ * Helper function to convert . to _ to allow ips to be stored in XML.
+ *
+ * @param string $ip
+ *   String ip address that needs to be converted.
+ *
+ * @return string
+ *   A string with periods converted to underscores.
+ */
+function system_convert_config_ip_address($ip) {
+  return str_replace('.', '_', $ip);
+}
diff --git a/core/modules/system/system.test b/core/modules/system/system.test
index 9287d16..894c8c5 100644
--- a/core/modules/system/system.test
+++ b/core/modules/system/system.test
@@ -673,13 +673,12 @@ class IPAddressBlockingTestCase extends DrupalWebTestCase {
    */
   function testIPAddressValidation() {
     $this->drupalGet('admin/config/people/ip-blocking');
-
     // Block a valid IP address.
     $edit = array();
     $edit['ip'] = '192.168.1.1';
     $this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
-    $ip = db_query("SELECT iid from {blocked_ips} WHERE ip = :ip", array(':ip' => $edit['ip']))->fetchField();
-    $this->assertTrue($ip, t('IP address found in database.'));
+    $ip = blocked_ip_load($edit['ip']);
+    $this->assertNotEqual($ip, FALSE, 'IP address found in config file.');
     $this->assertRaw(t('The IP address %ip has been blocked.', array('%ip' => $edit['ip'])), t('IP address was blocked.'));
 
     // Try to block an IP address that's already blocked.
@@ -709,8 +708,8 @@ class IPAddressBlockingTestCase extends DrupalWebTestCase {
     // Pass an IP address as a URL parameter and submit it.
     $submit_ip = '1.2.3.4';
     $this->drupalPost('admin/config/people/ip-blocking/' . $submit_ip, NULL, t('Add'));
-    $ip = db_query("SELECT iid from {blocked_ips} WHERE ip = :ip", array(':ip' => $submit_ip))->fetchField();
-    $this->assertTrue($ip, t('IP address found in database'));
+    $ip = blocked_ip_load($submit_ip);
+    $this->assertNotEqual($ip, FALSE, 'IP address found in config file.');
     $this->assertRaw(t('The IP address %ip has been blocked.', array('%ip' => $submit_ip)), t('IP address was blocked.'));
 
     // Submit your own IP address. This fails, although it works when testing manually.
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 4f3fab8..2e43e1e 100755
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -465,7 +465,7 @@ ini_set('session.cookie_lifetime', 2000000);
  * IP blocking:
  *
  * To bypass database queries for denied IP addresses, use this setting.
- * Drupal queries the {blocked_ips} table by default on every page request
+ * Drupal looks up the IPs in a config file named system.blocked_ips.xml
  * for both authenticated and anonymous users. This allows the system to
  * block IP addresses from within the administrative interface and before any
  * modules are loaded. However on high traffic websites you may want to avoid
