diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt
--- a/native/android/app/CMakeLists.txt
+++ b/native/android/app/CMakeLists.txt
@@ -130,6 +130,7 @@
   "../../native_rust_library/RustAESCrypto.cpp"
   "../../native_rust_library/RustCSAMetadataEmitter.cpp"
   "../../native_rust_library/RustSecureStore.cpp"
+  "../../native_rust_library/RustBackupExecutor.cpp"
 )
 file(GLOB CRYPTO_NATIVE_CODE "../../cpp/CommonCpp/CryptoTools/*.cpp")
 file(GLOB DB_NATIVE_CODE "../../cpp/CommonCpp/DatabaseManagers/*.cpp")
diff --git a/native/android/app/src/cpp/PlatformSpecificTools.cpp b/native/android/app/src/cpp/PlatformSpecificTools.cpp
--- a/native/android/app/src/cpp/PlatformSpecificTools.cpp
+++ b/native/android/app/src/cpp/PlatformSpecificTools.cpp
@@ -31,6 +31,27 @@
         cls->getStaticMethod<JString()>("getNotificationsCryptoAccountPath");
     return method(cls)->toStdString();
   }
+
+  static std::string getBackupDirectoryPath() {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<JString()>("getBackupDirectoryPath");
+    return method(cls)->toStdString();
+  }
+
+  static std::string
+  getBackupFilePath(std::string backupID, bool isAttachments) {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<JString(std::string, bool)>("getBackupFilePath");
+    return method(cls, backupID, isAttachments)->toStdString();
+  }
+
+  static void removeBackupDirectory() {
+    static const auto cls = javaClassStatic();
+    static auto method = cls->getStaticMethod<void()>("removeBackupDirectory");
+    method(cls);
+  }
 };
 
 namespace comm {
@@ -55,4 +76,28 @@
   return path;
 }
 
+std::string PlatformSpecificTools::getBackupDirectoryPath() {
+  std::string path;
+  NativeAndroidAccessProvider::runTask([&path]() {
+    path = PlatformSpecificToolsJavaClass::getBackupDirectoryPath();
+  });
+  return path;
+}
+
+std::string PlatformSpecificTools::getBackupFilePath(
+    std::string backupID,
+    bool isAttachments) {
+  std::string path;
+  NativeAndroidAccessProvider::runTask([&path, backupID, isAttachments]() {
+    path = PlatformSpecificToolsJavaClass::getBackupFilePath(
+        backupID, isAttachments);
+  });
+  return path;
+}
+
+void PlatformSpecificTools::removeBackupDirectory() {
+  NativeAndroidAccessProvider::runTask(
+      []() { PlatformSpecificToolsJavaClass::removeBackupDirectory(); });
+}
+
 } // namespace comm
diff --git a/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java b/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java
--- a/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java
+++ b/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java
@@ -3,9 +3,12 @@
 import android.content.Context;
 import android.util.Log;
 import app.comm.android.MainApplication;
+import java.io.File;
+import java.lang.SecurityException;
 import java.nio.charset.StandardCharsets;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
+
 public class PlatformSpecificTools {
   static SecureRandom secureRandom = new SecureRandom();
 
@@ -26,4 +29,73 @@
         .getFileStreamPath("comm_notifications_crypto_account")
         .getPath();
   }
