diff --git a/lib/shared/dm-ops/leave-thread-spec.js b/lib/shared/dm-ops/leave-thread-spec.js
--- a/lib/shared/dm-ops/leave-thread-spec.js
+++ b/lib/shared/dm-ops/leave-thread-spec.js
@@ -11,7 +11,6 @@
 import { messageTypes } from '../../types/message-types-enum.js';
 import { threadTypes } from '../../types/thread-types-enum.js';
 import { updateTypes } from '../../types/update-types-enum.js';
-import type { ClientUpdateInfo } from '../../types/update-types.js';
 import { rawMessageInfoFromMessageData } from '../message-utils.js';
 import { userIsMember } from '../thread-utils.js';
 
@@ -45,7 +44,6 @@
       rawMessageInfoFromMessageData(messageData, messageID),
     ];
 
-    const updateInfos: Array<ClientUpdateInfo> = [];
     if (
       viewerID === editorID &&
       userIsMember(threadInfo, editorID) &&
@@ -53,28 +51,55 @@
         (threadInfo.parentThreadID &&
           !utilities.threadInfos[threadInfo.parentThreadID]))
     ) {
-      updateInfos.push({
-        type: updateTypes.DELETE_THREAD,
-        id: uuid.v4(),
-        time,
-        threadID,
-      });
-    } else {
-      const updatedThreadInfo = {
-        ...threadInfo,
-        members: threadInfo.members.filter(member => member.id !== editorID),
+      return {
+        rawMessageInfos,
+        updateInfos: [
+          {
+            type: updateTypes.DELETE_THREAD,
+            id: uuid.v4(),
+            time,
+            threadID,
+          },
+        ],
       };
-      updateInfos.push({
-        type: updateTypes.UPDATE_THREAD,
-        id: uuid.v4(),
-        time,
-        threadInfo: updatedThreadInfo,
-      });
     }
 
+    if (threadInfo.timestamps.members[editorID]?.isMember > time) {
+      return {
+        rawMessageInfos,
+        updateInfos: [],
+      };
+    }
+
+    const memberTimestamps = { ...threadInfo.timestamps.members };
+    if (!memberTimestamps[editorID]) {
+      memberTimestamps[editorID] = {
+        isMember: time,
+        subscription: threadInfo.creationTime,
+      };
+    }
+    memberTimestamps[editorID] = {
+      ...memberTimestamps[editorID],
+      isMember: time,
+    };
+    const updatedThreadInfo = {
+      ...threadInfo,
+      members: threadInfo.members.filter(member => member.id !== editorID),
+      timestamps: {
+        ...threadInfo.timestamps,
+        members: memberTimestamps,
+      },
+    };
     return {
       rawMessageInfos,
-      updateInfos,
+      updateInfos: [
+        {
+          type: updateTypes.UPDATE_THREAD,
+          id: uuid.v4(),
+          time,
+          threadInfo: updatedThreadInfo,
+        },
+      ],
     };
   },
   canBeProcessed(