diff --git a/Sources/XXMessengerClient/Utils/BackupStorage.swift b/Sources/XXMessengerClient/Utils/BackupStorage.swift
index b13c86cb92bdb261dc4171a1e380234d99f19dfc..e85e2e869b6610440b9531f70fd1a7d3fd42bd45 100644
--- a/Sources/XXMessengerClient/Utils/BackupStorage.swift
+++ b/Sources/XXMessengerClient/Utils/BackupStorage.swift
@@ -18,28 +18,39 @@ public struct BackupStorage {
 
   public typealias Observer = (Backup?) -> Void
 
-  public var store: (Data) -> Void
+  public var store: (Data) throws -> Void
   public var observe: (@escaping Observer) -> Cancellable
-  public var remove: () -> Void
+  public var remove: () throws -> Void
 }
 
 extension BackupStorage {
-  public static func live(
-    now: @escaping () -> Date
+  public static func onDisk(
+    now: @escaping () -> Date = Date.init,
+    fileManager: MessengerFileManager = .live(),
+    path: String = FileManager.default
+      .urls(for: .applicationSupportDirectory, in: .userDomainMask)
+      .first!
+      .appendingPathComponent("backup.xxm")
+      .path
   ) -> BackupStorage {
     var observers: [UUID: Observer] = [:]
     var backup: Backup?
     func notifyObservers() {
       observers.values.forEach { $0(backup) }
     }
-
+    if let fileData = try? fileManager.loadFile(path),
+       let fileDate = try? fileManager.modifiedTime(path) {
+      backup = Backup(date: fileDate, data: fileData)
+    }
     return BackupStorage(
       store: { data in
-        backup = Backup(
+        let newBackup = Backup(
           date: now(),
           data: data
         )
+        backup = newBackup
         notifyObservers()
+        try fileManager.saveFile(path, newBackup.data)
       },
       observe: { observer in
         let id = UUID()
@@ -52,6 +63,7 @@ extension BackupStorage {
       remove: {
         backup = nil
         notifyObservers()
+        try fileManager.removeItem(path)
       }
     )
   }
diff --git a/Tests/XXMessengerClientTests/Utils/BackupStorageTests.swift b/Tests/XXMessengerClientTests/Utils/BackupStorageTests.swift
index 3dc8272ea913cb39dd8723a74c0179ce10e31015..d373ce6e3a88f1644e94ea735a5805dd039631e7 100644
--- a/Tests/XXMessengerClientTests/Utils/BackupStorageTests.swift
+++ b/Tests/XXMessengerClientTests/Utils/BackupStorageTests.swift
@@ -3,63 +3,98 @@ import XCTest
 @testable import XXMessengerClient
 
 final class BackupStorageTests: XCTestCase {
-  func testStorage() {
+  func testStorage() throws {
+    var actions: [Action]!
+
     var now: Date = .init(0)
-    let storage: BackupStorage = .live(
-      now: { now }
+    let path = "backup-path"
+    let fileData = "file-data".data(using: .utf8)!
+    let fileDate = Date(123)
+    var fileManager = MessengerFileManager.unimplemented
+    fileManager.loadFile = { path in
+      actions.append(.didLoadFile(path))
+      return fileData
+    }
+    fileManager.modifiedTime = { path in
+      actions.append(.didGetModifiedTime(path))
+      return fileDate
+    }
+    fileManager.saveFile = { path, data in
+      actions.append(.didSaveFile(path, data))
+    }
+    fileManager.removeItem = { path in
+      actions.append(.didRemoveItem(path))
+    }
+    actions = []
+    let storage: BackupStorage = .onDisk(
+      now: { now },
+      fileManager: fileManager,
+      path: path
     )
 
-    var didObserveA: [BackupStorage.Backup?] = []
+    XCTAssertNoDifference(actions, [
+      .didLoadFile(path),
+      .didGetModifiedTime(path),
+    ])
+
+    actions = []
     let observerA = storage.observe { backup in
-      didObserveA.append(backup)
+      actions.append(.didObserve("A", backup))
     }
 
-    XCTAssertNoDifference(didObserveA, [nil])
+    XCTAssertNoDifference(actions, [
+      .didObserve("A", .init(date: fileDate, data: fileData))
+    ])
 
+    actions = []
     now = .init(1)
-    didObserveA = []
     let data1 = "data-1".data(using: .utf8)!
-    storage.store(data1)
+    try storage.store(data1)
 
-    XCTAssertNoDifference(didObserveA, [.init(date: .init(1), data: data1)])
+    XCTAssertNoDifference(actions, [
+      .didObserve("A", .init(date: .init(1), data: data1)),
+      .didSaveFile(path, data1),
+    ])
 
+    actions = []
     now = .init(2)
-    didObserveA = []
-    var didObserveB: [BackupStorage.Backup?] = []
     let observerB = storage.observe { backup in
-      didObserveB.append(backup)
+      actions.append(.didObserve("B", backup))
     }
 
-    XCTAssertNoDifference(didObserveA, [])
-    XCTAssertNoDifference(didObserveB, [.init(date: .init(1), data: data1)])
+    XCTAssertNoDifference(actions, [
+      .didObserve("B", .init(date: .init(1), data: data1))
+    ])
 
+    actions = []
     now = .init(3)
-    didObserveA = []
-    didObserveB = []
+    observerA.cancel()
     let data2 = "data-2".data(using: .utf8)!
-    storage.store(data2)
+    try storage.store(data2)
 
-    XCTAssertNoDifference(didObserveA, [.init(date: .init(3), data: data2)])
-    XCTAssertNoDifference(didObserveB, [.init(date: .init(3), data: data2)])
+    XCTAssertNoDifference(actions, [
+      .didObserve("B", .init(date: .init(3), data: data2)),
+      .didSaveFile(path, data2),
+    ])
 
+    actions = []
     now = .init(4)
-    didObserveA = []
-    didObserveB = []
-    observerA.cancel()
-    storage.remove()
+    try storage.remove()
 
-    XCTAssertNoDifference(didObserveA, [])
-    XCTAssertNoDifference(didObserveB, [nil])
+    XCTAssertNoDifference(actions, [
+      .didObserve("B", nil),
+      .didRemoveItem(path),
+    ])
 
+    actions = []
     now = .init(5)
-    didObserveA = []
-    didObserveB = []
     observerB.cancel()
     let data3 = "data-3".data(using: .utf8)!
-    storage.store(data3)
+    try storage.store(data3)
 
-    XCTAssertNoDifference(didObserveA, [])
-    XCTAssertNoDifference(didObserveB, [])
+    XCTAssertNoDifference(actions, [
+      .didSaveFile(path, data3),
+    ])
   }
 }
 
@@ -68,3 +103,11 @@ private extension Date {
     self.init(timeIntervalSince1970: timeIntervalSince1970)
   }
 }
+
+private enum Action: Equatable {
+  case didLoadFile(String)
+  case didGetModifiedTime(String)
+  case didObserve(String, BackupStorage.Backup?)
+  case didSaveFile(String, Data)
+  case didRemoveItem(String)
+}