diff --git a/app/lib/entity/album/data_source.dart b/app/lib/entity/album/data_source.dart
index 20b4169d..5c79e268 100644
--- a/app/lib/entity/album/data_source.dart
+++ b/app/lib/entity/album/data_source.dart
@@ -189,7 +189,8 @@ class AlbumSqliteDbDataSource implements AlbumDataSource {
     await _c.sqliteDb.use((db) async {
       final rowIds =
           await db.accountFileRowIdsOf(album.albumFile!, appAccount: account);
-      final insert = SqliteAlbumConverter.toSql(album, rowIds.fileRowId);
+      final insert = SqliteAlbumConverter.toSql(
+          album, rowIds.fileRowId, album.albumFile!.etag!);
       var rowId = await _updateCache(db, rowIds.fileRowId, insert.album);
       if (rowId == null) {
         // new album, need insert
diff --git a/app/lib/entity/sqlite_table.dart b/app/lib/entity/sqlite_table.dart
index cec88932..e4b517fe 100644
--- a/app/lib/entity/sqlite_table.dart
+++ b/app/lib/entity/sqlite_table.dart
@@ -135,6 +135,8 @@ class Albums extends Table {
   IntColumn get file => integer()
       .references(Files, #rowId, onDelete: KeyAction.cascade)
       .unique()();
+  // store the etag of the file when the album is cached in the db
+  TextColumn get fileEtag => text().nullable()();
   IntColumn get version => integer()();
   DateTimeColumn get lastUpdated =>
       dateTime().map(const _DateTimeConverter())();
@@ -218,7 +220,7 @@ class SqliteDb extends _$SqliteDb {
   SqliteDb.connect(DatabaseConnection connection) : super.connect(connection);
 
   @override
-  get schemaVersion => 3;
+  get schemaVersion => 4;
 
   @override
   get migration => MigrationStrategy(
@@ -263,6 +265,9 @@ class SqliteDb extends _$SqliteDb {
                 await m.createTable(imageLocations);
                 await _createIndexV3(m);
               }
+              if (from < 4) {
+                await m.addColumn(albums, albums.fileEtag);
+              }
             });
           } catch (e, stackTrace) {
             _log.shout("[onUpgrade] Failed upgrading sqlite db", e, stackTrace);
diff --git a/app/lib/entity/sqlite_table.g.dart b/app/lib/entity/sqlite_table.g.dart
index 32b9cca4..bbe0e43f 100644
--- a/app/lib/entity/sqlite_table.g.dart
+++ b/app/lib/entity/sqlite_table.g.dart
@@ -2671,6 +2671,7 @@ class $DirFilesTable extends DirFiles with TableInfo<$DirFilesTable, DirFile> {
 class Album extends DataClass implements Insertable<Album> {
   final int rowId;
   final int file;
+  final String? fileEtag;
   final int version;
   final DateTime lastUpdated;
   final String name;
@@ -2683,6 +2684,7 @@ class Album extends DataClass implements Insertable<Album> {
   Album(
       {required this.rowId,
       required this.file,
+      this.fileEtag,
       required this.version,
       required this.lastUpdated,
       required this.name,
@@ -2699,6 +2701,8 @@ class Album extends DataClass implements Insertable<Album> {
           .mapFromDatabaseResponse(data['${effectivePrefix}row_id'])!,
       file: const IntType()
           .mapFromDatabaseResponse(data['${effectivePrefix}file'])!,
+      fileEtag: const StringType()
+          .mapFromDatabaseResponse(data['${effectivePrefix}file_etag']),
       version: const IntType()
           .mapFromDatabaseResponse(data['${effectivePrefix}version'])!,
       lastUpdated: $AlbumsTable.$converter0.mapToDart(const DateTimeType()
@@ -2724,6 +2728,9 @@ class Album extends DataClass implements Insertable<Album> {
     final map = <String, Expression>{};
     map['row_id'] = Variable<int>(rowId);
     map['file'] = Variable<int>(file);
+    if (!nullToAbsent || fileEtag != null) {
+      map['file_etag'] = Variable<String?>(fileEtag);
+    }
     map['version'] = Variable<int>(version);
     {
       final converter = $AlbumsTable.$converter0;
@@ -2744,6 +2751,9 @@ class Album extends DataClass implements Insertable<Album> {
     return AlbumsCompanion(
       rowId: Value(rowId),
       file: Value(file),
+      fileEtag: fileEtag == null && nullToAbsent
+          ? const Value.absent()
+          : Value(fileEtag),
       version: Value(version),
       lastUpdated: Value(lastUpdated),
       name: Value(name),
@@ -2762,6 +2772,7 @@ class Album extends DataClass implements Insertable<Album> {
     return Album(
       rowId: serializer.fromJson<int>(json['rowId']),
       file: serializer.fromJson<int>(json['file']),
+      fileEtag: serializer.fromJson<String?>(json['fileEtag']),
       version: serializer.fromJson<int>(json['version']),
       lastUpdated: serializer.fromJson<DateTime>(json['lastUpdated']),
       name: serializer.fromJson<String>(json['name']),
@@ -2781,6 +2792,7 @@ class Album extends DataClass implements Insertable<Album> {
     return <String, dynamic>{
       'rowId': serializer.toJson<int>(rowId),
       'file': serializer.toJson<int>(file),
+      'fileEtag': serializer.toJson<String?>(fileEtag),
       'version': serializer.toJson<int>(version),
       'lastUpdated': serializer.toJson<DateTime>(lastUpdated),
       'name': serializer.toJson<String>(name),
@@ -2796,6 +2808,7 @@ class Album extends DataClass implements Insertable<Album> {
   Album copyWith(
           {int? rowId,
           int? file,
+          Value<String?> fileEtag = const Value.absent(),
           int? version,
           DateTime? lastUpdated,
           String? name,
@@ -2808,6 +2821,7 @@ class Album extends DataClass implements Insertable<Album> {
       Album(
         rowId: rowId ?? this.rowId,
         file: file ?? this.file,
+        fileEtag: fileEtag.present ? fileEtag.value : this.fileEtag,
         version: version ?? this.version,
         lastUpdated: lastUpdated ?? this.lastUpdated,
         name: name ?? this.name,
@@ -2823,6 +2837,7 @@ class Album extends DataClass implements Insertable<Album> {
     return (StringBuffer('Album(')
           ..write('rowId: $rowId, ')
           ..write('file: $file, ')
+          ..write('fileEtag: $fileEtag, ')
           ..write('version: $version, ')
           ..write('lastUpdated: $lastUpdated, ')
           ..write('name: $name, ')
@@ -2840,6 +2855,7 @@ class Album extends DataClass implements Insertable<Album> {
   int get hashCode => Object.hash(
       rowId,
       file,
+      fileEtag,
       version,
       lastUpdated,
       name,
@@ -2855,6 +2871,7 @@ class Album extends DataClass implements Insertable<Album> {
       (other is Album &&
           other.rowId == this.rowId &&
           other.file == this.file &&
+          other.fileEtag == this.fileEtag &&
           other.version == this.version &&
           other.lastUpdated == this.lastUpdated &&
           other.name == this.name &&
@@ -2869,6 +2886,7 @@ class Album extends DataClass implements Insertable<Album> {
 class AlbumsCompanion extends UpdateCompanion<Album> {
   final Value<int> rowId;
   final Value<int> file;
+  final Value<String?> fileEtag;
   final Value<int> version;
   final Value<DateTime> lastUpdated;
   final Value<String> name;
@@ -2881,6 +2899,7 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
   const AlbumsCompanion({
     this.rowId = const Value.absent(),
     this.file = const Value.absent(),
+    this.fileEtag = const Value.absent(),
     this.version = const Value.absent(),
     this.lastUpdated = const Value.absent(),
     this.name = const Value.absent(),
@@ -2894,6 +2913,7 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
   AlbumsCompanion.insert({
     this.rowId = const Value.absent(),
     required int file,
+    this.fileEtag = const Value.absent(),
     required int version,
     required DateTime lastUpdated,
     required String name,
@@ -2916,6 +2936,7 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
   static Insertable<Album> custom({
     Expression<int>? rowId,
     Expression<int>? file,
+    Expression<String?>? fileEtag,
     Expression<int>? version,
     Expression<DateTime>? lastUpdated,
     Expression<String>? name,
@@ -2929,6 +2950,7 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
     return RawValuesInsertable({
       if (rowId != null) 'row_id': rowId,
       if (file != null) 'file': file,
+      if (fileEtag != null) 'file_etag': fileEtag,
       if (version != null) 'version': version,
       if (lastUpdated != null) 'last_updated': lastUpdated,
       if (name != null) 'name': name,
@@ -2946,6 +2968,7 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
   AlbumsCompanion copyWith(
       {Value<int>? rowId,
       Value<int>? file,
+      Value<String?>? fileEtag,
       Value<int>? version,
       Value<DateTime>? lastUpdated,
       Value<String>? name,
@@ -2958,6 +2981,7 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
     return AlbumsCompanion(
       rowId: rowId ?? this.rowId,
       file: file ?? this.file,
+      fileEtag: fileEtag ?? this.fileEtag,
       version: version ?? this.version,
       lastUpdated: lastUpdated ?? this.lastUpdated,
       name: name ?? this.name,
@@ -2979,6 +3003,9 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
     if (file.present) {
       map['file'] = Variable<int>(file.value);
     }
+    if (fileEtag.present) {
+      map['file_etag'] = Variable<String?>(fileEtag.value);
+    }
     if (version.present) {
       map['version'] = Variable<int>(version.value);
     }
@@ -3018,6 +3045,7 @@ class AlbumsCompanion extends UpdateCompanion<Album> {
     return (StringBuffer('AlbumsCompanion(')
           ..write('rowId: $rowId, ')
           ..write('file: $file, ')
+          ..write('fileEtag: $fileEtag, ')
           ..write('version: $version, ')
           ..write('lastUpdated: $lastUpdated, ')
           ..write('name: $name, ')
@@ -3051,6 +3079,11 @@ class $AlbumsTable extends Albums with TableInfo<$AlbumsTable, Album> {
       type: const IntType(),
       requiredDuringInsert: true,
       defaultConstraints: 'UNIQUE REFERENCES files (row_id) ON DELETE CASCADE');
+  final VerificationMeta _fileEtagMeta = const VerificationMeta('fileEtag');
+  @override
+  late final GeneratedColumn<String?> fileEtag = GeneratedColumn<String?>(
+      'file_etag', aliasedName, true,
+      type: const StringType(), requiredDuringInsert: false);
   final VerificationMeta _versionMeta = const VerificationMeta('version');
   @override
   late final GeneratedColumn<int?> version = GeneratedColumn<int?>(
@@ -3108,6 +3141,7 @@ class $AlbumsTable extends Albums with TableInfo<$AlbumsTable, Album> {
   List<GeneratedColumn> get $columns => [
         rowId,
         file,
+        fileEtag,
         version,
         lastUpdated,
         name,
@@ -3137,6 +3171,10 @@ class $AlbumsTable extends Albums with TableInfo<$AlbumsTable, Album> {
     } else if (isInserting) {
       context.missing(_fileMeta);
     }
+    if (data.containsKey('file_etag')) {
+      context.handle(_fileEtagMeta,
+          fileEtag.isAcceptableOrUnknown(data['file_etag']!, _fileEtagMeta));
+    }
     if (data.containsKey('version')) {
       context.handle(_versionMeta,
           version.isAcceptableOrUnknown(data['version']!, _versionMeta));
diff --git a/app/lib/entity/sqlite_table_converter.dart b/app/lib/entity/sqlite_table_converter.dart
index 1f51d9db..213e958c 100644
--- a/app/lib/entity/sqlite_table_converter.dart
+++ b/app/lib/entity/sqlite_table_converter.dart
@@ -14,6 +14,7 @@ import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql;
 import 'package:nc_photos/entity/tag.dart';
 import 'package:nc_photos/iterable_extension.dart';
 import 'package:nc_photos/object_extension.dart';
+import 'package:nc_photos/or_null.dart';
 
 extension SqlTagListExtension on List<sql.Tag> {
   Future<List<Tag>> convertToAppTag() {
@@ -74,17 +75,20 @@ class SqliteAlbumConverter {
                     sharedAt: e.sharedAt.toUtc(),
                   ))
               .toList(),
-      albumFile: albumFile,
+      // replace with the original etag when this album was cached
+      albumFile: albumFile.copyWith(etag: OrNull(album.fileEtag)),
       savedVersion: album.version,
     );
   }
 
-  static sql.CompleteAlbumCompanion toSql(Album album, int albumFileRowId) {
+  static sql.CompleteAlbumCompanion toSql(
+      Album album, int albumFileRowId, String albumFileEtag) {
     final providerJson = album.provider.toJson();
     final coverProviderJson = album.coverProvider.toJson();
     final sortProviderJson = album.sortProvider.toJson();
     final dbAlbum = sql.AlbumsCompanion.insert(
       file: albumFileRowId,
+      fileEtag: Value(albumFileEtag),
       version: Album.version,
       lastUpdated: album.lastUpdated,
       name: album.name,