+
+  public static String getBackupDirectoryPath() {
+    Context mainApplicationContext =
+        MainApplication.getMainApplicationContext();
+    if (mainApplicationContext == null) {
+      throw new RuntimeException(
+          "Failed to resolve backup path - main application context not initialized.");
+    }
+
+    String filesDirPath = mainApplicationContext.getFilesDir().getPath();
+    String backupDirPath = String.join(File.separator, filesDirPath, "backup");
+
+    try {
+      File backupDirectory = new File(backupDirPath);
+      if (!backupDirectory.exists() && !backupDirectory.mkdirs()) {
+        throw new RuntimeException("Failed to create backup directory.");
+      }
+      return backupDirPath;
+    } catch (SecurityException | NullPointerException e) {
+      throw new RuntimeException(
+          "Failed to check if backup directory exists or to attempt its creation. Details: " +
+          e.getMessage());
+    }
+  }
+
+  public static String
+  getBackupFilePath(String backupID, boolean isAttachments) {
+    String backupDirPath = PlatformSpecificTools.getBackupDirectoryPath();
+
+    String filename;
+    if (isAttachments) {
+      filename = String.join("_", "backup", backupID, "attachments");
+    } else {
+      filename = String.join("_", "backup", backupID);
+    }
+    return String.join(File.separator, backupDirPath, filename);
+  }
+
+  public static void removeBackupDirectory() {
+    String backupDirPath = PlatformSpecificTools.getBackupDirectoryPath();
+    try {
+      File backupDirectory = new File(backupDirPath);
+      if (!backupDirectory.exists()) {
+        return;
+      }
+
+      File[] files = backupDirectory.listFiles();
+      if (files == null && !backupDirectory.delete()) {
+        throw new RuntimeException("Failed to remove backup directory.");
+      } else if (files == null) {
+        return;
+      }
+
+      // Backup directory structure is supposed to be flat.
+      for (File file : files) {
+        if (!file.delete()) {
+          throw new RuntimeException(
+              "Failed to remove backup file at path: " + file.getPath());
+        }
+      }
+
+      if (!backupDirectory.delete()) {
+        throw new RuntimeException("Failed to remove backup directory.");
+      }
+    } catch (NullPointerException | SecurityException e) {
+      throw new RuntimeException(
+          "Failed to remove backup directory. Details: " + e.getMessage());
+    }
+  }
 }
diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
@@ -2,6 +2,7 @@
 #include "../Notifications/BackgroundDataStorage/NotificationsCryptoModule.h"
 #include "../Tools/CommSecureStore.h"
 #include "Logger.h"
+#include "PlatformSpecificTools.h"
 #include "SQLiteQueryExecutor.h"
 
 namespace comm {
@@ -34,6 +35,7 @@
   CommSecureStore::set(CommSecureStore::deviceID, "");
   CommSecureStore::set(CommSecureStore::commServicesAccessToken, "");
   SQLiteQueryExecutor::clearSensitiveData();
+  PlatformSpecificTools::removeBackupDirectory();
   NotificationsCryptoModule::clearSensitiveData();
   DatabaseManager::setDatabaseStatusAsWorkable();
 }
diff --git a/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h b/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h
--- a/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h
+++ b/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h
@@ -9,6 +9,10 @@
   static void generateSecureRandomBytes(crypto::OlmBuffer &buffer, size_t size);
   static std::string getDeviceOS();
   static std::string getNotificationsCryptoAccountPath();
+  static std::string getBackupDirectoryPath();
+  static std::string
+  getBackupFilePath(std::string backupID, bool isAttachments);
+  static void removeBackupDirectory();
 };
 
 } // namespace comm
diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj
--- a/native/ios/Comm.xcodeproj/project.pbxproj
+++ b/native/ios/Comm.xcodeproj/project.pbxproj
@@ -81,6 +81,7 @@
 		CBCA09062A8E0E7400F75B3E /* StaffUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBCA09052A8E0E6B00F75B3E /* StaffUtils.cpp */; };
 		CBCA09072A8E0E7D00F75B3E /* StaffUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBCA09052A8E0E6B00F75B3E /* StaffUtils.cpp */; };
 		CBDEC69B28ED867000C17588 /* GlobalDBSingleton.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */; };
+		CBFBEEBA2B4ED90600729F1D /* RustBackupExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBFBEEB82B4ED90600729F1D /* RustBackupExecutor.cpp */; };
 		CBFE58292885852B003B94C9 /* ThreadOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBFE58282885852B003B94C9 /* ThreadOperations.cpp */; };
 		D7DB6E0F85B2DBE15B01EC21 /* libPods-Comm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 994BEBDD4E4959F69CEA0BC3 /* libPods-Comm.a */; };
 		DFD5E77C2B05181400C32B6A /* RustSecureStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5E77B2B05181400C32B6A /* RustSecureStore.cpp */; };
