diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java
index 3d7e0f9..d70a131 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java
@@ -662,7 +662,7 @@ public class DocumentDiscoveryLiteService implements ClusterStateChangeListener,
         // Now from the above it also results that this only wakes up the
         // backgroundWorker if we have any pending 'backlogy instances'
         // otherwise this is a no-op
-        if (info == null) {
+        if (isExternal(info)) {
             // then ignore this as this is likely an external change
             // note: it could be a compacted change, in which case we should
             // probably still process it - but we have a 5sec fallback
@@ -675,4 +675,8 @@ public class DocumentDiscoveryLiteService implements ClusterStateChangeListener,
         wakeupBackgroundWorker(WakeupReason.BACKGROUND_READ_FINISHED);
     }
 
+    private static boolean isExternal(CommitInfo info) {
+        return info == null || info.isExternal();
+    }
+
 }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java
index ea21882..5dcc65d 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreObserver.java
@@ -93,7 +93,7 @@ public class SecondaryStoreObserver implements Observer {
             NodeState updatedSecondaryRoot = nodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
             secondaryObserver.contentChanged(DelegatingDocumentNodeState.wrap(updatedSecondaryRoot, differ));
 
-            TimerStats timer = info == null ? external : local;
+            TimerStats timer = isExternal(info) ? external : local;
             timer.update(w.elapsed(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
 
             if (!firstEventProcessed){
@@ -106,4 +106,8 @@ public class SecondaryStoreObserver implements Observer {
         }
     }
 
+    private static boolean isExternal(@Nullable CommitInfo info) {
+        return info == null || info.isExternal();
+    }
+
 }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
index 9b983b2..dbb7fc6 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
@@ -425,7 +425,7 @@ public final class FilterBuilder {
             }
 
             private boolean isExternal(CommitInfo info) {
-                return info == null;
+                return info == null || info.isExternal();
             }
             
             @Override
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java
index 6c456ce..8ed5796 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/BackgroundObserver.java
@@ -246,7 +246,7 @@ public class BackgroundObserver implements Observer, Closeable {
                 return size(filter(queue, new Predicate<ContentChange>() {
                     @Override
                     public boolean apply(ContentChange input) {
-                        return input.info != null;
+                        return !isExternal(input.info);
                     }
                 }));
             }
@@ -256,7 +256,7 @@ public class BackgroundObserver implements Observer, Closeable {
                 return size(filter(queue, new Predicate<ContentChange>() {
                     @Override
                     public boolean apply(ContentChange input) {
-                        return input.info == null;
+                        return isExternal(input.info);
                     }
                 }));
             }
@@ -273,7 +273,7 @@ public class BackgroundObserver implements Observer, Closeable {
         checkState(!stopped);
         checkNotNull(root);
 
-        if (alwaysCollapseExternalEvents && info == null && last != null && last.info == null) {
+        if (alwaysCollapseExternalEvents && isExternal(info) && last != null && isExternal(last.info)) {
             // This is an external change. If the previous change was
             // also external, we can drop it from the queue (since external
             // changes in any case can cover multiple commits) to help
@@ -311,6 +311,10 @@ public class BackgroundObserver implements Observer, Closeable {
 
     //------------------------------------------------------------< internal >---
 
+    private static boolean isExternal(@Nullable CommitInfo info) {
+        return info == null || info.isExternal();
+    }
+
     private static Logger getLogger(@Nonnull Observer observer) {
         return LoggerFactory.getLogger(checkNotNull(observer).getClass());
     }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
index 640a8f3..024ca0d 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
@@ -53,6 +53,8 @@ public final class CommitInfo {
 
     private final Map<String, Object> info;
 
+    private final boolean external;
+
     /**
      * Creates a commit info for the given session and user.
      *
@@ -72,9 +74,21 @@ public final class CommitInfo {
      * @param info info map
      */
     public CommitInfo(@Nonnull String sessionId, @Nullable String userId, Map<String, Object> info) {
+        this(sessionId, userId, info, false);
+    }
+
+    /**
+     * Creates a commit info for the given session and user and info map.
+     *  @param sessionId session identifier
+     * @param userId The user id.
+     * @param info info map
+     * @param external indicates if the commit info is from external change
+     */
+    public CommitInfo(@Nonnull String sessionId, @Nullable String userId, Map<String, Object> info, boolean external) {
         this.sessionId = checkNotNull(sessionId);
         this.userId = (userId == null) ? OAK_UNKNOWN : userId;
         this.info = checkNotNull(info);
+        this.external = external;
     }
 
     /**
@@ -100,6 +114,17 @@ public final class CommitInfo {
         return date;
     }
 
+
+    /**
+     * Return a flag indicating whether this is commit info is
+     * for an external change
+     *
+     * @return true if commit info is for an external change
+     */
+    public boolean isExternal() {
+        return external;
+    }
+
     /**
      * Returns the base path of this commit. All changes within this commit
      * are expected to be located within the returned path. By default this
@@ -135,6 +160,7 @@ public final class CommitInfo {
             return sessionId.equals(that.sessionId)
                     && userId.equals(that.userId)
                     && this.date == that.date
+                    && this.external == that.external
                     && info.equals(that.info);
         } else {
             return false;
@@ -143,7 +169,7 @@ public final class CommitInfo {
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(sessionId, userId, date, info);
+        return Objects.hashCode(sessionId, userId, date, info, external);
     }
 
     @Override
@@ -151,6 +177,7 @@ public final class CommitInfo {
         return toStringHelper(this).omitNullValues()
                 .add("sessionId", sessionId)
                 .add("userId", userId)
+                .add("external", external)
                 .add("date", date)
                 .add("info", info)
                 .toString();
diff --git oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
index eba2108..c7acd43 100644
--- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
+++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/EventFactory.java
@@ -64,7 +64,7 @@ public class EventFactory {
 
     EventFactory(NamePathMapper mapper, CommitInfo commitInfo) {
         this.mapper = mapper;
-        if (commitInfo != null) {
+        if (commitInfo != null && !commitInfo.isExternal()) {
             this.userID = commitInfo.getUserId();
             Object userData = commitInfo.getInfo().get(USER_DATA);
             this.userData = userData instanceof String ? (String) userData : null;
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java
index e5ccf0f..c227bf3 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserver.java
@@ -41,7 +41,7 @@ public class LocalIndexObserver implements Observer{
     @Override
     public void contentChanged(@Nonnull NodeState root, @Nullable CommitInfo info) {
         //TODO [hybrid] Do external diff?
-        if (info == null){
+        if (info == null || info.isExternal()){
            return;
         }
 
