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
@@ -8,6 +8,7 @@
   logInActionTypes,
   keyserverRegisterActionTypes,
 } from '../actions/user-actions.js';
+import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js';
 import type { ThreadStoreOperation } from '../ops/thread-store-ops';
 import type { IntegrityStore } from '../types/integrity-types';
 import type { RawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
@@ -23,11 +24,16 @@
   },
   threadStoreOperations: $ReadOnlyArray<ThreadStoreOperation>,
 ): IntegrityStore {
-  if (
+  if (action.type === fullStateSyncActionType) {
+    const threadHashesArray = Object.entries(state.threadHashes).filter(
+      ([key]) => extractKeyserverIDFromID(key) !== action.payload.keyserverID,
+    );
+    const threadHashes = Object.fromEntries(threadHashesArray);
+    return { threadHashes, threadHashingStatus: 'starting' };
+  } else if (
     action.type === logInActionTypes.success ||
     action.type === siweAuthActionTypes.success ||
     action.type === keyserverRegisterActionTypes.success ||
-    action.type === fullStateSyncActionType ||
     (action.type === setClientDBStoreActionType &&
       !!action.payload.threadStore &&
       state.threadHashingStatus !== 'completed')
diff --git a/lib/reducers/thread-reducer.js b/lib/reducers/thread-reducer.js
--- a/lib/reducers/thread-reducer.js
+++ b/lib/reducers/thread-reducer.js
@@ -25,7 +25,10 @@
   keyserverRegisterActionTypes,
   updateSubscriptionActionTypes,
 } from '../actions/user-actions.js';
-import { getThreadIDsForKeyservers } from '../keyserver-conn/keyserver-call-utils.js';
+import {
+  getThreadIDsForKeyservers,
+  extractKeyserverIDFromID,
+} from '../keyserver-conn/keyserver-call-utils.js';
 import { setNewSessionActionType } from '../keyserver-conn/keyserver-conn-types.js';
 import {
   type ThreadStoreOperation,
@@ -79,11 +82,34 @@
   newThreadInconsistencies: $ReadOnlyArray<ClientThreadInconsistencyReportCreationRequest>,
   threadStoreOperations: $ReadOnlyArray<ThreadStoreOperation>,
 } {
-  if (
+  if (action.type === fullStateSyncActionType) {
+    const threadsToRemove = Object.keys(state.threadInfos).filter(
+      key => extractKeyserverIDFromID(key) === action.payload.keyserverID,
+    );
+    const newThreadInfos = action.payload.threadInfos;
+    const threadStoreOperations = [
+      {
+        type: 'remove',
+        payload: { ids: threadsToRemove },
+      },
+      ...Object.keys(newThreadInfos).map((id: string) => ({
+        type: 'replace',
+        payload: { id, threadInfo: newThreadInfos[id] },
+      })),
+    ];
+    const updatedThreadStore = processThreadStoreOperations(
+      state,
+      threadStoreOperations,
+    );
+    return {
+      threadStore: updatedThreadStore,
+      newThreadInconsistencies: [],
+      threadStoreOperations,
+    };
+  } else if (
     action.type === logInActionTypes.success ||
     action.type === siweAuthActionTypes.success ||
-    action.type === keyserverRegisterActionTypes.success ||
-    action.type === fullStateSyncActionType
+    action.type === keyserverRegisterActionTypes.success
   ) {
     const newThreadInfos = action.payload.threadInfos;
     const threadStoreOperations = [
diff --git a/lib/reducers/user-reducer.js b/lib/reducers/user-reducer.js
--- a/lib/reducers/user-reducer.js
+++ b/lib/reducers/user-reducer.js
@@ -104,7 +104,13 @@
     if (!_isEqual(sessionChange.currentUserInfo)(state)) {
       return sessionChange.currentUserInfo;
     }
-  } else if (action.type === fullStateSyncActionType) {
+  } else if (
+    action.type === fullStateSyncActionType &&
+    relyingOnAuthoritativeKeyserver
+  ) {
+    if (action.payload.keyserverID !== authoritativeKeyserverID()) {
+      return state;
+    }
     const { currentUserInfo } = action.payload;
     if (!_isEqual(currentUserInfo)(state)) {
       return currentUserInfo;
@@ -273,11 +279,12 @@
       userStoreOps,
     ];
   } else if (
-    action.type === logInActionTypes.success ||
-    action.type === siweAuthActionTypes.success ||
-    action.type === keyserverRegisterActionTypes.success ||
-    action.type === fullStateSyncActionType
+    action.type === fullStateSyncActionType &&
+    relyingOnAuthoritativeKeyserver
   ) {
+    if (action.payload.keyserverID !== authoritativeKeyserverID()) {
+      return [state, [], []];
+    }
     const newUserInfos = _keyBy(userInfo => userInfo.id)(
       action.payload.userInfos,
     );
@@ -295,12 +302,7 @@
       action.type,
       onStateDifference,
     );
-    if (
-      action.type === logInActionTypes.success ||
-      action.type === siweAuthActionTypes.success ||
-      action.type === keyserverRegisterActionTypes.success ||
-      !_isEqual(state.userInfos)(newUserInfos)
-    ) {
+    if (!_isEqual(state.userInfos)(newUserInfos)) {
       return [
         {
           userInfos: newUserInfos,
@@ -309,6 +311,36 @@
         userStoreOps,
       ];
     }
+  } else if (
+    action.type === logInActionTypes.success ||
+    action.type === siweAuthActionTypes.success ||
+    action.type === keyserverRegisterActionTypes.success
+  ) {
+    const newUserInfos = _keyBy(userInfo => userInfo.id)(
+      action.payload.userInfos,
+    );
+    const userStoreOps: $ReadOnlyArray<UserStoreOperation> = [
+      { type: 'remove_all_users' },
+      ...convertUserInfosToReplaceUserOps(newUserInfos),
+    ];
+    const processedUserInfos: UserInfos = processUserStoreOps(
+      state.userInfos,
+      userStoreOps,
+    );
+    assertUserStoresAreEqual(
+      processedUserInfos,
+      newUserInfos,
+      action.type,
+      onStateDifference,
+    );
+
+    return [
+      {
+        userInfos: newUserInfos,
+      },
+      [],
+      userStoreOps,
+    ];
   } else if (action.type === keyserverAuthActionTypes.success) {
     const newUserInfos = _keyBy(userInfo => userInfo.id)(
       action.payload.userInfos,