@@ -277,6 +278,8 @@
 		CBCF57AB2B05096F00EC4BC0 /* AESCryptoModuleObjCCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AESCryptoModuleObjCCompat.h; path = Comm/CommAESCryptoUtils/AESCryptoModuleObjCCompat.h; sourceTree = "<group>"; };
 		CBDEC69928ED859600C17588 /* GlobalDBSingleton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlobalDBSingleton.h; sourceTree = "<group>"; };
 		CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = GlobalDBSingleton.mm; path = Comm/GlobalDBSingleton.mm; sourceTree = "<group>"; };
+		CBFBEEB82B4ED90600729F1D /* RustBackupExecutor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RustBackupExecutor.cpp; sourceTree = "<group>"; };
+		CBFBEEB92B4ED90600729F1D /* RustBackupExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RustBackupExecutor.h; sourceTree = "<group>"; };
 		CBFE58272885852B003B94C9 /* ThreadOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadOperations.h; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.h; sourceTree = "<group>"; };
 		CBFE58282885852B003B94C9 /* ThreadOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadOperations.cpp; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp; sourceTree = "<group>"; };
 		DFD5E77A2B05181400C32B6A /* RustSecureStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RustSecureStore.h; sourceTree = "<group>"; };
@@ -593,6 +596,8 @@
 		8B99AF6B28D50D4800EB5ADB /* native_rust_library */ = {
 			isa = PBXGroup;
 			children = (
+				CBFBEEB82B4ED90600729F1D /* RustBackupExecutor.cpp */,
+				CBFBEEB92B4ED90600729F1D /* RustBackupExecutor.h */,
 				CB74AB1E2B2B0C0900CBB494 /* RustCSAMetadataEmitter.cpp */,
 				CB74AB1F2B2B0C0900CBB494 /* RustCSAMetadataEmitter.h */,
 				DFD5E7842B052B1400C32B6A /* RustAESCrypto.cpp */,
@@ -1094,6 +1099,7 @@
 				CBFE58292885852B003B94C9 /* ThreadOperations.cpp in Sources */,
 				CB74AB1C2B2AFF6E00CBB494 /* CommServicesAuthMetadataEmitter.mm in Sources */,
 				8E3994552B039A7C00D5E950 /* UserStore.cpp in Sources */,
+				CBFBEEBA2B4ED90600729F1D /* RustBackupExecutor.cpp in Sources */,
 				7FBB2A7829E945C2002C6493 /* CommUtilsModule.cpp in Sources */,
 				CB38B48228771C7A00171182 /* NonBlockingLock.mm in Sources */,
 				718DE99E2653D41C00365824 /* WorkerThread.cpp in Sources */,
diff --git a/native/ios/Comm/PlatformSpecificTools.mm b/native/ios/Comm/PlatformSpecificTools.mm
--- a/native/ios/Comm/PlatformSpecificTools.mm
+++ b/native/ios/Comm/PlatformSpecificTools.mm
@@ -37,4 +37,74 @@
               .path UTF8String]);
 }
 
