diff --git a/core/modules/config/src/Tests/ConfigImportAllTest.php b/core/modules/config/src/Tests/ConfigImportAllTest.php
index 1624211..ced8a96 100644
--- a/core/modules/config/src/Tests/ConfigImportAllTest.php
+++ b/core/modules/config/src/Tests/ConfigImportAllTest.php
@@ -69,7 +69,10 @@ public function testInstallUninstall() {
 
     $fields = \Drupal::entityManager()->getStorage('field_config')->loadMultiple();
     \Drupal::entityManager()->getStorage('field_config')->delete($fields);
-    // Purge the data.
+    // Purge the data. Need to call this twice to actually remove all the
+    // fields. First time around will purge the instances. Second time will
+    // delete the instances and fields.
+    field_purge_batch(1000);
     field_purge_batch(1000);
 
     system_list_reset();
diff --git a/core/modules/filter/src/Entity/FilterFormat.php b/core/modules/filter/src/Entity/FilterFormat.php
index 944d5c7..8bda458 100644
--- a/core/modules/filter/src/Entity/FilterFormat.php
+++ b/core/modules/filter/src/Entity/FilterFormat.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\filter\Entity;
 
+use Drupal\Component\Utility\DiffArray;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityWithPluginBagsInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
@@ -97,7 +98,7 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface, En
    *
    * An associative array of filters assigned to the text format, keyed by the
    * instance ID of each filter and using the properties:
-   * - plugin_id: The plugin ID of the filter plugin instance.
+   * - id: The plugin ID of the filter plugin instance.
    * - module: The name of the module providing the filter.
    * - status: (optional) A Boolean indicating whether the filter is
    *   enabled in the text format. Defaults to FALSE.
@@ -194,8 +195,17 @@ public function preSave(EntityStorageInterface $storage) {
 
     $this->name = trim($this->label());
 
-    // @todo Do not save disabled filters whose properties are identical to
-    //   all default properties.
+    // Remove disabled filters which have default configuration.
+    $this->filters = array_filter($this->filters, function($filter) {
+      $default = \Drupal::service('plugin.manager.filter')->getDefinition($filter['id']);
+      if (!$filter['status']) {
+        // Compare the current settings to the default settings. If there are
+        // any customisations save them to configuration.
+        $diff = DiffArray::diffAssocRecursive($filter, $default);
+        return !empty($diff);
+      }
+      return TRUE;
+    });
   }
 
   /**
diff --git a/core/modules/filter/src/Tests/FilterAPITest.php b/core/modules/filter/src/Tests/FilterAPITest.php
index 2c5522a..383a7c0 100644
--- a/core/modules/filter/src/Tests/FilterAPITest.php
+++ b/core/modules/filter/src/Tests/FilterAPITest.php
@@ -335,6 +335,50 @@ function testTypedDataAPI() {
   }
 
   /**
+   * Tests that FilterFormat::preSave() only saves customised plugins.
+   */
+  public function testFilterFormatPreSave() {
+    /** @var \Drupal\filter\FilterFormatInterface $crazy_format */
+    $crazy_format = entity_create('filter_format', array(
+      'format' => 'crazy',
+      'name' => 'Crazy',
+      'weight' => 1,
+      'filters' => array(
+        'filter_html_escape' => array(
+          'weight' => 10,
+          'status' => 1,
+        ),
+        'filter_html' => array(
+          'weight' => -10,
+          'status' => 1,
+          'settings' => array(
+            'allowed_html' => '<p>',
+          ),
+        ),
+      )
+    ));
+    $crazy_format->save();
+    // Use config to directly load the configuration and check that only enabled
+    // or customised plugins are saved to configuration.
+    $filters = \Drupal::config('filter.format.crazy')->get('filters');
+    $this->assertEqual(array('filter_html_escape', 'filter_html'), array_keys($filters));
+
+    // Disable a plugin to ensure that disabled plugins with custom settings are
+    // stored in configuration.
+    $crazy_format->setFilterConfig('filter_html_escape', array('status' => FALSE));
+    $crazy_format->save();
+    $filters = \Drupal::config('filter.format.crazy')->get('filters');
+    $this->assertEqual(array('filter_html_escape', 'filter_html'), array_keys($filters));
+
+    // Set the settings as per default to ensure that disable plugins in this
+    // state are not stored in configuration.
+    $crazy_format->setFilterConfig('filter_html_escape', array('weight' => -10));
+    $crazy_format->save();
+    $filters = \Drupal::config('filter.format.crazy')->get('filters');
+    $this->assertEqual(array('filter_html'), array_keys($filters));
+  }
+
+  /**
    * Checks if an expected violation exists in the given violations.
    *
    * @param \Symfony\Component\Validator\ConstraintViolationListInterface $violations
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateFilterFormatTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateFilterFormatTest.php
index 47a3f32..8a27942 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateFilterFormatTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateFilterFormatTest.php
@@ -60,9 +60,9 @@ public function testFilterFormat() {
     $this->assertTrue($filters['filter_html']['status']);
 
     // These should be false by default.
-    $this->assertFalse($filters['filter_html_escape']['status']);
-    $this->assertFalse($filters['filter_caption']['status']);
-    $this->assertFalse($filters['filter_html_image_secure']['status']);
+    $this->assertFalse(isset($filters['filter_html_escape']));
+    $this->assertFalse(isset($filters['filter_caption']));
+    $this->assertFalse(isset($filters['filter_html_image_secure']));
 
     // Check variables migrated into filter.
     $this->assertIdentical($filters['filter_html']['settings']['allowed_html'], '<a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>');
diff --git a/core/modules/system/src/Tests/Entity/ConfigEntityImportTest.php b/core/modules/system/src/Tests/Entity/ConfigEntityImportTest.php
index 5fb79fb..a7d1ad3 100644
--- a/core/modules/system/src/Tests/Entity/ConfigEntityImportTest.php
+++ b/core/modules/system/src/Tests/Entity/ConfigEntityImportTest.php
@@ -2,11 +2,12 @@
 
 /**
  * @file
- * Contains \Drupal\system\Tests\Entity\ConfigEntityImportTestBase.
+ * Contains \Drupal\system\Tests\Entity\ConfigEntityImportTest.
  */
 
 namespace Drupal\system\Tests\Entity;
 
+use Drupal\Component\Utility\DiffArray;
 use Drupal\Core\Entity\EntityWithPluginBagsInterface;
 use Drupal\simpletest\WebTestBase;
 
@@ -110,13 +111,13 @@ protected function doFilterFormatUpdate() {
     $entity->set('filters', $filters);
     $entity->save();
     $this->assertIdentical($filters, $entity->get('filters'));
-    $this->assertIdentical($filters, $plugin_bag->getConfiguration());
+    $this->assertIdentical($filters, $this->filterFilters($plugin_bag->getConfiguration()));
 
     $filters['filter_url']['settings']['filter_url_length'] = -100;
     $entity->getPluginBags()['filters']->setConfiguration($filters);
     $entity->save();
     $this->assertIdentical($filters, $entity->get('filters'));
-    $this->assertIdentical($filters, $plugin_bag->getConfiguration());
+    $this->assertIdentical($filters, $this->filterFilters($plugin_bag->getConfiguration()));
 
     // Read the existing data, and prepare an altered version in staging.
     $custom_data = $original_data = $this->container->get('config.storage')->read($name);
@@ -125,6 +126,26 @@ protected function doFilterFormatUpdate() {
   }
 
   /**
+   * Filters an array of filters to only include customised filters.
+   *
+   * @param array $filters
+   *   An array fo filter plugin configuration keyed by plugin ID.
+   *
+   * @return array
+   *   The filtered array of filters.
+   */
+  protected function filterFilters(array $filters) {
+    return array_filter($filters, function($filter) {
+      $default = \Drupal::service('plugin.manager.filter')->getDefinition($filter['id']);
+      if (!$filter['status']) {
+        $diff = DiffArray::diffAssocRecursive($filter, $default);
+        return !empty($diff);
+      }
+      return TRUE;
+    });
+  }
+
+  /**
    * Tests updating an image style during import.
    */
   protected function doImageStyleUpdate() {
