diff --git a/common/dconf-changeset.c b/common/dconf-changeset.c
index 35b02be..80cd8d2 100644
--- a/common/dconf-changeset.c
+++ b/common/dconf-changeset.c
@@ -309,6 +309,20 @@ dconf_changeset_get (DConfChangeset  *changeset,
   return TRUE;
 }
 
+/**
+ * dconf_changeset_table_iter_init:
+ * @changeset: a #DConfChangeset
+ * @iter: a pointer to a #GHashTableIter
+ *
+ * Creates a hash table iterator for the table of @changeset
+ **/
+void
+dconf_changeset_table_iter_init (DConfChangeset *changeset,
+                                 GHashTableIter *iter)
+{
+  g_hash_table_iter_init (iter, changeset->table);
+}
+
 /**
  * dconf_changeset_is_similar_to:
  * @changeset: a #DConfChangeset
diff --git a/common/dconf-changeset.h b/common/dconf-changeset.h
index b0ce450..92ef9fd 100644
--- a/common/dconf-changeset.h
+++ b/common/dconf-changeset.h
@@ -47,6 +47,9 @@ gboolean                dconf_changeset_get                             (DConfCh
                                                                          const gchar              *key,
                                                                          GVariant                **value);
 
+void                    dconf_changeset_table_iter_init                 (DConfChangeset           *changeset,
+                                                                         GHashTableIter           *iter);
+
 gboolean                dconf_changeset_is_similar_to                   (DConfChangeset           *changeset,
                                                                          DConfChangeset           *other);
 
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c
index bc36e52..cd33136 100644
--- a/engine/dconf-engine.c
+++ b/engine/dconf-engine.c
@@ -965,6 +965,48 @@ dconf_engine_prepare_change (DConfEngine     *engine,
  */
 static void dconf_engine_manage_queue (DConfEngine *engine);
 
+/**
+ * dconf_engine_changeset_has_no_effect:
+ * @engine: a #DConfEngine to check the effect of the changes on
+ * @changeset: a #DConfChangeset
+ * @read_through: a #GQueue to include pending changes from
+ *
+ * Checks if @changeset would have no effect when applied to @engine
+ * (i.e. for all changes, the new value is the same as the old value,
+ * or the same as the pending value in @read_through).
+ *
+ * Returns: %TRUE if @changeset is empty
+ **/
+gboolean
+dconf_engine_changeset_has_no_effect (DConfEngine *engine, DConfChangeset *changeset, GQueue *read_through)
+{
+  if (dconf_changeset_is_empty (changeset))
+    return TRUE;
+
+  GHashTableIter iter;
+  gpointer key, new_value;
+  GVariant *current_value;
+
+  dconf_changeset_table_iter_init(changeset, &iter);
+  while (g_hash_table_iter_next (&iter, &key, &new_value))
+    {
+      GVariant *current_value = dconf_engine_read (engine,
+                                                   DCONF_READ_USER_VALUE,
+                                                   read_through,
+                                                   key);
+
+      if (!g_variant_equal(current_value, new_value))
+        {
+          g_variant_unref(current_value);
+          return FALSE;
+        }
+
+      g_variant_unref(current_value);
+    }
+
+  return TRUE;
+}
+
 static void
 dconf_engine_emit_changes (DConfEngine    *engine,
                            DConfChangeset *changeset,
@@ -1135,7 +1177,7 @@ dconf_engine_change_fast (DConfEngine     *engine,
 {
   GList *node;
 
-  if (dconf_changeset_is_empty (changeset))
+  if (dconf_engine_changeset_has_no_effect (engine, changeset, &engine->pending))
     return TRUE;
 
   if (!dconf_engine_changeset_changes_only_writable_keys (engine, changeset, error))
@@ -1202,7 +1244,7 @@ dconf_engine_change_sync (DConfEngine     *engine,
 {
   GVariant *reply;
 
-  if (dconf_changeset_is_empty (changeset))
+  if (dconf_engine_changeset_has_no_effect (engine, changeset, &engine->pending))
     {
       if (tag)
         *tag = g_strdup ("");
diff --git a/engine/dconf-engine.h b/engine/dconf-engine.h
index 2485423..6e6f7e6 100644
--- a/engine/dconf-engine.h
+++ b/engine/dconf-engine.h
@@ -137,6 +137,11 @@ G_GNUC_INTERNAL
 void                    dconf_engine_unwatch_fast                       (DConfEngine             *engine,
                                                                          const gchar             *path);
 
+G_GNUC_INTERNAL
+gboolean                dconf_engine_changeset_has_no_effect            (DConfEngine              *engine,
+                                                                         DConfChangeset           *changeset,
+                                                                         GQueue                   *read_through);
+
 G_GNUC_INTERNAL
 gboolean                dconf_engine_change_fast                        (DConfEngine             *engine,
                                                                          DConfChangeset          *changeset,
