diff --git a/lib/reducers/integrity-reducer.js b/lib/reducers/integrity-reducer.js
--- a/lib/reducers/integrity-reducer.js
+++ b/lib/reducers/integrity-reducer.js
@@ -9,9 +9,12 @@
   keyserverRegisterActionTypes,
 } from '../actions/user-actions.js';
 import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js';
-import { integrityStoreOpsHandlers } from '../ops/integrity-store-ops.js';
+import {
+  integrityStoreOpsHandlers,
+  type IntegrityStoreOperation,
+} from '../ops/integrity-store-ops.js';
 import type { ThreadStoreOperation } from '../ops/thread-store-ops';
-import type { IntegrityStore } from '../types/integrity-types';
+import type { IntegrityStore, ThreadHashes } from '../types/integrity-types';
 import type { RawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import type { BaseAction } from '../types/redux-types.js';
 import { fullStateSyncActionType } from '../types/socket-types.js';
@@ -71,25 +74,47 @@
   if (threadStoreOperations.length === 0) {
     return newState;
   }
-  let processedThreadHashes = { ...newState.threadHashes };
+  const integrityOperations: IntegrityStoreOperation[] = [];
+  let groupedReplaceThreadHashes: ThreadHashes = {};
   let threadHashingStatus = newState.threadHashingStatus;
   for (const operation of threadStoreOperations) {
+    if (
+      operation.type !== 'replace' &&
+      Object.keys(groupedReplaceThreadHashes).length > 0
+    ) {
+      integrityOperations.push({
+        type: 'replace_integrity_thread_hashes',
+        payload: { threadHashes: groupedReplaceThreadHashes },
+      });
+      groupedReplaceThreadHashes = {};
+    }
+
     if (operation.type === 'replace') {
-      processedThreadHashes[operation.payload.id] = hash(
-        operation.payload.threadInfo,
-      );
+      const newIntegrityThreadHash = hash(operation.payload.threadInfo);
+      groupedReplaceThreadHashes = {
+        ...groupedReplaceThreadHashes,
+        [operation.payload.id]: newIntegrityThreadHash,
+      };
     } else if (operation.type === 'remove') {
-      for (const id of operation.payload.ids) {
-        delete processedThreadHashes[id];
-      }
+      integrityOperations.push({
+        type: 'remove_integrity_thread_hashes',
+        payload: { ids: operation.payload.ids },
+      });
     } else if (operation.type === 'remove_all') {
-      processedThreadHashes = {};
+      integrityOperations.push({ type: 'remove_all_integrity_thread_hashes' });
       threadHashingStatus = 'completed';
     }
   }
+  if (Object.keys(groupedReplaceThreadHashes).length > 0) {
+    integrityOperations.push({
+      type: 'replace_integrity_thread_hashes',
+      payload: { threadHashes: groupedReplaceThreadHashes },
+    });
+  }
+
   return {
     ...newState,
-    threadHashes: processedThreadHashes,
+    threadHashes: processStoreOps(newState, integrityOperations).threadHashes,
     threadHashingStatus,
   };
 }