diff --git a/flow-typed/sync.js b/flow-typed/sync.js
index b30603340..cd0a323ef 100644
--- a/flow-typed/sync.js
+++ b/flow-typed/sync.js
@@ -11,6 +11,7 @@ declare type SyncState = {
   setSyncIsPending: boolean,
   prefsReady: boolean,
   syncLocked: boolean,
+  sharedStateSyncId: number,
   hashChanged: boolean,
   fatalError: boolean,
 };
diff --git a/ui/constants/action_types.js b/ui/constants/action_types.js
index 148175c6d..4f029e169 100644
--- a/ui/constants/action_types.js
+++ b/ui/constants/action_types.js
@@ -451,6 +451,7 @@ export const SYNC_APPLY_BAD_PASSWORD = 'SYNC_APPLY_BAD_PASSWORD';
 export const SYNC_RESET = 'SYNC_RESET';
 export const SYNC_FATAL_ERROR = 'SYNC_FATAL_ERROR';
 export const USER_STATE_POPULATE = 'USER_STATE_POPULATE';
+export const SHARED_STATE_SYNC_ID_CHANGED = 'SHARED_STATE_SYNC_ID_CHANGED';
 
 export const REACTIONS_LIST_STARTED = 'REACTIONS_LIST_STARTED';
 export const REACTIONS_LIST_FAILED = 'REACTIONS_LIST_FAILED';
diff --git a/ui/redux/actions/app.js b/ui/redux/actions/app.js
index 61da1cdf8..44afb1ee8 100644
--- a/ui/redux/actions/app.js
+++ b/ui/redux/actions/app.js
@@ -42,7 +42,7 @@ import {
 } from 'redux/selectors/app';
 import { selectDaemonSettings, selectClientSetting } from 'redux/selectors/settings';
 import { selectUser, selectUserVerifiedEmail } from 'redux/selectors/user';
-import { doSetPrefsReady, doPreferenceGet, doPopulateSharedUserState } from 'redux/actions/sync';
+import { doSetPrefsReady, doPreferenceGet, doPopulateSharedUserState, syncInvalidated } from 'redux/actions/sync';
 import { doAuthenticate } from 'redux/actions/user';
 import { lbrySettings as config, version as appVersion } from 'package.json';
 import analytics, { SHARE_INTERNAL } from 'analytics';
@@ -596,7 +596,7 @@ export function doToggle3PAnalytics(allowParam, doNotDispatch) {
   };
 }
 
