diff --git a/lib/reducers/local-id-reducer.js b/lib/reducers/local-id-reducer.js
deleted file mode 100644
--- a/lib/reducers/local-id-reducer.js
+++ /dev/null
@@ -1,119 +0,0 @@
-// @flow
-
-import invariant from 'invariant';
-
-import { createLocalEntryActionType } from '../actions/entry-actions.js';
-import {
-  sendTextMessageActionTypes,
-  sendMultimediaMessageActionTypes,
-  createLocalMessageActionType,
-  processMessagesActionType,
-  fetchMessagesBeforeCursorActionTypes,
-  fetchMostRecentMessagesActionTypes,
-  sendReactionMessageActionTypes,
-} from '../actions/message-actions.js';
-import { joinThreadActionTypes } from '../actions/thread-actions.js';
-import {
-  numberFromLocalID,
-  highestLocalIDSelector,
-} from '../selectors/local-id-selectors.js';
-import { updateSpecs } from '../shared/updates/update-specs.js';
-import type { RawMessageInfo } from '../types/message-types.js';
-import type { BaseAction } from '../types/redux-types.js';
-import { rehydrateActionType } from '../types/redux-types.js';
-import {
-  fullStateSyncActionType,
-  incrementalStateSyncActionType,
-} from '../types/socket-types.js';
-import {
-  type ClientUpdateInfo,
-  processUpdatesActionType,
-} from '../types/update-types.js';
-
-export default function reduceNextLocalID(
-  state: number,
-  action: BaseAction,
-): number {
-  let newCandidate = null;
-  if (action.type === rehydrateActionType) {
-    newCandidate = highestLocalIDSelector(action.payload) + 1;
-    if (
-      action.payload &&
-      action.payload.nextLocalID &&
-      action.payload.nextLocalID > newCandidate
-    ) {
-      newCandidate = action.payload.nextLocalID;
-    }
-  } else if (
-    action.type === sendTextMessageActionTypes.started ||
-    action.type === sendMultimediaMessageActionTypes.started ||
-    action.type === sendReactionMessageActionTypes.started ||
-    action.type === createLocalEntryActionType ||
-    action.type === createLocalMessageActionType
-  ) {
-    const { localID } = action.payload;
-    invariant(localID, 'should be set');
-    newCandidate = numberFromLocalID(localID) + 1;
-  } else if (action.type === incrementalStateSyncActionType) {
-    const messages = [
-      ...action.payload.messagesResult.rawMessageInfos,
-      ...getRawMessageInfosFromUpdates(action.payload.updatesResult.newUpdates),
-    ];
-    newCandidate = findHighestLocalID(messages) + 1;
-  } else if (action.type === processUpdatesActionType) {
-    const messages = getRawMessageInfosFromUpdates(
-      action.payload.updatesResult.newUpdates,
-    );
-    newCandidate = findHighestLocalID(messages) + 1;
-  } else if (
-    action.type === fullStateSyncActionType ||
-    action.type === processMessagesActionType
-  ) {
-    const messages = action.payload.messagesResult.rawMessageInfos;
-    newCandidate = findHighestLocalID(messages) + 1;
-  } else if (
-    action.type === fetchMessagesBeforeCursorActionTypes.success ||
-    action.type === fetchMostRecentMessagesActionTypes.success
-  ) {
-    const messages = action.payload.rawMessageInfos;
-    newCandidate = findHighestLocalID(messages) + 1;
-  } else if (action.type === joinThreadActionTypes.success) {
-    const messages = [
-      ...action.payload.rawMessageInfos,
-      ...getRawMessageInfosFromUpdates(action.payload.updatesResult.newUpdates),
-    ];
-    newCandidate = findHighestLocalID(messages) + 1;
-  }
-  return newCandidate && newCandidate > state ? newCandidate : state;
-}
-
-function findHighestLocalID(
-  rawMessageInfos: $ReadOnlyArray<RawMessageInfo>,
-): number {
-  let oldestID = -1;
-
-  for (const rawMessageInfo of rawMessageInfos) {
-    if (!rawMessageInfo.localID) {
-      continue;
-    }
-    const { localID } = rawMessageInfo;
-    if (!localID) {
-      continue;
-    }
-    const thisLocalID = numberFromLocalID(localID);
-    if (thisLocalID > oldestID) {
-      oldestID = thisLocalID;
-    }
-  }
-
-  return oldestID;
-}
-
-function getRawMessageInfosFromUpdates(
-  updates: $ReadOnlyArray<ClientUpdateInfo>,
-): RawMessageInfo[] {
-  return updates
-    .map(update => updateSpecs[update.type].getRawMessageInfos?.(update))
-    .filter(Boolean)
-    .flat();
-}
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
@@ -14,7 +14,6 @@
 import reduceKeyserverStore from './keyserver-reducer.js';
 import reduceLifecycleState from './lifecycle-state-reducer.js';
 import { reduceLoadingStatuses } from './loading-reducer.js';
