diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp
index 2d1f6e68b..e61cf9223 100644
--- a/soh/soh/SaveManager.cpp
+++ b/soh/soh/SaveManager.cpp
@@ -47,6 +47,11 @@ std::filesystem::path SaveManager::GetFileName(int fileNum) {
     return sSavePath / ("file" + std::to_string(fileNum + 1) + ".sav");
 }
 
+std::filesystem::path SaveManager::GetFileTempName(int fileNum) {
+    const std::filesystem::path sSavePath(LUS::Context::GetPathRelativeToAppDirectory("Save"));
+    return sSavePath / ("file" + std::to_string(fileNum + 1) + ".temp");
+}
+
 SaveManager::SaveManager() {
     coreSectionIDsByName["base"] = SECTION_ID_BASE;
     coreSectionIDsByName["randomizer"] = SECTION_ID_RANDOMIZER;
@@ -874,6 +879,32 @@ void SaveManager::InitFileMaxed() {
     gSaveContext.sceneFlags[5].swch = 0x40000000;
 }
 
+#if defined(__WIIU__) || defined(__SWITCH__)
+// std::filesystem::copy_file doesn't work properly with the Wii U's toolchain atm
+int copy_file(const char* src, const char* dst) {
+    alignas(0x40) uint8_t buf[4096];
+    FILE* r = fopen(src, "r");
+    if (!r) {
+        return -1;
+    }
+    FILE* w = fopen(dst, "w");
+    if (!w) {
+        return -2;
+    }
+
+    size_t res;
+    while ((res = fread(buf, 1, sizeof(buf), r)) > 0) {
+        if (fwrite(buf, 1, res, w) != res) {
+            break;
+        }
+    }
+
+    fclose(r);
+    fclose(w);
+    return res >= 0 ? 0 : res;
+}
+#endif
+
 // Threaded SaveFile takes copy of gSaveContext for local unmodified storage
 
 void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int sectionID) {
@@ -915,19 +946,42 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se
         svi.func(saveContext, sectionID, false);
     }
 
+    std::filesystem::path fileName = GetFileName(fileNum);
+    std::filesystem::path tempFile = GetFileTempName(fileNum);
+
+    if (std::filesystem::exists(tempFile)) {
+        std::filesystem::remove(tempFile);
+    }
+
 #if defined(__SWITCH__) || defined(__WIIU__)
-    FILE* w = fopen(GetFileName(fileNum).c_str(), "w");
+    FILE* w = fopen(tempFile.c_str(), "w");
     std::string json_string = saveBlock.dump(4);
     fwrite(json_string.c_str(), sizeof(char), json_string.length(), w);
     fclose(w);
 #else
-    std::ofstream output(GetFileName(fileNum));
+    std::ofstream output(tempFile);
     output << std::setw(4) << saveBlock << std::endl;
+    output.close();
 #endif
 
+    if (std::filesystem::exists(fileName)) {
+        std::filesystem::remove(fileName);
+    }
+    
+#if defined(__SWITCH__) || defined(__WIIU__)
+    copy_file(tempFile.c_str(), fileName.c_str());
+#else
+    std::filesystem::copy_file(tempFile, fileName);
+#endif
+    
+    if (std::filesystem::exists(tempFile)) {
+        std::filesystem::remove(tempFile);
+    }
+
     delete saveContext;
     InitMeta(fileNum);
     GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaveFile>(fileNum);
+    SPDLOG_INFO("Save File Finish - fileNum: {}", fileNum);
 }
 
 // SaveSection creates a copy of gSaveContext to prevent mid-save data modification, and passes its reference to SaveFileThreaded
@@ -2110,32 +2164,6 @@ void SaveManager::LoadStruct(const std::string& name, LoadStructFunc func) {
     }
 }
 
-#if defined(__WIIU__) || defined(__SWITCH__)
-// std::filesystem::copy_file doesn't work properly with the Wii U's toolchain atm
-int copy_file(const char* src, const char* dst) {
-    alignas(0x40) uint8_t buf[4096];
-    FILE* r = fopen(src, "r");
-    if (!r) {
-        return -1;
-    }
-    FILE* w = fopen(dst, "w");
-    if (!w) {
-        return -2;
-    }
-
-    size_t res;
-    while ((res = fread(buf, 1, sizeof(buf), r)) > 0) {
-        if (fwrite(buf, 1, res, w) != res) {
-            break;
-        }
-    }
-
-    fclose(r);
-    fclose(w);
-    return res >= 0 ? 0 : res;
-}
-#endif
-
 void SaveManager::CopyZeldaFile(int from, int to) {
     assert(std::filesystem::exists(GetFileName(from)));
     DeleteZeldaFile(to);
diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h
index 892aec923..310ecda7d 100644
--- a/soh/soh/SaveManager.h
+++ b/soh/soh/SaveManager.h
@@ -142,6 +142,7 @@ class SaveManager {
 
   private:
     std::filesystem::path GetFileName(int fileNum);
+    std::filesystem::path GetFileTempName(int fileNum);
     nlohmann::json saveBlock;
 
     void ConvertFromUnversioned();