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
@@ -18,6 +18,7 @@
 import policiesReducer from './policies-reducer.js';
 import reduceReportStore from './report-store-reducer.js';
 import reduceServicesAccessToken from './services-access-token-reducer.js';
+import { reduceThreadActivity } from './thread-activity-reducer.js';
 import { reduceThreadInfos } from './thread-reducer.js';
 import { reduceCurrentUserInfo, reduceUserInfos } from './user-reducer.js';
 import { siweAuthActionTypes } from '../actions/siwe-actions.js';
@@ -145,6 +146,10 @@
       ),
       inviteLinksStore: reduceInviteLinks(state.inviteLinksStore, action),
       keyserverStore,
+      threadActivityStore: reduceThreadActivity(
+        state.threadActivityStore,
+        action,
+      ),
     },
     storeOperations: {
       draftStoreOperations,
diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js
--- a/lib/reducers/message-reducer.js
+++ b/lib/reducers/message-reducer.js
@@ -92,6 +92,7 @@
   fullStateSyncActionType,
   incrementalStateSyncActionType,
 } from '../types/socket-types.js';
+import { updateThreadLastNavigatedActionType } from '../types/thread-activity-types.js';
 import { threadPermissions } from '../types/thread-permission-types.js';
 import { type RawThreadInfo } from '../types/thread-types.js';
 import { updateTypes } from '../types/update-types-enum.js';
@@ -1738,6 +1739,32 @@
       messageStoreOperations,
       messageStore: processedMessageStore,
     };
+  } else if (action.type === updateThreadLastNavigatedActionType) {
+    const { threadID, time } = action.payload;
+    if (!messageStore.threads[threadID]) {
+      return { messageStoreOperations: [], messageStore };
+    }
+
+    const updatedThreads = {
+      [threadID]: {
+        ...messageStore.threads[threadID],
+        lastNavigatedTo: time,
+      },
+    };
+
+    const messageStoreOperations = [
+      {
+        type: 'replace_threads',
+        payload: { threads: updatedThreads },
+      },
+    ];
+
+    const processedMessageStore = processMessageStoreOperations(
+      messageStore,
+      messageStoreOperations,
+    );
+
+    return { messageStoreOperations, messageStore: processedMessageStore };
   }
   return { messageStoreOperations: [], messageStore };
 }
diff --git a/lib/reducers/thread-activity-reducer.js b/lib/reducers/thread-activity-reducer.js
new file mode 100644
--- /dev/null
+++ b/lib/reducers/thread-activity-reducer.js
@@ -0,0 +1,37 @@
+// @flow
+
+import {
+  logOutActionTypes,
+  deleteAccountActionTypes,
+} from '../actions/user-actions.js';
+import type { BaseAction } from '../types/redux-types.js';
+import type { ThreadActivityStore } from '../types/thread-activity-types.js';
+import { updateThreadLastNavigatedActionType } from '../types/thread-activity-types.js';
+import { setNewSessionActionType } from '../utils/action-utils.js';
+
+function reduceThreadActivity(
+  state: ThreadActivityStore,
+  action: BaseAction,
+): ThreadActivityStore {
+  if (action.type === updateThreadLastNavigatedActionType) {
+    const { threadID, time } = action.payload;
+    const updatedThreadActivityStore = {
+      ...state,
+      [threadID]: {
+        ...state[threadID],
+        lastNavigatedTo: time,
+      },
+    };
+    return updatedThreadActivityStore;
+  } else if (
+    action.type === logOutActionTypes.success ||
+    action.type === deleteAccountActionTypes.success ||
+    (action.type === setNewSessionActionType &&
+      action.payload.sessionChange.cookieInvalidated)
+  ) {
+    return {};
+  }
+  return state;
+}
+
+export { reduceThreadActivity };
diff --git a/lib/reducers/thread-activity-reducer.test.js b/lib/reducers/thread-activity-reducer.test.js
new file mode 100644
--- /dev/null
+++ b/lib/reducers/thread-activity-reducer.test.js
@@ -0,0 +1,69 @@
+// @flow
+
+import { reduceThreadActivity } from './thread-activity-reducer.js';
+import { updateThreadLastNavigatedActionType } from '../types/thread-activity-types.js';
+
+// NOTE: These unit tests were generated by GitHub Copilot.
+
+describe('reduceThreadActivity', () => {
+  test('updates the lastNavigatedTo time for a thread', () => {
+    const initialState = {
+      thread1: {
+        lastNavigatedTo: 1639522314170,
+        lastPruned: 1639522314170,
+      },
+      thread2: {
+        lastNavigatedTo: 1639522314170,
+        lastPruned: 1639522314170,
+      },
+    };
+    const action = {
+      type: updateThreadLastNavigatedActionType,
+      payload: {
+        threadID: 'thread1',
+        time: 1639522317443,
+      },
+    };
+    const expectedState = {
+      thread1: {
+        lastNavigatedTo: 1639522317443,
+        lastPruned: 1639522314170,
+      },
+      thread2: {
+        lastNavigatedTo: 1639522314170,
+        lastPruned: 1639522314170,
+      },
+    };
+    const result = reduceThreadActivity(initialState, action);
+    expect(result).toEqual(expectedState);
+  });
+
+  test('returns the initial state if the action type is not recognized', () => {
+    const initialState = {
+      thread1: {
+        lastNavigatedTo: 1639522314170,
+        lastPruned: 1639522314170,
+      },
+      thread2: {
+        lastNavigatedTo: 1639522314170,
+        lastPruned: 1639522314170,
+      },
+    };
+    const action = {
+      type: 'UPDATE_REPORTS_ENABLED',
+      payload: {},
+    };
+    const expectedState = {
+      thread1: {
+        lastNavigatedTo: 1639522314170,
+        lastPruned: 1639522314170,
+      },
+      thread2: {
+        lastNavigatedTo: 1639522314170,
+        lastPruned: 1639522314170,
+      },
+    };
+    const result = reduceThreadActivity(initialState, action);
+    expect(result).toEqual(expectedState);
+  });
+});
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -99,6 +99,7 @@
   UpdateDisconnectedBarPayload,
 } from './socket-types.js';
 import type { SubscriptionUpdateResult } from './subscription-types.js';