-export function doGetAndPopulatePreferences() {
+export function doGetAndPopulatePreferences(syncId /* ?: number */) {
   const { SDK_SYNC_KEYS } = SHARED_PREFERENCES;
 
   return (dispatch, getState) => {
@@ -615,7 +615,10 @@ export function doGetAndPopulatePreferences() {
       const successState = getState();
       const daemonSettings = selectDaemonSettings(successState);
       if (savedPreferences !== null) {
-        dispatch(doPopulateSharedUserState(savedPreferences));
+        if (!syncInvalidated(getState, syncId)) {
+          dispatch(doPopulateSharedUserState(savedPreferences));
+        }
+
         // @if TARGET='app'
 
         const { settings } = savedPreferences.value;
@@ -660,11 +663,15 @@ export function doGetAndPopulatePreferences() {
   };
 }
 
-export function doHandleSyncComplete(error, hasNewData) {
-  return (dispatch) => {
+export function doHandleSyncComplete(error, hasNewData, syncId) {
+  return (dispatch, getState) => {
     if (!error) {
       if (hasNewData) {
-        dispatch(doGetAndPopulatePreferences());
+        if (syncInvalidated(getState, syncId)) {
+          return;
+        }
+
+        dispatch(doGetAndPopulatePreferences(syncId));
         // we just got sync data, better update our channels
         dispatch(doFetchChannelListMine());
       }
diff --git a/ui/redux/actions/sync.js b/ui/redux/actions/sync.js
index aa76f22a7..727cffcac 100644
--- a/ui/redux/actions/sync.js
+++ b/ui/redux/actions/sync.js
@@ -21,6 +21,19 @@ const SYNC_INTERVAL = 1000 * 60 * 5; // 5 minutes
 const NO_WALLET_ERROR = 'no wallet found for this user';
 const BAD_PASSWORD_ERROR_NAME = 'InvalidPasswordError';
 
+/**
+ * Checks if there is a newer sync session, indicating that fetched data from
+ * the current one can be dropped.
+ *
+ * @param getState
+ * @param syncId [Optional] The id of the current sync session. If not given, assume not invalidated.
+ * @returns {boolean}
+ */
+export function syncInvalidated(getState: GetState, syncId?: number) {
+  const state = getState();
+  return syncId && state.sync.sharedStateSyncId !== syncId;
+}
+
 export function doSetDefaultAccount(success: () => void, failure: (string) => void) {
   return (dispatch: Dispatch) => {
     dispatch({
@@ -115,7 +128,14 @@ export const doGetSyncDesktop = (cb?: (any, any) => void, password?: string) =>
   });
 };
 
-export function doSyncLoop(noInterval?: boolean) {
+/**
+ * doSyncLoop
+ *
+ * @param noInterval
+ * @param syncId Optional ID to identify a specific loop. Can be used to abort the loop, for example.
+ * @returns {(function(Dispatch, GetState): void)|*}
+ */
+export function doSyncLoop(noInterval?: boolean, syncId?: number) {
   return (dispatch: Dispatch, getState: GetState) => {
     if (!noInterval && syncTimer) clearInterval(syncTimer);
     const state = getState();
@@ -123,7 +143,7 @@ export function doSyncLoop(noInterval?: boolean) {
     const syncEnabled = selectClientSetting(state, SETTINGS.ENABLE_SYNC);
     const syncLocked = selectSyncIsLocked(state);
     if (hasVerifiedEmail && syncEnabled && !syncLocked) {
-      dispatch(doGetSyncDesktop((error, hasNewData) => dispatch(doHandleSyncComplete(error, hasNewData))));
+      dispatch(doGetSyncDesktop((error, hasNewData) => dispatch(doHandleSyncComplete(error, hasNewData, syncId))));
       if (!noInterval) {
         syncTimer = setInterval(() => {
           const state = getState();
diff --git a/ui/redux/middleware/shared-state.js b/ui/redux/middleware/shared-state.js
index 5bac9231f..91a608f1f 100644
--- a/ui/redux/middleware/shared-state.js
+++ b/ui/redux/middleware/shared-state.js
@@ -1,4 +1,5 @@
 // @flow
+import * as ACTIONS from 'constants/action_types';
 import isEqual from 'util/deep-equal';
 import { doPreferenceSet } from 'redux/actions/sync';
 
@@ -47,10 +48,12 @@ export const buildSharedStateMiddleware = (
 
     if (sharedStateCb) {
       // Pass dispatch to the callback to consumers can dispatch actions in response to preference set
-      sharedStateCb({ dispatch, getState });
+      sharedStateCb({ dispatch, getState, syncId: timeout });
     }
     clearTimeout(timeout);
     return actionResult;
   }
+
   timeout = setTimeout(runPreferences, RUN_PREFERENCES_DELAY_MS);
+  dispatch({ type: ACTIONS.SHARED_STATE_SYNC_ID_CHANGED, data: timeout });
 };
diff --git a/ui/redux/reducers/sync.js b/ui/redux/reducers/sync.js
index 0e0e55a93..1547f4d94 100644
--- a/ui/redux/reducers/sync.js
+++ b/ui/redux/reducers/sync.js
@@ -16,6 +16,7 @@ const defaultState: SyncState = {
   setSyncIsPending: false,
   prefsReady: false,
   syncLocked: false,
+  sharedStateSyncId: -1,
   hashChanged: false,
   fatalError: false,
 };
@@ -114,6 +115,10 @@ reducers[ACTIONS.SYNC_FATAL_ERROR] = (state: SyncState) => {
 
 reducers[ACTIONS.SYNC_RESET] = () => defaultState;
 
+reducers[ACTIONS.SHARED_STATE_SYNC_ID_CHANGED] = (state: SyncState, action: any) => {
+  return { ...state, sharedStateSyncId: action.data };
+};
+
 export default function syncReducer(state: SyncState = defaultState, action: any) {
   const handler = reducers[action.type];
   if (handler) return handler(state, action);
diff --git a/ui/store.js b/ui/store.js
index 13f9e24a8..a26c57905 100644
--- a/ui/store.js
+++ b/ui/store.js
@@ -185,8 +185,8 @@ const sharedStateFilters = {
   unpublishedCollections: { source: 'collections', property: 'unpublished' },
 };
 
-const sharedStateCb = ({ dispatch, getState }) => {
-  dispatch(doSyncLoop());
+const sharedStateCb = ({ dispatch, getState, syncId }) => {
+  dispatch(doSyncLoop(false, syncId));
 };
 
 const populateAuthTokenHeader = () => {