diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt
index a720cba8eb..b8c8ac36d0 100644
--- a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt
+++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt
@@ -137,6 +137,6 @@ open class NativeSyncApiImplBase(context: Context) {
         return albums.map { album ->
             val count = albumsCount[album.id] ?: 0
             album.copy(assetCount = count.toLong())
-        }
+        }.sortedBy { it.id }
     }
 }
diff --git a/mobile/lib/domain/services/device_sync.service.dart b/mobile/lib/domain/services/device_sync.service.dart
index 9e3e2d7292..1c8182aef4 100644
--- a/mobile/lib/domain/services/device_sync.service.dart
+++ b/mobile/lib/domain/services/device_sync.service.dart
@@ -37,12 +37,12 @@ class DeviceSyncService {
   bool get _ignoreIcloudAssets =>
       _storeService.get(StoreKey.ignoreIcloudAssets, false) == true;
 
-  Future<void> sync() async {
+  Future<void> sync({bool full = false}) async {
     final Stopwatch stopwatch = Stopwatch()..start();
     try {
-      if (await _nativeSyncApi.shouldFullSync()) {
-        _log.fine("Cannot use partial sync. Performing full sync");
-        DLog.log("Cannot use partial sync. Performing full sync");
+      if (full || await _nativeSyncApi.shouldFullSync()) {
+        _log.fine("Full sync request from ${full ? "user" : "native"}");
+        DLog.log("Full sync request from ${full ? "user" : "native"}");
         return await fullSync();
       }
 
diff --git a/mobile/lib/domain/utils/background_sync.dart b/mobile/lib/domain/utils/background_sync.dart
index 48b95389ce..5e8e931ec2 100644
--- a/mobile/lib/domain/utils/background_sync.dart
+++ b/mobile/lib/domain/utils/background_sync.dart
@@ -23,13 +23,14 @@ class BackgroundSyncManager {
   }
 
   // No need to cancel the task, as it can also be run when the user logs out
-  Future<void> syncLocal() {
+  Future<void> syncLocal({bool full = false}) {
     if (_deviceAlbumSyncTask != null) {
       return _deviceAlbumSyncTask!.future;
     }
 
     _deviceAlbumSyncTask = runInIsolateGentle(
-      computation: (ref) => ref.read(deviceSyncServiceProvider).sync(),
+      computation: (ref) =>
+          ref.read(deviceSyncServiceProvider).sync(full: full),
     );
 
     return _deviceAlbumSyncTask!.whenComplete(() {
diff --git a/mobile/lib/presentation/pages/dev/feat_in_development.page.dart b/mobile/lib/presentation/pages/dev/feat_in_development.page.dart
index 896d4fdf95..da0bea157f 100644
--- a/mobile/lib/presentation/pages/dev/feat_in_development.page.dart
+++ b/mobile/lib/presentation/pages/dev/feat_in_development.page.dart
@@ -21,6 +21,11 @@ final _features = [
     icon: Icons.photo_album_rounded,
     onTap: (_, ref) => ref.read(backgroundSyncProvider).syncLocal(),
   ),
+  _Feature(
+    name: 'Sync Local Full',
+    icon: Icons.photo_library_rounded,
+    onTap: (_, ref) => ref.read(backgroundSyncProvider).syncLocal(full: true),
+  ),
   _Feature(
     name: 'Sync Remote',
     icon: Icons.refresh_rounded,
@@ -69,6 +74,7 @@ class FeatInDevPage extends StatelessWidget {
       body: Column(
         children: [
           Flexible(
+            flex: 1,
             child: ListView.builder(
               itemBuilder: (_, index) {
                 final feat = _features[index];
@@ -76,6 +82,7 @@ class FeatInDevPage extends StatelessWidget {
                   builder: (ctx, ref, _) => ListTile(
                     title: Text(feat.name),
                     trailing: Icon(feat.icon),
+                    visualDensity: VisualDensity.compact,
                     onTap: () => unawaited(feat.onTap(ctx, ref)),
                   ),
                 );