diff --git a/native/backup/backup-handler.js b/native/backup/backup-handler.js
new file mode 100644
--- /dev/null
+++ b/native/backup/backup-handler.js
@@ -0,0 +1,62 @@
+// @flow
+
+import AsyncStorage from '@react-native-async-storage/async-storage';
+import * as React from 'react';
+import { useSelector } from 'react-redux';
+
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { getMessageForException } from 'lib/utils/errors.js';
+
+import { BACKUP_HASH_STORAGE_KEY } from './constants.js';
+import { convertObjToBytes } from './conversion-utils.js';
+import { useClientBackup } from './use-client-backup.js';
+import { commUtilsModule } from '../native-modules.js';
+import Alert from '../utils/alert.js';
+import { useStaffCanSee } from '../utils/staff-utils.js';
+
+function BackupHandler(): null {
+  const userStore = useSelector(state => state.userStore);
+  const currentUserID = useSelector(
+    state => state.currentUserInfo && state.currentUserInfo.id,
+  );
+  const loggedIn = useSelector(isLoggedIn);
+  const staffCanSee = useStaffCanSee();
+
+  const { uploadBackupProtocol } = useClientBackup();
+
+  React.useEffect(() => {
+    (async () => {
+      if (!loggedIn || !staffCanSee) {
+        return;
+      }
+
+      const userData = { userStore };
+      const userDataBytes = convertObjToBytes(userData);
+      const currentBackupHash = commUtilsModule.sha256(userDataBytes.buffer);
+
+      const recentBackupHash = await AsyncStorage.getItem(
+        BACKUP_HASH_STORAGE_KEY,
+      );
+
+      if (!recentBackupHash || currentBackupHash !== recentBackupHash) {
+        try {
+          await uploadBackupProtocol(userData);
+          await AsyncStorage.setItem(
+            BACKUP_HASH_STORAGE_KEY,
+            currentBackupHash,
+          );
+        } catch (e) {
+          console.error(`Backup uploading error: ${e}`);
+          Alert.alert(
+            'Backup protocol info',
+            `Backup uploading error: ${String(getMessageForException(e))}`,
+          );
+        }
+      }
+    })();
+  }, [currentUserID, loggedIn, staffCanSee, uploadBackupProtocol, userStore]);
+
+  return null;
+}
+
+export default BackupHandler;
diff --git a/native/backup/constants.js b/native/backup/constants.js
--- a/native/backup/constants.js
+++ b/native/backup/constants.js
@@ -1,3 +1,5 @@
 // @flow
 
 export const BACKUP_ID_LENGTH = 32; //256 bits
+
+export const BACKUP_HASH_STORAGE_KEY = 'RECENT_USER_DATA_HASH';
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -26,6 +26,7 @@
 
 import { RegistrationContextProvider } from './account/registration/registration-context-provider.react.js';
 import NativeEditThreadAvatarProvider from './avatars/native-edit-thread-avatar-provider.react.js';
+import BackupHandler from './backup/backup-handler.js';
 import ChatContextProvider from './chat/chat-context-provider.react.js';
 import MessageEditingContextProvider from './chat/message-editing-context-provider.react.js';
 import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js';
@@ -240,6 +241,7 @@
       <ConnectivityUpdater />
       <ThemeHandler />
       <OrientationHandler />
+      <BackupHandler />
     </>
   );
   let navigation;