+import type { ThreadActivityStore } from './thread-activity-types.js';
 import type {
   ThreadStore,
   ChangeThreadSettingsPayload,
@@ -137,6 +138,7 @@
   +commServicesAccessToken: ?string,
   +inviteLinksStore: InviteLinksStore,
   +keyserverStore: KeyserverStore,
+  +threadActivityStore: ThreadActivityStore,
   ...
 };
 
@@ -1211,6 +1213,10 @@
   | {
       +type: 'SET_ACCESS_TOKEN',
       +payload: string,
+    }
+  | {
+      +type: 'UPDATE_THREAD_LAST_NAVIGATED',
+      +payload: { +threadID: string, +time: number },
     };
 
 export type ActionPayload = ?(Object | Array<*> | $ReadOnlyArray<*> | string);
diff --git a/lib/types/thread-activity-types.js b/lib/types/thread-activity-types.js
new file mode 100644
--- /dev/null
+++ b/lib/types/thread-activity-types.js
@@ -0,0 +1,12 @@
+// @flow
+
+export const updateThreadLastNavigatedActionType =
+  'UPDATE_THREAD_LAST_NAVIGATED';
+
+export type ThreadActivityStoreEntry = {
+  +lastNavigatedTo: number, // millisecond timestamp
+  +lastPruned: number, // millisecond timestamp
+};
+export type ThreadActivityStore = {
+  +[threadID: string]: ThreadActivityStoreEntry,
+};
diff --git a/native/navigation/thread-screen-tracker.react.js b/native/navigation/thread-screen-tracker.react.js
--- a/native/navigation/thread-screen-tracker.react.js
+++ b/native/navigation/thread-screen-tracker.react.js
@@ -3,8 +3,9 @@
 import * as React from 'react';
 import { useDispatch } from 'react-redux';
 
+import { updateThreadLastNavigatedActionType } from 'lib/types/thread-activity-types.js';
+
 import { useActiveMessageList } from './nav-selectors.js';