+NSURL *getBackupDirAsURL() {
+  NSError *err = nil;
+  NSURL *documentsUrl =
+      [NSFileManager.defaultManager URLForDirectory:NSDocumentDirectory
+                                           inDomain:NSUserDomainMask
+                                  appropriateForURL:nil
+                                             create:false
+                                              error:&err];
+  if (err) {
+    NSLog(@"Error: %@", err);
+    throw std::runtime_error(
+        "Failed to resolve backup path - could not find documentsUrl. "
+        "Details: " +
+        std::string([err.localizedDescription UTF8String]));
+  }
+
+  NSURL *backupDir = [documentsUrl URLByAppendingPathComponent:@"backup"];
+  NSError *backupDirCreateError = nil;
+  if (![NSFileManager.defaultManager fileExistsAtPath:backupDir.path]) {
+    [NSFileManager.defaultManager createDirectoryAtURL:backupDir
+                           withIntermediateDirectories:YES
+                                            attributes:nil
+                                                 error:&backupDirCreateError];
+  }
+  if (backupDirCreateError) {
+    throw std::runtime_error(
+        "Failed to create backup directory. Details: " +
+        std::string([backupDirCreateError.localizedDescription UTF8String]));
+  }
+  return backupDir;
+}
+
+std::string PlatformSpecificTools::getBackupDirectoryPath() {
+  return [getBackupDirAsURL().path UTF8String];
+}
+
+std::string PlatformSpecificTools::getBackupFilePath(
+    std::string backupID,
+    bool isAttachments) {
+
+  NSURL *backupDir = getBackupDirAsURL();
+  NSString *backupIDObjC = [NSString stringWithCString:backupID.c_str()
+                                              encoding:NSUTF8StringEncoding];
+  NSString *filename;
+  if (isAttachments) {
+    filename = [@[ @"backup", backupIDObjC, @"attachments" ]
+        componentsJoinedByString:@"_"];
+  } else {
+    filename = [@[ @"backup", backupIDObjC ] componentsJoinedByString:@"_"];
+  }
+  return [[backupDir URLByAppendingPathComponent:filename].path UTF8String];
+}
+
+void PlatformSpecificTools::removeBackupDirectory() {
+  NSURL *backupDir = getBackupDirAsURL();
+  if (![NSFileManager.defaultManager fileExistsAtPath:backupDir.path]) {
+    return;
+  }
+
+  NSError *backupDirRemovalError = nil;
+  [NSFileManager.defaultManager removeItemAtURL:backupDir
+                                          error:&backupDirRemovalError];
+
+  if (backupDirRemovalError) {
+    throw std::runtime_error(
+        "Failed to remove backup directory. Details: " +
+        std::string([backupDirRemovalError.localizedDescription UTF8String]));
+  }
+}
+
 }; // namespace comm
diff --git a/native/native_rust_library/RustBackupExecutor.h b/native/native_rust_library/RustBackupExecutor.h
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/RustBackupExecutor.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "cxx.h"
+
+namespace comm {
+
+rust::String getBackupDirectoryPath();
+rust::String getBackupFilePath(rust::String backupID, bool isAttachments);
+
+} // namespace comm
diff --git a/native/native_rust_library/RustBackupExecutor.cpp b/native/native_rust_library/RustBackupExecutor.cpp
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/RustBackupExecutor.cpp
@@ -0,0 +1,16 @@
+#include "RustBackupExecutor.h"
+#include "../cpp/CommonCpp/Tools/PlatformSpecificTools.h"
+
+#include <string>
+
+namespace comm {
+
+rust::String getBackupDirectoryPath() {
+  return rust::String(PlatformSpecificTools::getBackupDirectoryPath());
+}
+
+rust::String getBackupFilePath(rust::String backupID, bool isAttachments) {
+  return rust::String(PlatformSpecificTools::getBackupFilePath(
+      std::string(backupID), isAttachments));
+}
+} // namespace comm
diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs
--- a/native/native_rust_library/src/lib.rs
+++ b/native/native_rust_library/src/lib.rs
@@ -244,6 +244,23 @@
     #[cxx_name = "secureStoreGet"]
     fn secure_store_get(key: &str) -> Result<String>;
   }
+
+  // C++ Backup creation
+  #[namespace = "comm"]
+  unsafe extern "C++" {
+    include!("RustBackupExecutor.h");
+
+    #[allow(unused)]
+    #[cxx_name = "getBackupDirectoryPath"]
+    fn get_backup_directory_path() -> Result<String>;
+
+    #[allow(unused)]
+    #[cxx_name = "getBackupFilePath"]
+    fn get_backup_file_path(
+      backup_id: String,
+      is_attachments: bool,
+    ) -> Result<String>;
+  }
 }
 
 fn handle_string_result_as_callback<E>(