diff --git a/keyserver/src/responders/redux-state-responders.js b/keyserver/src/responders/redux-state-responders.js
--- a/keyserver/src/responders/redux-state-responders.js
+++ b/keyserver/src/responders/redux-state-responders.js
@@ -14,10 +14,7 @@
   parsePendingThreadID,
   createPendingThread,
 } from 'lib/shared/thread-utils.js';
-import {
-  entryStoreValidator,
-  calendarQueryValidator,
-} from 'lib/types/entry-types.js';
+import { entryStoreValidator } from 'lib/types/entry-types.js';
 import { defaultCalendarFilters } from 'lib/types/filter-types.js';
 import { inviteLinksStoreValidator } from 'lib/types/link-types.js';
 import {
@@ -38,7 +35,7 @@
 import { tShape, ashoatKeyserverID } from 'lib/utils/validation-utils.js';
 import { navInfoValidator } from 'web/types/nav-types.js';
 import type {
-  InitialReduxState,
+  InitialReduxStateResponse,
   InitialKeyserverInfo,
 } from 'web/types/redux-types.js';
 import { navInfoFromURL } from 'web/url-utils.js';
@@ -62,17 +59,15 @@
   updatesCurrentAsOf: t.Number,
 });
 
-export const initialReduxStateValidator: TInterface<InitialReduxState> =
-  tShape<InitialReduxState>({
+export const initialReduxStateValidator: TInterface<InitialReduxStateResponse> =
+  tShape<InitialReduxStateResponse>({
     navInfo: navInfoValidator,
     currentUserInfo: currentUserInfoValidator,
     entryStore: entryStoreValidator,
     threadStore: threadStoreValidator,
     userInfos: userInfosValidator,
-    actualizedCalendarQuery: calendarQueryValidator,
     messageStore: messageStoreValidator,
     pushApiPublicKey: t.maybe(t.String),
-    dataLoaded: t.Boolean,
     commServicesAccessToken: t.Nil,
     inviteLinksStore: inviteLinksStoreValidator,
     keyserverInfo: initialKeyserverInfoValidator,
@@ -81,7 +76,7 @@
 async function getInitialReduxStateResponder(
   viewer: Viewer,
   urlInfo: URLInfo,
-): Promise<InitialReduxState> {
+): Promise<InitialReduxStateResponse> {
   const hasNotAcknowledgedPoliciesPromise = hasAnyNotAcknowledgedPolicies(
     viewer.id,
     baseLegalPolicies,
@@ -318,15 +313,13 @@
     };
   })();
 
-  const initialReduxState: InitialReduxState = await promiseAll({
+  const initialReduxState: InitialReduxStateResponse = await promiseAll({
     navInfo: navInfoPromise,
     currentUserInfo: currentUserInfoPromise,
     entryStore: entryStorePromise,
     threadStore: threadStorePromise,
     userInfos: userInfosPromise,
-    actualizedCalendarQuery: calendarQueryPromise,
     messageStore: messageStorePromise,
-    dataLoaded: viewer.loggedIn,
     pushApiPublicKey: pushApiPublicKeyPromise,
     commServicesAccessToken: null,
     inviteLinksStore: inviteLinksStorePromise,
diff --git a/web/redux/action-types.js b/web/redux/action-types.js
--- a/web/redux/action-types.js
+++ b/web/redux/action-types.js
@@ -1,9 +1,17 @@
 // @flow
 
-import type { CallServerEndpoint } from 'lib/utils/call-server-endpoint.js';
+import { defaultCalendarFilters } from 'lib/types/filter-types.js';
+import { extractKeyserverIDFromID } from 'lib/utils/action-utils.js';
+import { useKeyserverCall } from 'lib/utils/keyserver-call.js';
+import type { CallKeyserverEndpoint } from 'lib/utils/keyserver-call.js';
 import type { URLInfo } from 'lib/utils/url-utils.js';
+import { ashoatKeyserverID } from 'lib/utils/validation-utils.js';
 
-import type { InitialReduxState } from '../types/redux-types.js';
+import type {
+  InitialReduxState,
+  InitialReduxStateResponse,
+  InitialKeyserverInfo,
+} from '../types/redux-types.js';
 
 export const updateNavInfoActionType = 'UPDATE_NAV_INFO';
 export const updateWindowDimensionsActionType = 'UPDATE_WINDOW_DIMENSIONS';
@@ -13,28 +21,129 @@
 const getInitialReduxStateCallServerEndpointOptions = { timeout: 300000 };
 const getInitialReduxState =
   (
-    callServerEndpoint: CallServerEndpoint,
-  ): (URLInfo => Promise<InitialReduxState>) =>
+    callKeyserverEndpoint: CallKeyserverEndpoint,
+    allKeyserverIDs: $ReadOnlyArray<string>,
+  ): ((input: URLInfo) => Promise<InitialReduxState>) =>
   async urlInfo => {
-    const response = await callServerEndpoint(
-      'get_initial_redux_state',
-      urlInfo,
-      getInitialReduxStateCallServerEndpointOptions,
-    );
+    const requests = {};
+    const { thread, inviteSecret, ...rest } = urlInfo;
+    const threadKeyserverID = thread ? extractKeyserverIDFromID(thread) : null;
+
+    for (const keyserverID of allKeyserverIDs) {
+      if (keyserverID === threadKeyserverID) {
+        requests[keyserverID] = urlInfo;
+      } else {
+        requests[keyserverID] = rest;
+      }
+    }
+
+    const responses: { +[string]: InitialReduxStateResponse } =
+      await callKeyserverEndpoint(
+        'get_initial_redux_state',
+        requests,
+        getInitialReduxStateCallServerEndpointOptions,
+      );
+
+    const {
+      currentUserInfo,
+      userInfos,
+      pushApiPublicKey,
+      commServicesAccessToken,
+      navInfo,
+    } = responses[ashoatKeyserverID];
+
+    const dataLoaded = currentUserInfo && !currentUserInfo.anonymous;
+    const actualizedCalendarQuery = {
+      startDate: navInfo.startDate,
+      endDate: navInfo.endDate,
+      filters: defaultCalendarFilters,
+    };
+
+    const entryStore = {
+      daysToEntries: {},
+      entryInfos: {},
+      lastUserInteractionCalendar: 0,
+    };
+    const threadStore = {
+      threadInfos: {},
+    };
+    const messageStore = {
+      currentAsOf: {},
+      local: {},
+      messages: {},
+      threads: {},
+    };
+    const inviteLinksStore = {
+      links: {},
+    };
+    let keyserverInfos: { [keyserverID: string]: InitialKeyserverInfo } = {};
+
+    for (const keyserverID in responses) {
+      entryStore.daysToEntries = {
+        ...entryStore.daysToEntries,
+        ...responses[keyserverID].entryStore.daysToEntries,
+      };
+      entryStore.entryInfos = {
+        ...entryStore.entryInfos,
+        ...responses[keyserverID].entryStore.entryInfos,
+      };
+      entryStore.lastUserInteractionCalendar = Math.max(
+        entryStore.lastUserInteractionCalendar,
+        responses[keyserverID].entryStore.lastUserInteractionCalendar,
+      );
+
+      threadStore.threadInfos = {
+        ...threadStore.threadInfos,
+        ...responses[keyserverID].threadStore.threadInfos,
+      };
+
+      messageStore.currentAsOf = {
+        ...messageStore.currentAsOf,
+        ...responses[keyserverID].messageStore.currentAsOf,
+      };
+      messageStore.messages = {
+        ...messageStore.messages,
+        ...responses[keyserverID].messageStore.messages,
+      };
+      messageStore.threads = {
+        ...messageStore.threads,
+        ...responses[keyserverID].messageStore.threads,
+      };
+
+      inviteLinksStore.links = {
+        ...inviteLinksStore.links,
+        ...responses[keyserverID].inviteLinksStore.links,
+      };
+
+      keyserverInfos = {
+        ...keyserverInfos,
+        [keyserverID]: responses[keyserverID].keyserverInfo,
+      };
+    }
+
     return {
-      navInfo: response.navInfo,
-      currentUserInfo: response.currentUserInfo,
-      entryStore: response.entryStore,
-      threadStore: response.threadStore,
-      userInfos: response.userInfos,
-      actualizedCalendarQuery: response.actualizedCalendarQuery,
-      messageStore: response.messageStore,
-      dataLoaded: response.dataLoaded,
-      pushApiPublicKey: response.pushApiPublicKey,
-      commServicesAccessToken: response.commServicesAccessToken,
-      inviteLinksStore: response.inviteLinksStore,
-      keyserverInfo: response.keyserverInfo,
+      navInfo: {
+        ...navInfo,
+        inviteSecret,
+      },
+      currentUserInfo,
+      entryStore,
+      threadStore,
+      userInfos,
+      actualizedCalendarQuery,
+      messageStore,
+      dataLoaded,
+      pushApiPublicKey,
+      commServicesAccessToken,
+      inviteLinksStore,
+      keyserverInfos,
     };
   };
 
-export { getInitialReduxState };
+function useGetInitialReduxState(): (
+  input: URLInfo,
+) => Promise<InitialReduxState> {
+  return useKeyserverCall(getInitialReduxState);
+}
+
+export { useGetInitialReduxState };
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
@@ -5,12 +5,14 @@
 import { PersistGate } from 'redux-persist/es/integration/react.js';
 import type { Persistor } from 'redux-persist/es/types';
 
-import { useServerCall } from 'lib/utils/action-utils.js';
 import { convertIDToNewSchema } from 'lib/utils/migration-utils.js';
 import { infoFromURL } from 'lib/utils/url-utils.js';
 import { ashoatKeyserverID } from 'lib/utils/validation-utils.js';
 
-import { getInitialReduxState, setInitialReduxState } from './action-types.js';
+import {
+  setInitialReduxState,
+  useGetInitialReduxState,
+} from './action-types.js';
 import { useSelector } from './redux-utils.js';
 import Loading from '../loading.react.js';
 
@@ -20,7 +22,7 @@
 };
 function InitialReduxStateGate(props: Props): React.Node {
   const { children, persistor } = props;
-  const callGetInitialReduxState = useServerCall(getInitialReduxState);
+  const callGetInitialReduxState = useGetInitialReduxState();
   const dispatch = useDispatch();
 
   const [initError, setInitError] = React.useState<?Error>(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
@@ -124,20 +124,21 @@
   let state = oldState;
 
   if (action.type === setInitialReduxState) {
-    const { userInfos, keyserverInfo, ...rest } = action.payload;
+    const { userInfos, keyserverInfos, ...rest } = action.payload;
+    const newKeyserverInfos = { ...state.keyserverStore.keyserverInfos };
+    for (const keyserverID in keyserverInfos) {
+      newKeyserverInfos[keyserverID] = {
+        ...newKeyserverInfos[keyserverID],
+        ...keyserverInfos[keyserverID],
+      };
+    }
     return validateState(oldState, {
       ...state,
       ...rest,
       userStore: { userInfos },
       keyserverStore: {
         ...state.keyserverStore,
-        keyserverInfos: {
-          ...state.keyserverStore.keyserverInfos,
-          [ashoatKeyserverID]: {
-            ...state.keyserverStore.keyserverInfos[ashoatKeyserverID],
-            ...keyserverInfo,
-          },
-        },
+        keyserverInfos: newKeyserverInfos,
       },
       initialStateLoaded: true,
     });
diff --git a/web/types/redux-types.js b/web/types/redux-types.js
--- a/web/types/redux-types.js
+++ b/web/types/redux-types.js
@@ -8,21 +8,34 @@
 
 import type { NavInfo } from '../types/nav-types.js';
 
-export type InitialReduxState = {
+export type InitialReduxStateResponse = {
   +navInfo: NavInfo,
   +currentUserInfo: CurrentUserInfo,
   +entryStore: EntryStore,
   +threadStore: ThreadStore,
   +userInfos: UserInfos,
-  +actualizedCalendarQuery: CalendarQuery,
   +messageStore: MessageStore,
-  +dataLoaded: boolean,
   +pushApiPublicKey: ?string,
   +commServicesAccessToken: null,
   +inviteLinksStore: InviteLinksStore,
   +keyserverInfo: InitialKeyserverInfo,
 };
 
+export type InitialReduxState = {
+  +navInfo: NavInfo,
+  +currentUserInfo: CurrentUserInfo,
+  +entryStore: EntryStore,
+  +threadStore: ThreadStore,
+  +userInfos: UserInfos,
+  +messageStore: MessageStore,
+  +pushApiPublicKey: ?string,
+  +commServicesAccessToken: null,
+  +inviteLinksStore: InviteLinksStore,
+  +dataLoaded: boolean,
+  +actualizedCalendarQuery: CalendarQuery,
+  +keyserverInfos: { +[keyserverID: string]: InitialKeyserverInfo },
+};
+
 export type InitialKeyserverInfo = {
   +sessionID: ?string,
   +updatesCurrentAsOf: number,