-import { updateThreadLastNavigatedActionType } from '../redux/action-types.js';
 
 const ThreadScreenTracker: React.ComponentType<{}> = React.memo<{}>(
   function ThreadScreenTracker() {
diff --git a/native/redux/action-types.js b/native/redux/action-types.js
--- a/native/redux/action-types.js
+++ b/native/redux/action-types.js
@@ -18,8 +18,6 @@
 export const updateThemeInfoActionType = 'UPDATE_THEME_INFO';
 export const updateDeviceCameraInfoActionType = 'UPDATE_DEVICE_CAMERA_INFO';
 export const updateDeviceOrientationActionType = 'UPDATE_DEVICE_ORIENTATION';
-export const updateThreadLastNavigatedActionType =
-  'UPDATE_THREAD_LAST_NAVIGATED';
 export const setStoreLoadedActionType = 'SET_STORE_LOADED';
 export const setReduxStateActionType = 'SET_REDUX_STATE';
 export const setLocalSettingsActionType = 'SET_LOCAL_SETTINGS';
diff --git a/native/redux/default-state.js b/native/redux/default-state.js
--- a/native/redux/default-state.js
+++ b/native/redux/default-state.js
@@ -85,6 +85,7 @@
   localSettings: {
     isBackupEnabled: false,
   },
+  threadActivityStore: {},
 }: AppState);
 
 export { defaultState };
diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js
--- a/native/redux/redux-setup.js
+++ b/native/redux/redux-setup.js
@@ -32,7 +32,6 @@
   updateThemeInfoActionType,
   updateDeviceCameraInfoActionType,
   updateDeviceOrientationActionType,
-  updateThreadLastNavigatedActionType,
   backgroundActionTypes,
   setReduxStateActionType,
   setStoreLoadedActionType,
@@ -183,42 +182,6 @@
       ...state,
       deviceOrientation: action.payload,
     };
-  } else if (action.type === updateThreadLastNavigatedActionType) {
-    const { threadID, time } = action.payload;
-    if (state.messageStore.threads[threadID]) {
-      const updatedThreads = {
-        [threadID]: {
-          ...state.messageStore.threads[threadID],
-          lastNavigatedTo: time,
-        },
-      };
-
-      state = {
-        ...state,
-        messageStore: {
-          ...state.messageStore,
-          threads: {
-            ...state.messageStore.threads,
-            ...updatedThreads,
-          },
-        },
-      };
-
-      processDBStoreOperations({
-        draftStoreOperations: [],
-        messageStoreOperations: [
-          {
-            type: 'replace_threads',
-            payload: {
-              threads: updatedThreads,
-            },
-          },
-        ],
-        threadStoreOperations: [],
-        reportStoreOperations: [],
-      });
-    }
-    return state;
   } else if (action.type === setLocalSettingsActionType) {
     return {
       ...state,
diff --git a/native/redux/state-types.js b/native/redux/state-types.js
--- a/native/redux/state-types.js
+++ b/native/redux/state-types.js
@@ -14,6 +14,7 @@
 import type { MessageStore } from 'lib/types/message-types.js';
 import type { UserPolicies } from 'lib/types/policy-types.js';
 import type { ReportStore } from 'lib/types/report-types.js';
+import type { ThreadActivityStore } from 'lib/types/thread-activity-types';
 import type { ThreadStore } from 'lib/types/thread-types.js';
 import type { CurrentUserInfo, UserStore } from 'lib/types/user-types.js';
 import type { NotifPermissionAlertInfo } from 'lib/utils/push-alerts.js';
@@ -57,5 +58,6 @@
   +commServicesAccessToken: ?string,
   +inviteLinksStore: InviteLinksStore,
   +keyserverStore: KeyserverStore,
+  +threadActivityStore: ThreadActivityStore,
   +localSettings: LocalSettings,
 };
diff --git a/web/redux/default-state.js b/web/redux/default-state.js
--- a/web/redux/default-state.js
+++ b/web/redux/default-state.js
@@ -87,6 +87,7 @@
       },
     },
   },
+  threadActivityStore: {},
   initialStateLoaded: false,
 });
 
diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js
--- a/web/redux/redux-setup.js
+++ b/web/redux/redux-setup.js
@@ -30,6 +30,7 @@
 import type { UserPolicies } from 'lib/types/policy-types.js';
 import type { BaseAction } from 'lib/types/redux-types.js';
 import type { ReportStore } from 'lib/types/report-types.js';
+import type { ThreadActivityStore } from 'lib/types/thread-activity-types';
 import type { ThreadStore } from 'lib/types/thread-types.js';
 import type { CurrentUserInfo, UserStore } from 'lib/types/user-types.js';
 import { setNewSessionActionType } from 'lib/utils/action-utils.js';
@@ -97,6 +98,7 @@
   +commServicesAccessToken: ?string,
   +inviteLinksStore: InviteLinksStore,
   +keyserverStore: KeyserverStore,
+  +threadActivityStore: ThreadActivityStore,
   +initialStateLoaded: boolean,
 };