diff --git a/App/client-ios.xcodeproj/project.pbxproj b/App/client-ios.xcodeproj/project.pbxproj
index bddd3873d8a672f63620f6732ff81d1cc9826096..c5951402ab44c15cbccd0d4017c7b572c1365596 100644
--- a/App/client-ios.xcodeproj/project.pbxproj
+++ b/App/client-ios.xcodeproj/project.pbxproj
@@ -448,7 +448,7 @@
 				CODE_SIGN_ENTITLEMENTS = "client-ios/Resources/client-ios.entitlements";
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 266;
+				CURRENT_PROJECT_VERSION = 267;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
@@ -487,7 +487,7 @@
 				CODE_SIGN_ENTITLEMENTS = "client-ios/Resources/client-ios.entitlements";
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 266;
+				CURRENT_PROJECT_VERSION = 267;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
@@ -522,7 +522,7 @@
 				CODE_SIGN_ENTITLEMENTS = NotificationExtension/NotificationExtension.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 266;
+				CURRENT_PROJECT_VERSION = 267;
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -553,7 +553,7 @@
 				CODE_SIGN_ENTITLEMENTS = NotificationExtension/NotificationExtension.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 266;
+				CURRENT_PROJECT_VERSION = 267;
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
diff --git a/Sources/BackupFeature/Service/BackupService.swift b/Sources/BackupFeature/Service/BackupService.swift
index 1d4857924384d0cc263f947f46a87fc0bd8bc86f..b71916f161e461ef6a48338070a9150b04bd017a 100644
--- a/Sources/BackupFeature/Service/BackupService.swift
+++ b/Sources/BackupFeature/Service/BackupService.swift
@@ -22,24 +22,17 @@ public final class BackupService {
   @Dependency var driveService: GoogleDriveInterface
 
   @KeyObject(.username, defaultValue: nil) var username: String?
-  @KeyObject(.backupSettings, defaultValue: Data()) private var storedSettings: Data
+  @KeyObject(.backupSettings, defaultValue: nil) var storedSettings: Data?
 
   public var settingsPublisher: AnyPublisher<BackupSettings, Never> {
     settings.handleEvents(receiveSubscription: { [weak self] _ in
       guard let self = self else { return }
-
-      let lastRefreshDate = self.settingsLastRefreshedDate ?? Date.distantPast
-
-      if Date().timeIntervalSince(lastRefreshDate) < 10 { return }
-
-      self.settingsLastRefreshedDate = Date()
       self.refreshConnections()
       self.refreshBackups()
     }).eraseToAnyPublisher()
   }
 
   private var connType: ConnectionType = .wifi
-  private var settingsLastRefreshedDate: Date?
   private var cancellables = Set<AnyCancellable>()
   private lazy var settings = CurrentValueSubject<BackupSettings, Never>(.init(fromData: storedSettings))
 
@@ -140,6 +133,8 @@ extension BackupService {
     if isAutomaticEnabled && hasEnabledService {
       performBackup()
     }
+
+    refreshBackups()
   }
 
   public func setBackupOnlyOnWifi(_ enabled: Bool) {
@@ -226,7 +221,11 @@ extension BackupService {
   }
 
   private func refreshBackups() {
+    print(">>> Refreshing backups...")
+
     if icloudService.isAuthorized() {
+      print(">>> Refreshing icloud backup...")
+
       icloudService.downloadMetadata { [weak settings] in
         guard let settings = settings else { return }
 
@@ -244,6 +243,8 @@ extension BackupService {
     }
 
     if sftpService.isAuthorized() {
+      print(">>> Refreshing sftp backup...")
+
       sftpService.fetchMetadata { [weak settings] in
         guard let settings = settings else { return }
 
@@ -261,6 +262,8 @@ extension BackupService {
     }
 
     if dropboxService.isAuthorized() {
+      print(">>> Refreshing dropbox backup...")
+
       dropboxService.downloadMetadata { [weak settings] in
         guard let settings = settings else { return }
 
@@ -278,6 +281,7 @@ extension BackupService {
     }
 
     driveService.isAuthorized { [weak settings] isAuthorized  in
+      print(">>> Refreshing drive backup...")
       guard let settings = settings else { return }
 
       if isAuthorized {
@@ -315,6 +319,7 @@ extension BackupService {
 
     switch enabledService {
     case .drive:
+      print(">>> Performing upload on drive")
       driveService.uploadBackup(url) {
         switch $0 {
         case .success(let metadata):
@@ -328,6 +333,7 @@ extension BackupService {
         }
       }
     case .icloud:
+      print(">>> Performing upload on iCloud")
       icloudService.uploadBackup(url) {
         switch $0 {
         case .success(let metadata):
@@ -341,19 +347,25 @@ extension BackupService {
         }
       }
     case .dropbox:
+      print(">>> Performing upload on dropbox")
       dropboxService.uploadBackup(url) {
         switch $0 {
         case .success(let metadata):
+          print(">>> Performed upload on dropbox: \(metadata)")
+
           self.settings.value.backups[.dropbox] = .init(
             id: metadata.path,
             date: metadata.modifiedDate,
             size: metadata.size
           )
+
+          self.refreshBackups()
         case .failure(let error):
           print(error.localizedDescription)
         }
       }
     case .sftp:
+      print(">>> Performing upload on sftp")
       sftpService.uploadBackup(url: url) {
         switch $0 {
         case .success(let backup):
diff --git a/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift b/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift
index 74ce209fbf6b2d71a81bb3e93a88fa9838150ea3..0b205733e2f44e8554a8c3df9add0d8382d72af7 100644
--- a/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift
+++ b/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift
@@ -79,6 +79,7 @@ extension BackupConfigViewModel {
       },
       lastBackup: {
         context.service.settingsPublisher
+          .print(">>> lastBackup updated!")
           .map {
             guard let enabledService = $0.enabledService else { return nil }
             return $0.backups[enabledService]
diff --git a/Sources/ChatFeature/Controllers/GroupChatController.swift b/Sources/ChatFeature/Controllers/GroupChatController.swift
index d147ebbd99e224c4482f484042059250d2b9aa21..6080ba62c24a8096e3ec4d4ecaee1fbf20fcb89b 100644
--- a/Sources/ChatFeature/Controllers/GroupChatController.swift
+++ b/Sources/ChatFeature/Controllers/GroupChatController.swift
@@ -439,6 +439,35 @@ extension GroupChatController: UICollectionViewDataSource {
 
                 return cell
             }
+        } else if item.status == .sendingTimedOut {
+          if let replyMessageId = item.replyMessageId {
+            let cell: OutgoingFailedGroupReplyCell = collectionView.dequeueReusableCell(forIndexPath: indexPath)
+
+            Bubbler.buildReplyGroup(
+              bubble: cell.rightView,
+              with: item,
+              reply: replyContent(replyMessageId),
+              sender: name(item.senderId)
+            )
+
+            cell.canReply = false
+            cell.performReply = performReply
+
+            return cell
+          } else {
+            let cell: OutgoingFailedGroupTextCell = collectionView.dequeueReusableCell(forIndexPath: indexPath)
+
+            Bubbler.buildGroup(
+              bubble: cell.rightView,
+              with: item,
+              with: name(item.senderId)
+            )
+
+            cell.canReply = false
+            cell.performReply = performReply
+
+            return cell
+          }
         } else {
             if let replyMessageId = item.replyMessageId {
                 let cell: OutgoingGroupReplyCell = collectionView.dequeueReusableCell(forIndexPath: indexPath)
diff --git a/Sources/ChatFeature/Helpers/BubbleBuilder.swift b/Sources/ChatFeature/Helpers/BubbleBuilder.swift
index ae33fd01e60bfaf501583779e11eb59575444b4f..e6d71c81ee3557385b2d9ec3e349ece13948ac33 100644
--- a/Sources/ChatFeature/Helpers/BubbleBuilder.swift
+++ b/Sources/ChatFeature/Helpers/BubbleBuilder.swift
@@ -235,7 +235,15 @@ final class Bubbler {
             bubble.replyView.space.backgroundColor = Asset.brandPrimary.color
             bubble.lockerImageView.removeFromSuperview()
             bubble.revertBottomStackOrder()
-        case .sendingFailed, .sendingTimedOut:
+        case .sendingTimedOut:
+          bubble.senderLabel.removeFromSuperview()
+          bubble.backgroundColor = Asset.accentWarning.color
+          bubble.textView.textColor = Asset.neutralWhite.color
+          bubble.dateLabel.textColor = Asset.neutralWhite.color
+          roundButtonColor = Asset.neutralWhite.color
+          bubble.replyView.space.backgroundColor = Asset.neutralWhite.color
+          bubble.replyView.container.backgroundColor = Asset.brandLight.color
+        case .sendingFailed:
             bubble.senderLabel.removeFromSuperview()
             bubble.backgroundColor = Asset.accentDanger.color
             bubble.textView.textColor = Asset.neutralWhite.color
@@ -293,7 +301,13 @@ final class Bubbler {
             roundButtonColor = Asset.neutralDisabled.color
             bubble.lockerImageView.removeFromSuperview()
             bubble.revertBottomStackOrder()
-        case .sendingFailed, .sendingTimedOut:
+        case .sendingTimedOut:
+          bubble.senderLabel.removeFromSuperview()
+          bubble.backgroundColor = Asset.accentWarning.color
+          bubble.textView.textColor = Asset.neutralWhite.color
+          bubble.dateLabel.textColor = Asset.neutralWhite.color
+          roundButtonColor = Asset.neutralWhite.color
+        case .sendingFailed:
             bubble.senderLabel.removeFromSuperview()
             bubble.backgroundColor = Asset.accentDanger.color
             bubble.textView.textColor = Asset.neutralWhite.color
diff --git a/Sources/DropboxFeature/Resources/Dropbox-Keys.plist b/Sources/DropboxFeature/Resources/Dropbox-Keys.plist
index ecf15d0188386cac204a2e243e59320620a6c9c5..5348e76e769e5604dfacdb05e1cd396bbb39a15b 100644
--- a/Sources/DropboxFeature/Resources/Dropbox-Keys.plist
+++ b/Sources/DropboxFeature/Resources/Dropbox-Keys.plist
@@ -3,6 +3,6 @@
 <plist version="1.0">
 <dict>
 	<key>DROPBOX_APP_KEY</key>
-	<string></string>
+	<string>ppx0de5f16p9aq2</string>
 </dict>
 </plist>
diff --git a/Sources/GoogleDriveFeature/Resources/GoogleDrive-Keys.plist b/Sources/GoogleDriveFeature/Resources/GoogleDrive-Keys.plist
index 614bac60d3fd5014a33613ee3e83c72656d0854d..d25a7ec0e57eaa6ec8785dd599263d2ef82ae613 100644
--- a/Sources/GoogleDriveFeature/Resources/GoogleDrive-Keys.plist
+++ b/Sources/GoogleDriveFeature/Resources/GoogleDrive-Keys.plist
@@ -3,6 +3,6 @@
 <plist version="1.0">
 <dict>
 	<key>DRIVE_API_KEY</key>
-	<string></string>
+	<string>AIzaSyCbI2yQ7pbuVSRvraqanjGcS9CDrjD7lNU</string>
 </dict>
 </plist>
diff --git a/Sources/Models/BackupSettings.swift b/Sources/Models/BackupSettings.swift
index d52cb1f0e33149b70a22337f56c23d6814d7f7be..41b5d13d19dccc4aa84fea4a980d6efe0ee26eb7 100644
--- a/Sources/Models/BackupSettings.swift
+++ b/Sources/Models/BackupSettings.swift
@@ -25,15 +25,24 @@ public struct BackupSettings: Equatable, Codable {
         (try? PropertyListEncoder().encode(self)) ?? Data()
     }
 
-    public init(fromData data: Data) {
-        let settings = try? PropertyListDecoder().decode(BackupSettings.self, from: data)
+    public init(fromData data: Data?) {
+      if let data = data, let settings = try? PropertyListDecoder().decode(BackupSettings.self, from: data) {
         self.init(
-            wifiOnlyBackup: settings?.wifiOnlyBackup ?? false,
-            automaticBackups: settings?.automaticBackups ?? true,
-            enabledService: settings?.enabledService,
-            connectedServices: settings?.connectedServices ?? [],
-            backups: settings?.backups ?? [:]
+          wifiOnlyBackup: settings.wifiOnlyBackup,
+          automaticBackups: settings.automaticBackups,
+          enabledService: settings.enabledService,
+          connectedServices: settings.connectedServices,
+          backups: settings.backups
         )
+      } else {
+        self.init(
+          wifiOnlyBackup: false,
+          automaticBackups: true,
+          enabledService: nil,
+          connectedServices: [],
+          backups: [:]
+        )
+      }
     }
 }
 
diff --git a/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift b/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift
index d7eb5db970117df0d24c0fe33a464bef841d141e..b7564509410a86b480489e08206abe80e188893d 100644
--- a/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift
+++ b/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift
@@ -6,95 +6,99 @@ import Defaults
 import XXClient
 import Foundation
 import InputField
+import BackupFeature
 import CombineSchedulers
 import XXMessengerClient
 import DependencyInjection
 
 struct ProfileCodeViewState: Equatable {
-    var input: String = ""
-    var status: InputField.ValidationStatus = .unknown(nil)
-    var resendDebouncer: Int = 0
+  var input: String = ""
+  var status: InputField.ValidationStatus = .unknown(nil)
+  var resendDebouncer: Int = 0
 }
 
 final class ProfileCodeViewModel {
-    @Dependency var messenger: Messenger
+  @Dependency var messenger: Messenger
+  @Dependency var backupService: BackupService
 
-    @KeyObject(.email, defaultValue: nil) var email: String?
-    @KeyObject(.phone, defaultValue: nil) var phone: String?
+  @KeyObject(.email, defaultValue: nil) var email: String?
+  @KeyObject(.phone, defaultValue: nil) var phone: String?
 
-    let confirmation: AttributeConfirmation
+  let confirmation: AttributeConfirmation
 
-    var timer: Timer?
+  var timer: Timer?
 
-    var completionPublisher: AnyPublisher<AttributeConfirmation, Never> { completionRelay.eraseToAnyPublisher() }
-    private let completionRelay = PassthroughSubject<AttributeConfirmation, Never>()
+  var completionPublisher: AnyPublisher<AttributeConfirmation, Never> { completionRelay.eraseToAnyPublisher() }
+  private let completionRelay = PassthroughSubject<AttributeConfirmation, Never>()
 
-    var hud: AnyPublisher<HUDStatus, Never> { hudRelay.eraseToAnyPublisher() }
-    private let hudRelay = CurrentValueSubject<HUDStatus, Never>(.none)
+  var hud: AnyPublisher<HUDStatus, Never> { hudRelay.eraseToAnyPublisher() }
+  private let hudRelay = CurrentValueSubject<HUDStatus, Never>(.none)
 
-    var state: AnyPublisher<ProfileCodeViewState, Never> { stateRelay.eraseToAnyPublisher() }
-    private let stateRelay = CurrentValueSubject<ProfileCodeViewState, Never>(.init())
+  var state: AnyPublisher<ProfileCodeViewState, Never> { stateRelay.eraseToAnyPublisher() }
+  private let stateRelay = CurrentValueSubject<ProfileCodeViewState, Never>(.init())
 
-    var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler()
+  var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler()
 
-    init(_ confirmation: AttributeConfirmation) {
-        self.confirmation = confirmation
-        didTapResend()
-    }
+  init(_ confirmation: AttributeConfirmation) {
+    self.confirmation = confirmation
+    didTapResend()
+  }
 
-    func didInput(_ string: String) {
-        stateRelay.value.input = string
-        validate()
-    }
+  func didInput(_ string: String) {
+    stateRelay.value.input = string
+    validate()
+  }
 
-    func didTapResend() {
-        guard stateRelay.value.resendDebouncer == 0 else { return }
+  func didTapResend() {
+    guard stateRelay.value.resendDebouncer == 0 else { return }
 
-        stateRelay.value.resendDebouncer = 60
+    stateRelay.value.resendDebouncer = 60
 
-        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {  [weak self] in
-            guard let self = self, self.stateRelay.value.resendDebouncer > 0 else {
-                $0.invalidate()
-                return
-            }
+    timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {  [weak self] in
+      guard let self = self, self.stateRelay.value.resendDebouncer > 0 else {
+        $0.invalidate()
+        return
+      }
 
-            self.stateRelay.value.resendDebouncer -= 1
-        }
+      self.stateRelay.value.resendDebouncer -= 1
     }
+  }
 
-    func didTapNext() {
-        hudRelay.send(.on)
-
-        backgroundScheduler.schedule { [weak self] in
-            guard let self = self else { return }
-
-            do {
-                try self.messenger.ud.get()!.confirmFact(
-                    confirmationId: self.confirmation.confirmationId!,
-                    code: self.stateRelay.value.input
-                )
-
-                if self.confirmation.isEmail {
-                    self.email = self.confirmation.content
-                } else {
-                    self.phone = self.confirmation.content
-                }
-
-                self.timer?.invalidate()
-                self.hudRelay.send(.none)
-                self.completionRelay.send(self.confirmation)
-            } catch {
-                self.hudRelay.send(.error(.init(with: error)))
-            }
-        }
-    }
+  func didTapNext() {
+    hudRelay.send(.on)
 
-    private func validate() {
-        switch Validator.code.validate(stateRelay.value.input) {
-        case .success:
-            stateRelay.value.status = .valid(nil)
-        case .failure(let error):
-            stateRelay.value.status = .invalid(error)
+    backgroundScheduler.schedule { [weak self] in
+      guard let self = self else { return }
+
+      do {
+        try self.messenger.ud.get()!.confirmFact(
+          confirmationId: self.confirmation.confirmationId!,
+          code: self.stateRelay.value.input
+        )
+
+        if self.confirmation.isEmail {
+          self.email = self.confirmation.content
+        } else {
+          self.phone = self.confirmation.content
         }
+
+        self.timer?.invalidate()
+        self.hudRelay.send(.none)
+        self.completionRelay.send(self.confirmation)
+
+        self.backupService.performBackup()
+      } catch {
+        self.hudRelay.send(.error(.init(with: error)))
+      }
+    }
+  }
+
+  private func validate() {
+    switch Validator.code.validate(stateRelay.value.input) {
+    case .success:
+      stateRelay.value.status = .valid(nil)
+    case .failure(let error):
+      stateRelay.value.status = .invalid(error)
     }
+  }
 }
diff --git a/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift b/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift
index 1d01467d8e20b16aff653bb67e5a441292b802d6..b1bddd42bbbe751e5194848fca749bb76d85106d 100644
--- a/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift
+++ b/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift
@@ -8,9 +8,10 @@ import XXClient
 import Countries
 import Foundation
 import Permissions
+import BackupFeature
+import XXMessengerClient
 import CombineSchedulers
 import DependencyInjection
-import XXMessengerClient
 
 enum ProfileNavigationRoutes {
   case none
@@ -33,7 +34,8 @@ final class ProfileViewModel {
   @KeyObject(.sharingPhone, defaultValue: false) var isPhoneSharing: Bool
 
   @Dependency var messenger: Messenger
-  @Dependency private var permissions: PermissionHandling
+  @Dependency var backupService: BackupService
+  @Dependency var permissions: PermissionHandling
 
   var name: String { username! }
 
@@ -106,6 +108,7 @@ final class ProfileViewModel {
           self.isPhoneSharing = false
         }
 
+        self.backupService.performBackup()
         self.hudRelay.send(.none)
         self.refresh()
       } catch {