diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
index f4c0cdf..1ce2fb8 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.plugins.document;
 
 import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.apache.jackrabbit.oak.api.CommitFailedException.CONSTRAINT;
+import static org.apache.jackrabbit.oak.api.CommitFailedException.MERGE;
 import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
 import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.REMEMBER_REVISION_ORDER_MILLIS;
 import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS;
@@ -44,11 +45,13 @@ import java.util.TreeSet;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Semaphore;
+import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
+import com.google.common.base.Stopwatch;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -1074,6 +1077,95 @@ public class DocumentNodeStoreTest {
         store.dispose();
     }
 
+    @Test
+    public void slowRebase() throws Exception {
+        final Stopwatch watch = Stopwatch.createStarted();
+        final int NUM_NODES = DocumentRootBuilder.UPDATE_LIMIT / 2;
+        final int NUM_PROPS = 10;
+        final int REBASE_COUNT = 10;
+        final DocumentNodeStore ns = new DocumentMK.Builder().getNodeStore();
+        final SynchronousQueue<CountDownLatch> syncQueue = new SynchronousQueue<CountDownLatch>();
+
+        NodeBuilder builder = ns.getRoot().builder();
+        for (int i = 0; i < NUM_NODES; i++) {
+            NodeBuilder c = builder.child("n" + i).child("m" + i);
+            for (int j = 0; j < NUM_PROPS; j++) {
+                c.setProperty("p" + j, "value");
+            }
+        }
+
+        //1. Prepare a large tree
+        merge(ns, builder);
+
+        builder = ns.getRoot().builder();
+        for (int i = 0; i < NUM_NODES; i++) {
+            NodeBuilder c = builder.getChildNode("n" + i).getChildNode("m" + i);
+            for (int j = 0; j < NUM_PROPS; j++) {
+                c.setProperty("q" + j, "value");
+                c.setProperty("r" + j, "value");
+                c.setProperty("s" + j, "value");
+                c.setProperty("t" + j, "value");
+            }
+        }
+
+        final AtomicInteger commitCounter = new AtomicInteger();
+
+        Thread changeHead = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                while(true){
+                    try {
+                        CountDownLatch latch = syncQueue.take();
+                        doSomeChange(ns);
+                        latch.countDown();
+                    } catch (InterruptedException e) {
+                        Thread.interrupted();
+                        return;
+                    }
+                }
+
+            }
+        });
+        changeHead.start();
+
+        final CommitHook failingHook = new CommitHook() {
+            public NodeState processCommit(NodeState before, NodeState after, CommitInfo info)
+                    throws CommitFailedException {
+                if (commitCounter.get() < REBASE_COUNT){
+                    System.out.printf("---------------Failing commit - Count %d , TimeSpent %s %n",commitCounter.get(), watch);
+                    watch.reset().start();
+                    CountDownLatch latch = new CountDownLatch(1);
+                    try {
+                        syncQueue.put(latch);
+                        latch.await();
+                    } catch (InterruptedException ignore) {
+
+                    }
+                    commitCounter.incrementAndGet();
+                    throw new CommitFailedException(MERGE, 0, "fail");
+                }
+                return after;
+            }
+        };
+
+        doSomeChange(ns);
+        ns.merge(builder, CompositeHook.compose(
+                        Arrays.asList(new TestHook("p"), new TestHook("q"), new TestHook("r"), failingHook)),
+                CommitInfo.EMPTY);
+        changeHead.interrupt();
+        ns.dispose();
+    }
+
+    private void doSomeChange(NodeStore ns){
+        NodeBuilder b = ns.getRoot().builder();
+        b.setProperty("count", System.currentTimeMillis());
+        try {
+            merge(ns, b);
+        } catch (CommitFailedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     private static void assertNoPreviousDocs(Set<String> ids) {
         for (String id : ids) {
             assertFalse("must not read previous document: " +
