diff --git a/lib/reducers/db-ops-reducer.js b/lib/reducers/db-ops-reducer.js
--- a/lib/reducers/db-ops-reducer.js
+++ b/lib/reducers/db-ops-reducer.js
@@ -1,10 +1,14 @@
 // @flow
 
 import { opsProcessingFinishedActionType } from '../actions/db-ops-actions.js';
+import { extractKeyserverIDFromIDOptional } from '../keyserver-conn/keyserver-call-utils.js';
+import type { MessageSearchStoreOperation } from '../message-search-types.js';
+import type { MessageStoreOperation } from '../ops/message-store-ops.js';
 import type {
   MessageSourceMetadata,
   DBOpsStore,
 } from '../types/db-ops-types.js';
+import { messageTypes } from '../types/message-types-enum.js';
 import type { BaseAction } from '../types/redux-types.js';
 import type { StoreOperations } from '../types/store-ops-types.js';
 import { values } from '../utils/objects.js';
@@ -21,13 +25,69 @@
   return store;
 }
 
+function getMessageSearchStoreOps(
+  messageStoreOps: ?$ReadOnlyArray<MessageStoreOperation>,
+): $ReadOnlyArray<MessageSearchStoreOperation> {
+  if (!messageStoreOps) {
+    return [];
+  }
+  const messageSearchStoreOps: MessageSearchStoreOperation[] = [];
+  for (const messageOp of messageStoreOps) {
+    if (messageOp.type === 'replace') {
+      // We only create search index for thick threads,
+      // and for non-local messages
+      const { messageInfo } = messageOp.payload;
+      if (
+        extractKeyserverIDFromIDOptional(messageInfo.threadID) ||
+        !messageInfo.id
+      ) {
+        continue;
+      }
+
+      if (messageInfo.type === messageTypes.TEXT) {
+        messageSearchStoreOps.push({
+          type: 'update_search_messages',
+          payload: {
+            originalMessageID: messageInfo.id,
+            messageID: messageInfo.id,
+            content: messageInfo.text,
+          },
+        });
+      } else if (messageInfo.type === messageTypes.EDIT_MESSAGE) {
+        messageSearchStoreOps.push({
+          type: 'update_search_messages',
+          payload: {
+            originalMessageID: messageInfo.targetMessageID,
+            messageID: messageInfo.id,
+            content: messageInfo.text,
+          },
+        });
+      }
+    }
+  }
+  return messageSearchStoreOps;
+}
+
 function queueDBOps(
   store: DBOpsStore,
   messageSourceMetadata: ?MessageSourceMetadata,
-  ops: StoreOperations,
+  inputOps: StoreOperations,
 ): DBOpsStore {
-  const areNewOpsPresent = values(ops).some(opsArray => opsArray.length > 0);
+  const areNewOpsPresent = values(inputOps).some(
+    opsArray => opsArray.length > 0,
+  );
   let newEntry = null;
+
+  const { messageStoreOperations } = inputOps;
+  const messageSearchStoreOperations = getMessageSearchStoreOps(
+    messageStoreOperations,
+  );
+
+  const ops = {
+    ...inputOps,
+    messageSearchStoreOperations,
+  };
+
   if (messageSourceMetadata && areNewOpsPresent) {
     newEntry = {
       messageSourceMetadata,
@@ -53,4 +113,4 @@
   };
 }
 
-export { reduceDBOpsStore, queueDBOps };
+export { reduceDBOpsStore, queueDBOps, getMessageSearchStoreOps };
diff --git a/lib/types/store-ops-types.js b/lib/types/store-ops-types.js
--- a/lib/types/store-ops-types.js
+++ b/lib/types/store-ops-types.js
@@ -22,7 +22,10 @@
 import type { ThreadActivityStore } from './thread-activity-types.js';
 import type { ClientDBThreadInfo, ThreadStore } from './thread-types.js';
 import type { UserInfos } from './user-types.js';
-import type { ClientDBMessageSearchStoreOperation } from '../message-search-types.js';
+import type {
+  ClientDBMessageSearchStoreOperation,
+  MessageSearchStoreOperation,
+} from '../message-search-types.js';
 import type {
   ClientDBAuxUserInfo,
   ClientDBAuxUserStoreOperation,
@@ -90,6 +93,7 @@
   +threadActivityStoreOperations?: $ReadOnlyArray<ThreadActivityStoreOperation>,
   +outboundP2PMessages?: $ReadOnlyArray<OutboundP2PMessage>,
   +entryStoreOperations?: $ReadOnlyArray<EntryStoreOperation>,
+  +messageSearchStoreOperations?: $ReadOnlyArray<MessageSearchStoreOperation>,
 };
 
 export type ClientDBStoreOperations = {
diff --git a/native/redux/redux-utils.js b/native/redux/redux-utils.js
--- a/native/redux/redux-utils.js
+++ b/native/redux/redux-utils.js
@@ -47,6 +47,7 @@
     threadActivityStoreOperations,
     outboundP2PMessages,
     entryStoreOperations,
+    messageSearchStoreOperations,
   } = storeOperations;
 
   const convertedThreadStoreOperations =
@@ -102,6 +103,7 @@
       threadActivityStoreOperations: convertedThreadActivityStoreOperations,
       outboundP2PMessages,
       entryStoreOperations: convertedEntryStoreOperations,
+      messageSearchStoreOperations,
     };
     if (values(dbOps).some(ops => ops && ops.length > 0)) {
       promises.push(commCoreModule.processDBStoreOperations(dbOps));
diff --git a/web/redux/initial-state-gate.js b/web/redux/initial-state-gate.js
--- a/web/redux/initial-state-gate.js
+++ b/web/redux/initial-state-gate.js
@@ -9,6 +9,7 @@
 import type { MessageStoreOperation } from 'lib/ops/message-store-ops.js';
 import type { ThreadStoreOperation } from 'lib/ops/thread-store-ops.js';
 import type { UserStoreOperation } from 'lib/ops/user-store-ops.js';
+import { getMessageSearchStoreOps } from 'lib/reducers/db-ops-reducer.js';
 import { allUpdatesCurrentAsOfSelector } from 'lib/selectors/keyserver-selectors.js';
 import { canUseDatabaseOnWeb } from 'lib/shared/web-database.js';
 import type { RawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
@@ -164,6 +165,9 @@
           messageStoreOperations.length > 0 ||
           entryStoreOperations.length > 0
         ) {
+          const messageSearchStoreOperations = getMessageSearchStoreOps(
+            messageStoreOperations,
+          );
           await processDBStoreOperations(
             {
               threadStoreOperations,
@@ -178,6 +182,7 @@
               auxUserStoreOperations: [],
               threadActivityStoreOperations: [],
               entryStoreOperations,
+              messageSearchStoreOperations,
             },
             currentLoggedInUserID,
           );
diff --git a/web/shared-worker/utils/store.js b/web/shared-worker/utils/store.js
--- a/web/shared-worker/utils/store.js
+++ b/web/shared-worker/utils/store.js
@@ -179,6 +179,7 @@
     threadActivityStoreOperations,
     outboundP2PMessages,
     entryStoreOperations,
+    messageSearchStoreOperations,
   } = storeOperations;
 
   const canUseDatabase = canUseDatabaseOnWeb(userID);
@@ -250,6 +251,7 @@
         threadActivityStoreOperations: convertedThreadActivityStoreOperations,
         outboundP2PMessages,
         entryStoreOperations: convertedEntryStoreOperations,
+        messageSearchStoreOperations,
       },
     });
   } catch (e) {