diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
index 2f816d1..effdd83 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
@@ -38,6 +38,7 @@ import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.SplitDocTy
 import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.SplitDocType.DEFAULT_LEAF;
 
 public class VersionGarbageCollector {
+    static final int DELETION_BATCH_SIZE = 450;
     private final DocumentNodeStore nodeStore;
     private final VersionGCSupport versionStore;
 
@@ -91,6 +92,7 @@ public class VersionGarbageCollector {
     private void collectDeletedDocuments(VersionGCStats stats, Revision headRevision, long oldestRevTimeStamp) {
         List<String> docIdsToDelete = new ArrayList<String>();
         Iterable<NodeDocument> itr = versionStore.getPossiblyDeletedDocs(oldestRevTimeStamp);
+        long totalCount = 0;
         try {
             for (NodeDocument doc : itr) {
                 //Check if node is actually deleted at current revision
@@ -104,24 +106,36 @@ public class VersionGarbageCollector {
                         docIdsToDelete.add(prevDoc.getId());
                     }
                 }
+
+                if (docIdsToDelete.size() >= DELETION_BATCH_SIZE){
+                    totalCount += docIdsToDelete.size();
+                    deleteDocs(docIdsToDelete);
+                    docIdsToDelete.clear();
+                }
             }
         } finally {
             Utils.closeIfCloseable(itr);
         }
 
-        if(log.isDebugEnabled()) {
+        totalCount += docIdsToDelete.size();
+        deleteDocs(docIdsToDelete);
+
+        nodeStore.invalidateDocChildrenCache();
+        stats.deletedDocGCCount = totalCount;
+    }
+
+    private void deleteDocs(List<String> docIdsToDelete) {
+        if (log.isDebugEnabled()) {
             StringBuilder sb = new StringBuilder("Deleted document with following ids were deleted as part of GC \n");
             Joiner.on(StandardSystemProperty.LINE_SEPARATOR.value()).appendTo(sb, docIdsToDelete);
             log.debug(sb.toString());
         }
         nodeStore.getDocumentStore().remove(Collection.NODES, docIdsToDelete);
-        nodeStore.invalidateDocChildrenCache();
-        stats.deletedDocGCCount += docIdsToDelete.size();
     }
 
     public static class VersionGCStats {
         boolean ignoredGCDueToCheckPoint;
-        int deletedDocGCCount;
+        long deletedDocGCCount;
         int splitDocGCCount;
         int intermediateSplitDocGCCount;
 
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorTest.java
index 5b89883..5872800 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorTest.java
@@ -384,6 +384,34 @@ public class VersionGarbageCollectorTest {
         assertTrue("too many revisions: " + numRevs, numRevs < 6000);
     }
 
+    @Test
+    public void testGCDeletedDocumentInBatches() throws Exception{
+        //1. Create nodes
+        int noOfChildDocs = VersionGarbageCollector.DELETION_BATCH_SIZE * 2 + 50;
+        NodeBuilder b1 = store.getRoot().builder();
+        NodeBuilder x = b1.child("x");
+        for (int i = 0; i < noOfChildDocs; i++) {
+            x.child("child" + i);
+        }
+        store.merge(b1, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+        long maxAge = 1; //hours
+        long delta = TimeUnit.MINUTES.toMillis(10);
+
+        //Remove x/y
+        NodeBuilder b2 = store.getRoot().builder();
+        b2.child("x").remove();
+        store.merge(b2, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+        store.runBackgroundOperations();
+
+        //3. Check that deleted doc does get collected post maxAge
+        clock.waitUntil(clock.getTime() + HOURS.toMillis(maxAge*2) + delta);
+
+        VersionGCStats stats = gc.gc(maxAge*2, HOURS);
+        assertEquals(noOfChildDocs + 1, stats.deletedDocGCCount);
+    }
+
     private void merge(DocumentNodeStore store, NodeBuilder builder)
             throws CommitFailedException {
         store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
