diff --git a/src/authority/storagehelper.cpp b/src/authority/storagehelper.cpp
index 2cd215630cdc35021ed66dd1f1ba86c6d2d6e3a2..d2e9d19d1b4cb3fd8705b4189761a61d71d72df7 100644
--- a/src/authority/storagehelper.cpp
+++ b/src/authority/storagehelper.cpp
@@ -1201,20 +1201,27 @@ migrateIfNeeded(const QStringList& accountIds,
         oldDataDir.removeRecursively();
     }
 
-    // first check if there is any legacy data storage to migrate
-    {
-        if (not QFile(dataDir.absoluteFilePath("ring.db")).exists() &&
-            not QDir(dataDir.absoluteFilePath("text/")).exists() &&
-            not QDir(dataDir.absoluteFilePath("profiles/")).exists() &&
-            not QDir(dataDir.absoluteFilePath("peer_profiles/")).exists()) {
-            qDebug() << "No migration required";
-            return dbs;
-        }
+    bool needsMigration = false;
+    std::map<QString, bool> hasMigratedData;
+    for (const auto& accountId : accountIds) {
+        auto hasMigratedDb = QFile(appPath + accountId + "/history.db").exists() &&
+                            !QFile(appPath + accountId + "/history.db-journal").exists();
+        hasMigratedData.insert(std::make_pair(accountId, hasMigratedDb));
+        needsMigration |= !hasMigratedDb;
+    }
+    if (!needsMigration) {
+        // if there's any lingering pre-migration data, remove it
+        QFile(dataDir.absoluteFilePath("ring.db")).remove();
+        QDir(dataDir.absoluteFilePath("text/")).removeRecursively();
+        QDir(dataDir.absoluteFilePath("profiles/")).removeRecursively();
+        QDir(dataDir.absoluteFilePath("peer_profiles/")).removeRecursively();
+        qDebug() << "No migration required";
+        return dbs;
     }
 
     // A fairly long migration may now occur
     std::thread migrateThread(
-        [&appPath, &accountIds, &dbs, &didMigrateCb, &dataDir] {
+        [&appPath, &accountIds, &dbs, &didMigrateCb, &dataDir, &hasMigratedData] {
             // 1. migrate old lrc -> new lrc if needed
             // 2. migrate new lrc db version 1 -> db version 1.1 if needed
             // the destructor of LegacyDatabase will remove 'ring.db' and clean out
@@ -1237,32 +1244,32 @@ migrateIfNeeded(const QStringList& accountIds,
                 }
             }
 
-            // clean out any potentially failed previous migration attempts thwarted
-            // by client termination before starting the migration process
-            for (auto accountId : accountIds) {
-                QFile(appPath + accountId + "/history.db").remove();
-                QFile(appPath + accountId + "/history.db-journal").remove();
-                QFile(appPath + accountId + "/profile.vcf").remove();
-                QDir(appPath + accountId + "/profiles/").removeRecursively();
-            }
-
             // 3. migrate db version 1.1 -> per account dbs version 1
             int index = 0;
-            for (auto accountId : accountIds) {
+            for (const auto& accountId : accountIds) {
+                if (hasMigratedData.at(accountId)) {
+                    index++;
+                    continue;
+                }
                 qDebug() << "Migrating account: " << accountId << "...";
+                // try to remove the transaction journal from a failed migration
+                QFile(appPath + accountId + "/history.db-journal").remove();
                 try {
+                    QSqlDatabase::database().transaction();
                     auto dbName = QString::fromStdString(accountId.toStdString() + "/history");
                     dbs.at(index) = lrc::DatabaseFactory::create<Database>(dbName, appPath);
                     auto& db = dbs.at(index++);
                     migration::migrateAccountDb(accountId, db, legacyDb);
+                    QSqlDatabase::database().commit();
                 } catch (const std::runtime_error& e) {
                     qWarning().noquote()
                         << "Could not migrate database for account: "
                         << accountId << "\n " << e.what();
+                    QSqlDatabase::database().rollback();
                 }
             }
 
-            // done!
+            // done
             if (didMigrateCb)
                 didMigrateCb();
         });