diff --git a/lib/reducers/dm-operations-queue-reducer.js b/lib/reducers/dm-operations-queue-reducer.js
--- a/lib/reducers/dm-operations-queue-reducer.js
+++ b/lib/reducers/dm-operations-queue-reducer.js
@@ -2,6 +2,7 @@
 
 import _mapValues from 'lodash/fp/mapValues.js';
 
+import type { DMOperationStoreOperation } from '../ops/dm-operations-store-ops.js';
 import {
   clearQueuedEntryDMOpsActionType,
   clearQueuedMembershipDMOpsActionType,
@@ -17,108 +18,136 @@
 function reduceDMOperationsQueue(
   store: QueuedDMOperations,
   action: BaseAction,
-): QueuedDMOperations {
+): {
+  +store: QueuedDMOperations,
+  +operations: $ReadOnlyArray<DMOperationStoreOperation>,
+} {
   if (action.type === queueDMOpsActionType) {
     const { condition, operation, timestamp } = action.payload;
 
     if (condition.type === 'thread') {
       return {
-        ...store,
-        threadQueue: {
-          ...store.threadQueue,
-          [condition.threadID]: [
-            ...(store.threadQueue[condition.threadID] ?? []),
-            { operation, timestamp },
-          ],
+        store: {
+          ...store,
+          threadQueue: {
+            ...store.threadQueue,
+            [condition.threadID]: [
+              ...(store.threadQueue[condition.threadID] ?? []),
+              { operation, timestamp },
+            ],
+          },
         },
+        operations: [],
       };
     }
 
     if (condition.type === 'entry') {
       return {
-        ...store,
-        entryQueue: {
-          ...store.entryQueue,
-          [condition.entryID]: [
-            ...(store.entryQueue[condition.entryID] ?? []),
-            { operation, timestamp },
-          ],
+        store: {
+          ...store,
+          entryQueue: {
+            ...store.entryQueue,
+            [condition.entryID]: [
+              ...(store.entryQueue[condition.entryID] ?? []),
+              { operation, timestamp },
+            ],
+          },
         },
+        operations: [],
       };
     }
 
     if (condition.type === 'message') {
       return {
-        ...store,
-        messageQueue: {
-          ...store.messageQueue,
-          [condition.messageID]: [
-            ...(store.messageQueue[condition.messageID] ?? []),
-            { operation, timestamp },
-          ],
+        store: {
+          ...store,
+          messageQueue: {
+            ...store.messageQueue,
+            [condition.messageID]: [
+              ...(store.messageQueue[condition.messageID] ?? []),
+              { operation, timestamp },
+            ],
+          },
         },
+        operations: [],
       };
     }
 
     return {
-      ...store,
-      membershipQueue: {
-        ...store.membershipQueue,
-        [condition.threadID]: {
-          ...(store.membershipQueue[condition.threadID] ?? {}),
-          [condition.userID]: [
-            ...(store.membershipQueue[condition.threadID]?.[condition.userID] ??
-              []),
-            { operation, timestamp },
-          ],
+      store: {
+        ...store,
+        membershipQueue: {
+          ...store.membershipQueue,
+          [condition.threadID]: {
+            ...(store.membershipQueue[condition.threadID] ?? {}),
+            [condition.userID]: [
+              ...(store.membershipQueue[condition.threadID]?.[
+                condition.userID
+              ] ?? []),
+              { operation, timestamp },
+            ],
+          },
         },
       },
+      operations: [],
     };
   } else if (action.type === pruneDMOpsQueueActionType) {
     const filterOperations = (queue: OperationsQueue) =>
       queue.filter(op => op.timestamp >= action.payload.pruneMaxTimestamp);
     return {
-      ...store,
-      threadQueue: _mapValues(operations => filterOperations(operations))(
-        store.threadQueue,
-      ),
-      messageQueue: _mapValues(operations => filterOperations(operations))(
-        store.messageQueue,
-      ),
-      entryQueue: _mapValues(operations => filterOperations(operations))(
-        store.entryQueue,
-      ),
-      membershipQueue: _mapValues(threadMembershipQueue =>
-        _mapValues(operations => filterOperations(operations))(
-          threadMembershipQueue,
+      store: {
+        ...store,
+        threadQueue: _mapValues(operations => filterOperations(operations))(
+          store.threadQueue,
         ),
-      )(store.membershipQueue),
+        messageQueue: _mapValues(operations => filterOperations(operations))(
+          store.messageQueue,
+        ),
+        entryQueue: _mapValues(operations => filterOperations(operations))(
+          store.entryQueue,
+        ),
+        membershipQueue: _mapValues(threadMembershipQueue =>
+          _mapValues(operations => filterOperations(operations))(
+            threadMembershipQueue,
+          ),
+        )(store.membershipQueue),
+      },
+      operations: [],
     };
   } else if (action.type === clearQueuedThreadDMOpsActionType) {
     const { [action.payload.threadID]: removed, ...threadQueue } =
       store.threadQueue;
     return {
-      ...store,
-      threadQueue,
+      store: {
+        ...store,
+        threadQueue,
+      },
+      operations: [],
     };
   } else if (action.type === clearQueuedMessageDMOpsActionType) {
     const { [action.payload.messageID]: removed, ...messageQueue } =
       store.messageQueue;
     return {
-      ...store,
-      messageQueue,
+      store: {
+        ...store,
+        messageQueue,
+      },
+      operations: [],
     };
   } else if (action.type === clearQueuedEntryDMOpsActionType) {
     const { [action.payload.entryID]: removed, ...entryQueue } =
       store.entryQueue;
     return {
-      ...store,
-      entryQueue,
+      store: {
+        ...store,
+        entryQueue,
+      },
+      operations: [],
     };
   } else if (action.type === clearQueuedMembershipDMOpsActionType) {
     const threadQueue = store.membershipQueue[action.payload.threadID];
     if (!threadQueue) {
-      return store;
+      return { store, operations: [] };
     }
 
     const { [action.payload.userID]: removed, ...queue } = threadQueue;
@@ -126,20 +155,26 @@
       const { [action.payload.threadID]: removedThread, ...membershipQueue } =
         store.membershipQueue;
       return {
-        ...store,
-        membershipQueue,
+        store: {
+          ...store,
+          membershipQueue,
+        },
+        operations: [],
       };
     }
 
     return {
-      ...store,
-      membershipQueue: {
-        ...store.membershipQueue,
-        [action.payload.userID]: queue,
+      store: {
+        ...store,
+        membershipQueue: {
+          ...store.membershipQueue,
+          [action.payload.userID]: queue,
+        },
       },
+      operations: [],
     };
   }
-  return store;
+  return { store, operations: [] };
 }
 
 export { reduceDMOperationsQueue };
diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js
--- a/lib/reducers/master-reducer.js
+++ b/lib/reducers/master-reducer.js
@@ -194,6 +194,9 @@
   const { threadActivityStore, threadActivityStoreOperations } =
     reduceThreadActivity(state.threadActivityStore, action);
 
+  const { store: queuedDMOperations, operations: dmOperationStoreOperations } =
+    reduceDMOperationsQueue(state.queuedDMOperations, action);
+
   let storeOperations = {
     draftStoreOperations,
     threadStoreOperations,
@@ -207,6 +210,7 @@
     auxUserStoreOperations,
     threadActivityStoreOperations,
     entryStoreOperations,
+    dmOperationStoreOperations,
   };
 
   if (
@@ -255,10 +259,7 @@
         state.tunnelbrokerDeviceToken,
         action,
       ),
-      queuedDMOperations: reduceDMOperationsQueue(
-        state.queuedDMOperations,
-        action,
-      ),
+      queuedDMOperations,
       holderStore: reduceHolderStore(state.holderStore, action),
     },
     storeOperations,