-import reduceNextLocalID from './local-id-reducer.js';
 import { reduceMessageStore } from './message-reducer.js';
 import reduceBaseNavInfo from './nav-reducer.js';
 import { reduceNotifPermissionAlertInfo } from './notif-permission-alert-info-reducer.js';
@@ -205,7 +204,6 @@
       lifecycleState: reduceLifecycleState(state.lifecycleState, action),
       enabledApps: reduceEnabledApps(state.enabledApps, action),
       reportStore,
-      nextLocalID: reduceNextLocalID(state.nextLocalID, action),
       dataLoaded: reduceDataLoaded(state.dataLoaded, action),
       userPolicies: policiesReducer(state.userPolicies, action),
       commServicesAccessToken: reduceServicesAccessToken(
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
@@ -155,7 +155,6 @@
   +lifecycleState: LifecycleState,
   +enabledApps: EnabledApps,
   +reportStore: ReportStore,
-  +nextLocalID: number,
   +dataLoaded: boolean,
   +userPolicies: UserPolicies,
   +commServicesAccessToken: ?string,
diff --git a/lib/utils/reducers-utils.test.js b/lib/utils/reducers-utils.test.js
--- a/lib/utils/reducers-utils.test.js
+++ b/lib/utils/reducers-utils.test.js
@@ -58,7 +58,6 @@
         },
         queuedReports: [],
       },
-      nextLocalID: 0,
       _persist: null,
       userPolicies: {},
       commServicesAccessToken: null,
@@ -102,7 +101,6 @@
         systemTheme: null,
       },
       communityPickerStore: { chat: '256|1', calendar: '256|1' },
-      nextLocalID: 9,
       navInfo: {
         activeChatThreadID: null,
         startDate: '2023-02-02',
@@ -115,7 +113,6 @@
     const nonUserSpecificFields = [
       'globalThemeInfo',
       'communityPickerStore',
-      'nextLocalID',
       'navInfo',
     ];
 
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
@@ -55,7 +55,6 @@
     },
     queuedReports: [],
   },
-  nextLocalID: 0,
   _persist: null,
   dimensions: defaultDimensionsInfo,
   connectivity: defaultConnectivityInfo,
diff --git a/native/redux/persist.js b/native/redux/persist.js
--- a/native/redux/persist.js
+++ b/native/redux/persist.js
@@ -1199,6 +1199,10 @@
 
     return state;
   },
+  [67]: (state: any) => {
+    const { nextLocalID, ...rest } = state;
+    return rest;
+  },
 };
 
 // After migration 31, we'll no longer want to persist `messageStore.messages`
@@ -1266,7 +1270,7 @@
   storage: AsyncStorage,
   blacklist: persistBlacklist,
   debug: __DEV__,
-  version: 66,
+  version: 67,
   transforms: [
     messageStoreMessagesBlocklistTransform,
     reportStoreTransform,
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
@@ -36,7 +36,6 @@
   'loadingStatuses',
   'customServer',
   'lifecycleState',
-  'nextLocalID',
   'dimensions',
   'connectivity',
   'deviceCameraInfo',
@@ -64,7 +63,6 @@
   +lifecycleState: LifecycleState,
   +enabledApps: EnabledApps,
   +reportStore: ReportStore,
-  +nextLocalID: number,
   +_persist: ?PersistState,
   +dimensions: DimensionsInfo,
   +connectivity: ConnectivityInfo,
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
@@ -56,7 +56,6 @@
     },
     queuedReports: [],
   },
-  nextLocalID: 0,
   _persist: null,
   userPolicies: {},
   commServicesAccessToken: null,
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
@@ -82,7 +82,6 @@
   'loadingStatuses',
   'windowDimensions',
   'lifecycleState',
-  'nextLocalID',
   'windowActive',
   'pushApiPublicKey',
   'keyserverStore',
@@ -108,7 +107,6 @@
   +lifecycleState: LifecycleState,
   +enabledApps: EnabledApps,
   +reportStore: ReportStore,
-  +nextLocalID: number,
   +dataLoaded: boolean,
   +windowActive: boolean,
   +userPolicies: UserPolicies,