diff --git a/v2rayN/ServiceLib/Common/ProcUtils.cs b/v2rayN/ServiceLib/Common/ProcUtils.cs
index f9cc8ccd..ded6f4d8 100644
--- a/v2rayN/ServiceLib/Common/ProcUtils.cs
+++ b/v2rayN/ServiceLib/Common/ProcUtils.cs
@@ -86,17 +86,43 @@ public static class ProcUtils
         GetProcessKeyInfo(proc, review, out var procId, out var fileName, out var processName);
 
         try
-        { proc?.Kill(true); }
-        catch (Exception ex) { Logging.SaveLog(_tag, ex); }
+        {
+            if (Utils.IsNonWindows())
+            {
+                proc?.Kill(true);
+            }
+        }
+        catch (Exception ex)
+        {
+            Logging.SaveLog(_tag, ex);
+        }
+
         try
-        { proc?.Kill(); }
-        catch (Exception ex) { Logging.SaveLog(_tag, ex); }
+        {
+            proc?.Kill();
+        }
+        catch (Exception ex)
+        {
+            Logging.SaveLog(_tag, ex);
+        }
+
         try
-        { proc?.Close(); }
-        catch (Exception ex) { Logging.SaveLog(_tag, ex); }
+        {
+            proc?.Close();
+        }
+        catch (Exception ex)
+        {
+            Logging.SaveLog(_tag, ex);
+        }
+
         try
-        { proc?.Dispose(); }
-        catch (Exception ex) { Logging.SaveLog(_tag, ex); }
+        {
+            proc?.Dispose();
+        }
+        catch (Exception ex)
+        {
+            Logging.SaveLog(_tag, ex);
+        }
 
         await Task.Delay(300);
         await ProcessKillByKeyInfo(review, procId, fileName, processName);
diff --git a/v2rayN/ServiceLib/Common/Utils.cs b/v2rayN/ServiceLib/Common/Utils.cs
index f4b60f3c..15f111d4 100644
--- a/v2rayN/ServiceLib/Common/Utils.cs
+++ b/v2rayN/ServiceLib/Common/Utils.cs
@@ -433,10 +433,22 @@ namespace ServiceLib.Common
         {
             try
             {
-                var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
-                var ipEndPoints = ipProperties.GetActiveTcpListeners();
-                //var lstIpEndPoints = new List<IPEndPoint>(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
-                return ipEndPoints.Any(endPoint => endPoint.Port == port);
+                List<IPEndPoint> lstIpEndPoints = new();
+                List<TcpConnectionInformation> lstTcpConns = new();
+
+                lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
+                lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
+                lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
+
+                if (lstIpEndPoints?.FindIndex(it => it.Port == port) >= 0)
+                {
+                    return true;
+                }
+
+                if (lstTcpConns?.FindIndex(it => it.LocalEndPoint.Port == port) >= 0)
+                {
+                    return true;
+                }
             }
             catch (Exception ex)
             {
@@ -786,6 +798,24 @@ namespace ServiceLib.Common
             }
         }
 
+        public static string GetBinConfigPath(string filename = "")
+        {
+            var tempPath = Path.Combine(StartupPath(), "binConfigs");
+            if (!Directory.Exists(tempPath))
+            {
+                Directory.CreateDirectory(tempPath);
+            }
+
+            if (Utils.IsNullOrEmpty(filename))
+            {
+                return tempPath;
+            }
+            else
+            {
+                return Path.Combine(tempPath, filename);
+            }
+        }
+
         #endregion TempPath
 
         #region Platform
diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs
index eb4da4ab..0e874ae0 100644
--- a/v2rayN/ServiceLib/Global.cs
+++ b/v2rayN/ServiceLib/Global.cs
@@ -16,7 +16,7 @@ namespace ServiceLib
         public const string ConfigFileName = "guiNConfig.json";
         public const string CoreConfigFileName = "config.json";
         public const string CorePreConfigFileName = "configPre.json";
-        public const string CoreSpeedtestConfigFileName = "configSpeedtest.json";
+        public const string CoreSpeedtestConfigFileName = "configTest{0}.json";
         public const string CoreMultipleLoadConfigFileName = "configMultipleLoad.json";
         public const string ClashMixinConfigFileName = "Mixin.yaml";
 
diff --git a/v2rayN/ServiceLib/Handler/AppHandler.cs b/v2rayN/ServiceLib/Handler/AppHandler.cs
index 72a080e8..cf0f73af 100644
--- a/v2rayN/ServiceLib/Handler/AppHandler.cs
+++ b/v2rayN/ServiceLib/Handler/AppHandler.cs
@@ -1,4 +1,4 @@
-namespace ServiceLib.Handler
+namespace ServiceLib.Handler
 {
     public sealed class AppHandler
     {
@@ -98,6 +98,7 @@
             {
                 FileManager.DeleteExpiredFiles(Utils.GetLogPath(), DateTime.Now.AddMonths(-1));
                 FileManager.DeleteExpiredFiles(Utils.GetTempPath(), DateTime.Now.AddMonths(-1));
+                FileManager.DeleteExpiredFiles(Utils.GetBinConfigPath(), DateTime.Now.AddHours(-1));
             });
         }
 
@@ -252,4 +253,4 @@
 
         #endregion Core Type
     }
-}
\ No newline at end of file
+}
diff --git a/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs b/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
index 8713b8dd..11982882 100644
--- a/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
@@ -1,4 +1,4 @@
-namespace ServiceLib.Handler
+namespace ServiceLib.Handler
 {
     /// <summary>
     /// Core configuration file processing class
@@ -109,6 +109,30 @@
             return result;
         }
 
+        public static async Task<RetResult> GenerateClientSpeedtestConfig(Config config, ProfileItem node, ServerTestItem testItem, string fileName)
+        {
+            var result = new RetResult();
+            var initPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.speedtest);
+            var port = Utils.GetFreePort(initPort + testItem.QueueNum);
+            testItem.Port = port;
+
+            if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box)
+            {
+                result = await new CoreConfigSingboxService(config).GenerateClientSpeedtestConfig(node, port);
+            }
+            else
+            {
+                result = await new CoreConfigV2rayService(config).GenerateClientSpeedtestConfig(node, port);
+            }
+            if (result.Success != true)
+            {
+                return result;
+            }
+
+            await File.WriteAllTextAsync(fileName, result.Data.ToString());
+            return result;
+        }
+
         public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType)
         {
             var result = new RetResult();
@@ -129,4 +153,4 @@
             return result;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs
index dbd93081..08615879 100644
--- a/v2rayN/ServiceLib/Handler/CoreHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs
@@ -70,7 +70,7 @@ namespace ServiceLib.Handler
                 return;
             }
 
-            var fileName = Utils.GetConfigPath(Global.CoreConfigFileName);
+            var fileName = Utils.GetBinConfigPath(Global.CoreConfigFileName);
             var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
             if (result.Success != true)
             {
@@ -101,7 +101,8 @@ namespace ServiceLib.Handler
         public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
         {
             var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) ? ECoreType.sing_box : ECoreType.Xray;
-            var configPath = Utils.GetConfigPath(Global.CoreSpeedtestConfigFileName);
+            var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false));
+            var configPath = Utils.GetBinConfigPath(fileName);
             var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
             UpdateFunc(false, result.Msg);
             if (result.Success != true)
@@ -113,7 +114,34 @@ namespace ServiceLib.Handler
             UpdateFunc(false, configPath);
 
             var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
-            var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true, false);
+            var proc = await RunProcess(coreInfo, fileName, true, false);
+            if (proc is null)
+            {
+                return -1;
+            }
+
+            return proc.Id;
+        }
+
+        public async Task<int> LoadCoreConfigSpeedtest(ServerTestItem testItem)
+        {
+            var node = await AppHandler.Instance.GetProfileItem(testItem.IndexId);
+            if (node is null)
+            {
+                return -1;
+            }
+
+            var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false));
+            var configPath = Utils.GetBinConfigPath(fileName);
+            var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, node, testItem, configPath);
+            if (result.Success != true)
+            {
+                return -1;
+            }
+
+            var coreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
+            var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
+            var proc = await CoreHandler.Instance.RunProcess(coreInfo, fileName, true, false);
             if (proc is null)
             {
                 return -1;
@@ -175,7 +203,7 @@ namespace ServiceLib.Handler
                 if (itemSocks != null)
                 {
                     var preCoreType = itemSocks.CoreType ?? ECoreType.sing_box;
-                    var fileName = Utils.GetConfigPath(Global.CorePreConfigFileName);
+                    var fileName = Utils.GetBinConfigPath(Global.CorePreConfigFileName);
                     var result = await CoreConfigHandler.GenerateClientConfig(itemSocks, fileName);
                     if (result.Success)
                     {
@@ -225,8 +253,8 @@ namespace ServiceLib.Handler
                     StartInfo = new()
                     {
                         FileName = fileName,
-                        Arguments = string.Format(coreInfo.Arguments, coreInfo.AbsolutePath ? Utils.GetConfigPath(configPath) : configPath),
-                        WorkingDirectory = Utils.GetConfigPath(),
+                        Arguments = string.Format(coreInfo.Arguments, coreInfo.AbsolutePath ? Utils.GetBinConfigPath(configPath) : configPath),
+                        WorkingDirectory = Utils.GetBinConfigPath(),
                         UseShellExecute = false,
                         RedirectStandardOutput = displayLog,
                         RedirectStandardError = displayLog,
@@ -298,7 +326,7 @@ namespace ServiceLib.Handler
 
         private async Task RunProcessAsLinuxSudo(Process proc, string fileName, CoreInfo coreInfo, string configPath)
         {
-            var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetConfigPath(configPath).AppendQuotes())}";
+            var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
 
             var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
             proc.StartInfo.FileName = shFilePath;
diff --git a/v2rayN/ServiceLib/Models/ServerTestItem.cs b/v2rayN/ServiceLib/Models/ServerTestItem.cs
index 1a6352f6..99e45d2b 100644
--- a/v2rayN/ServiceLib/Models/ServerTestItem.cs
+++ b/v2rayN/ServiceLib/Models/ServerTestItem.cs
@@ -1,4 +1,4 @@
-namespace ServiceLib.Models
+namespace ServiceLib.Models
 {
     [Serializable]
     public class ServerTestItem
@@ -8,6 +8,6 @@
         public int Port { get; set; }
         public EConfigType ConfigType { get; set; }
         public bool AllowTest { get; set; }
-        public int Delay { get; set; }
+        public int QueueNum { get; set; }
     }
-}
\ No newline at end of file
+}
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
index 3b044f57..cd11ecd1 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs
@@ -242,6 +242,66 @@ namespace ServiceLib.Services.CoreConfig
             }
         }
 
+        public async Task<RetResult> GenerateClientSpeedtestConfig(ProfileItem node, int port)
+        {
+            var ret = new RetResult();
+            try
+            {
+                if (node is not { Port: > 0 })
+                {
+                    ret.Msg = ResUI.CheckServerSettings;
+                    return ret;
+                }
+                if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp))
+                {
+                    ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
+                    return ret;
+                }
+
+                ret.Msg = ResUI.InitialConfiguration;
+
+                var result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
+                if (Utils.IsNullOrEmpty(result))
+                {
+                    ret.Msg = ResUI.FailedGetDefaultConfiguration;
+                    return ret;
+                }
+
+                var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result);
+                if (singboxConfig == null)
+                {
+                    ret.Msg = ResUI.FailedGenDefaultConfiguration;
+                    return ret;
+                }
+
+                await GenLog(singboxConfig);
+                await GenOutbound(node, singboxConfig.outbounds.First());
+                await GenMoreOutbounds(node, singboxConfig);
+                await GenDnsDomains(null, singboxConfig, null);
+
+                singboxConfig.route.rules.Clear();
+                singboxConfig.inbounds.Clear();
+                singboxConfig.inbounds.Add(new()
+                {
+                    tag = $"{EInboundProtocol.mixed}{port}",
+                    listen = Global.Loopback,
+                    listen_port = port,
+                    type = EInboundProtocol.mixed.ToString(),
+                });
+
+                ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
+                ret.Success = true;
+                ret.Data = JsonUtils.Serialize(singboxConfig);
+                return ret;
+            }
+            catch (Exception ex)
+            {
+                Logging.SaveLog(_tag, ex);
+                ret.Msg = ResUI.FailedGenDefaultConfiguration;
+                return ret;
+            }
+        }
+
         public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
         {
             var ret = new RetResult();
@@ -1264,7 +1324,7 @@ namespace ServiceLib.Services.CoreConfig
                 singboxConfig.experimental.cache_file = new CacheFile4Sbox()
                 {
                     enabled = true,
-                    path = Utils.GetConfigPath("cache.db")
+                    path = Utils.GetBinConfigPath("cache.db")
                 };
             }
 
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs
index c79cc56c..46c99e97 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs
@@ -353,6 +353,64 @@ namespace ServiceLib.Services.CoreConfig
             }
         }
 
+        public async Task<RetResult> GenerateClientSpeedtestConfig(ProfileItem node, int port)
+        {
+            var ret = new RetResult();
+            try
+            {
+                if (node is not { Port: > 0 })
+                {
+                    ret.Msg = ResUI.CheckServerSettings;
+                    return ret;
+                }
+
+                if (node.GetNetwork() is nameof(ETransport.quic))
+                {
+                    ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
+                    return ret;
+                }
+
+                var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
+                if (Utils.IsNullOrEmpty(result))
+                {
+                    ret.Msg = ResUI.FailedGetDefaultConfiguration;
+                    return ret;
+                }
+
+                var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
+                if (v2rayConfig == null)
+                {
+                    ret.Msg = ResUI.FailedGenDefaultConfiguration;
+                    return ret;
+                }
+
+                await GenLog(v2rayConfig);
+                await GenOutbound(node, v2rayConfig.outbounds.First());
+                await GenMoreOutbounds(node, v2rayConfig);
+
+                v2rayConfig.routing.rules.Clear();
+                v2rayConfig.inbounds.Clear();
+                v2rayConfig.inbounds.Add(new()
+                {
+                    tag = $"{EInboundProtocol.socks}{port}",
+                    listen = Global.Loopback,
+                    port = port,
+                    protocol = EInboundProtocol.socks.ToString(),
+                });
+
+                ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
+                ret.Success = true;
+                ret.Data = JsonUtils.Serialize(v2rayConfig);
+                return ret;
+            }
+            catch (Exception ex)
+            {
+                Logging.SaveLog(_tag, ex);
+                ret.Msg = ResUI.FailedGenDefaultConfiguration;
+                return ret;
+            }
+        }
+
         #endregion public gen function
 
         #region private gen function
diff --git a/v2rayN/ServiceLib/Services/SpeedtestService.cs b/v2rayN/ServiceLib/Services/SpeedtestService.cs
index a978f2f5..6fe94284 100644
--- a/v2rayN/ServiceLib/Services/SpeedtestService.cs
+++ b/v2rayN/ServiceLib/Services/SpeedtestService.cs
@@ -22,12 +22,11 @@ namespace ServiceLib.Services
         {
             Task.Run(async () =>
             {
-                var exitLoopKey = Utils.GetGuid(false);
-                _lstExitLoop.Add(exitLoopKey);
-
-                var lstSelected = GetClearItem(actionType, selecteds);
-                await RunAsync(actionType, lstSelected, exitLoopKey);
+                await RunAsync(actionType, selecteds);
+                await ProfileExHandler.Instance.SaveTo();
                 UpdateFunc("", ResUI.SpeedtestingCompleted);
+
+                FileManager.DeleteExpiredFiles(Utils.GetBinConfigPath(), DateTime.Now.AddHours(-1));
             });
         }
 
@@ -41,49 +40,30 @@ namespace ServiceLib.Services
             }
         }
 
-        private async Task RunAsync(ESpeedActionType actionType, List<ServerTestItem> lstSelected, string exitLoopKey, int pageSize = 0)
+        private async Task RunAsync(ESpeedActionType actionType, List<ProfileItem> selecteds)
         {
-            if (actionType == ESpeedActionType.Tcping)
-            {
-                await RunTcpingAsync(lstSelected);
-                return;
-            }
+            var exitLoopKey = Utils.GetGuid(false);
+            _lstExitLoop.Add(exitLoopKey);
 
-            if (pageSize <= 0)
-            {
-                pageSize = lstSelected.Count < Global.SpeedTestPageSize ? lstSelected.Count : Global.SpeedTestPageSize;
-            }
-            var lstTest = GetTestBatchItem(lstSelected, pageSize);
+            var lstSelected = GetClearItem(actionType, selecteds);
 
-            List<ServerTestItem> lstFailed = new();
-            foreach (var lst in lstTest)
+            switch (actionType)
             {
-                var ret = actionType switch
-                {
-                    ESpeedActionType.Realping => await RunRealPingAsync(lst, exitLoopKey),
-                    ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst, exitLoopKey),
-                    ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst, exitLoopKey),
-                    _ => true
-                };
-                if (ret == false)
-                {
-                    lstFailed.AddRange(lst);
-                }
-                await Task.Delay(100);
-            }
+                case ESpeedActionType.Tcping:
+                    await RunTcpingAsync(lstSelected);
+                    break;
 
-            //Retest the failed part
-            var pageSizeNext = pageSize / 2;
-            if (lstFailed.Count > 0 && pageSizeNext > 0)
-            {
-                if (_lstExitLoop.Any(p => p == exitLoopKey) == false)
-                {
-                    UpdateFunc("", ResUI.SpeedtestingSkip);
-                    return;
-                }
+                case ESpeedActionType.Realping:
+                    await RunRealPingBatchAsync(lstSelected, exitLoopKey);
+                    break;
 
-                UpdateFunc("", string.Format(ResUI.SpeedtestingTestFailedPart, lstFailed.Count));
-                await RunAsync(actionType, lstFailed, exitLoopKey, pageSizeNext);
+                case ESpeedActionType.Speedtest:
+                    await RunMixedTestAsync(lstSelected, 1, exitLoopKey);
+                    break;
+
+                case ESpeedActionType.Mixedtest:
+                    await RunMixedTestAsync(lstSelected, 5, exitLoopKey);
+                    break;
             }
         }
 
@@ -107,7 +87,8 @@ namespace ServiceLib.Services
                     IndexId = it.IndexId,
                     Address = it.Address,
                     Port = it.Port,
-                    ConfigType = it.ConfigType
+                    ConfigType = it.ConfigType,
+                    QueueNum = selecteds.IndexOf(it)
                 });
             }
 
@@ -138,60 +119,65 @@ namespace ServiceLib.Services
             return lstSelected;
         }
 
-        private List<List<ServerTestItem>> GetTestBatchItem(List<ServerTestItem> lstSelected, int pageSize)
-        {
-            List<List<ServerTestItem>> lstTest = new();
-            var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard)).ToList();
-            var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard).ToList();
-
-            for (var num = 0; num < (int)Math.Ceiling(lst1.Count * 1.0 / pageSize); num++)
-            {
-                lstTest.Add(lst1.Skip(num * pageSize).Take(pageSize).ToList());
-            }
-            for (var num = 0; num < (int)Math.Ceiling(lst2.Count * 1.0 / pageSize); num++)
-            {
-                lstTest.Add(lst2.Skip(num * pageSize).Take(pageSize).ToList());
-            }
-
-            return lstTest;
-        }
-
         private async Task RunTcpingAsync(List<ServerTestItem> selecteds)
         {
-            try
+            List<Task> tasks = [];
+            foreach (var it in selecteds)
             {
-                List<Task> tasks = [];
-                foreach (var it in selecteds)
+                if (it.ConfigType == EConfigType.Custom)
                 {
-                    if (it.ConfigType == EConfigType.Custom)
-                    {
-                        continue;
-                    }
-                    tasks.Add(Task.Run(async () =>
-                    {
-                        try
-                        {
-                            var time = await GetTcpingTime(it.Address, it.Port);
-                            var output = FormatOut(time, Global.DelayUnit);
-
-                            ProfileExHandler.Instance.SetTestDelay(it.IndexId, output);
-                            UpdateFunc(it.IndexId, output);
-                        }
-                        catch (Exception ex)
-                        {
-                            Logging.SaveLog(_tag, ex);
-                        }
-                    }));
+                    continue;
                 }
-                Task.WaitAll([.. tasks]);
+                tasks.Add(Task.Run(async () =>
+                {
+                    try
+                    {
+                        var time = await GetTcpingTime(it.Address, it.Port);
+                        var output = FormatOut(time, Global.DelayUnit);
+
+                        ProfileExHandler.Instance.SetTestDelay(it.IndexId, output);
+                        UpdateFunc(it.IndexId, output);
+                    }
+                    catch (Exception ex)
+                    {
+                        Logging.SaveLog(_tag, ex);
+                    }
+                }));
             }
-            catch (Exception ex)
+            Task.WaitAll([.. tasks]);
+        }
+
+        private async Task RunRealPingBatchAsync(List<ServerTestItem> lstSelected, string exitLoopKey, int pageSize = 0)
+        {
+            if (pageSize <= 0)
             {
-                Logging.SaveLog(_tag, ex);
+                pageSize = lstSelected.Count < Global.SpeedTestPageSize ? lstSelected.Count : Global.SpeedTestPageSize;
             }
-            finally
+            var lstTest = GetTestBatchItem(lstSelected, pageSize);
+
+            List<ServerTestItem> lstFailed = new();
+            foreach (var lst in lstTest)
             {
-                await ProfileExHandler.Instance.SaveTo();
+                var ret = await RunRealPingAsync(lst, exitLoopKey);
+                if (ret == false)
+                {
+                    lstFailed.AddRange(lst);
+                }
+                await Task.Delay(100);
+            }
+
+            //Retest the failed part
+            var pageSizeNext = pageSize / 2;
+            if (lstFailed.Count > 0 && pageSizeNext > 0)
+            {
+                if (_lstExitLoop.Any(p => p == exitLoopKey) == false)
+                {
+                    UpdateFunc("", ResUI.SpeedtestingSkip);
+                    return;
+                }
+
+                UpdateFunc("", string.Format(ResUI.SpeedtestingTestFailedPart, lstFailed.Count));
+                await RunRealPingBatchAsync(lstFailed, exitLoopKey, pageSizeNext);
             }
         }
 
@@ -221,20 +207,7 @@ namespace ServiceLib.Services
                     }
                     tasks.Add(Task.Run(async () =>
                     {
-                        try
-                        {
-                            var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
-                            var output = await GetRealPingTime(downloadHandle, webProxy);
-
-                            ProfileExHandler.Instance.SetTestDelay(it.IndexId, output);
-                            UpdateFunc(it.IndexId, output);
-                            int.TryParse(output, out var delay);
-                            it.Delay = delay;
-                        }
-                        catch (Exception ex)
-                        {
-                            Logging.SaveLog(_tag, ex);
-                        }
+                        await DoRealPing(downloadHandle, it);
                     }));
                 }
                 Task.WaitAll(tasks.ToArray());
@@ -249,25 +222,15 @@ namespace ServiceLib.Services
                 {
                     await ProcUtils.ProcessKill(pid);
                 }
-                await ProfileExHandler.Instance.SaveTo();
             }
             return true;
         }
 
-        private async Task<bool> RunSpeedTestAsync(List<ServerTestItem> selecteds, string exitLoopKey)
+        private async Task RunMixedTestAsync(List<ServerTestItem> selecteds, int concurrencyCount, string exitLoopKey)
         {
-            var pid = -1;
-            pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds);
-            if (pid < 0)
-            {
-                return false;
-            }
-
-            var url = _config.SpeedTestItem.SpeedTestUrl;
-            var timeout = _config.SpeedTestItem.SpeedTestTimeout;
-
-            DownloadService downloadHandle = new();
-
+            using var concurrencySemaphore = new SemaphoreSlim(concurrencyCount);
+            var downloadHandle = new DownloadService();
+            List<Task> tasks = new();
             foreach (var it in selecteds)
             {
                 if (_lstExitLoop.Any(p => p == exitLoopKey) == false)
@@ -275,135 +238,73 @@ namespace ServiceLib.Services
                     UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip);
                     continue;
                 }
-
-                if (!it.AllowTest)
-                {
-                    continue;
-                }
                 if (it.ConfigType == EConfigType.Custom)
                 {
                     continue;
                 }
-                //if (it.delay < 0)
-                //{
-                //    UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
-                //    continue;
-                //}
-                ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1");
-                UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
+                await concurrencySemaphore.WaitAsync();
 
-                var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
-                if (item is null)
-                    continue;
-
-                var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
-
-                await downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) =>
+                tasks.Add(Task.Run(async () =>
                 {
-                    decimal.TryParse(msg, out var dec);
-                    if (dec > 0)
+                    var pid = -1;
+                    try
                     {
-                        ProfileExHandler.Instance.SetTestSpeed(it.IndexId, msg);
+                        pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(it);
+                        if (pid > 0)
+                        {
+                            await Task.Delay(1000);
+                            await DoRealPing(downloadHandle, it);
+                            await DoSpeedTest(downloadHandle, it);
+                        }
+                        else
+                        {
+                            UpdateFunc(it.IndexId, "", ResUI.FailedToRunCore);
+                        }
                     }
-                    UpdateFunc(it.IndexId, "", msg);
-                });
-            }
-
-            if (pid > 0)
-            {
-                await ProcUtils.ProcessKill(pid);
-            }
-            await ProfileExHandler.Instance.SaveTo();
-            return true;
-        }
-
-        private async Task<bool> RunSpeedTestMultiAsync(List<ServerTestItem> selecteds, string exitLoopKey)
-        {
-            var pid = -1;
-            pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds);
-            if (pid < 0)
-            {
-                return false;
-            }
-
-            var url = _config.SpeedTestItem.SpeedTestUrl;
-            var timeout = _config.SpeedTestItem.SpeedTestTimeout;
-
-            DownloadService downloadHandle = new();
-
-            foreach (var it in selecteds)
-            {
-                if (_lstExitLoop.Any(p => p == exitLoopKey) == false)
-                {
-                    UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip);
-                    continue;
-                }
-
-                if (!it.AllowTest)
-                {
-                    continue;
-                }
-                if (it.ConfigType == EConfigType.Custom)
-                {
-                    continue;
-                }
-                if (it.Delay < 0)
-                {
-                    UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip);
-                    continue;
-                }
-                ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1");
-                UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
-
-                var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
-                if (item is null)
-                    continue;
-
-                var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
-                _ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) =>
-                {
-                    decimal.TryParse(msg, out var dec);
-                    if (dec > 0)
+                    catch (Exception ex)
                     {
-                        ProfileExHandler.Instance.SetTestSpeed(it.IndexId, msg);
+                        Logging.SaveLog(_tag, ex);
                     }
-                    UpdateFunc(it.IndexId, "", msg);
-                });
-                await Task.Delay(2000);
+                    finally
+                    {
+                        if (pid > 0)
+                        {
+                            await ProcUtils.ProcessKill(pid);
+                        }
+                        concurrencySemaphore.Release();
+                    }
+                }));
             }
-
-            await Task.Delay((timeout + 2) * 1000);
-
-            if (pid > 0)
-            {
-                await ProcUtils.ProcessKill(pid);
-            }
-            await ProfileExHandler.Instance.SaveTo();
-            return true;
+            Task.WaitAll(tasks.ToArray());
         }
 
-        private async Task<bool> RunMixedTestAsync(List<ServerTestItem> selecteds, string exitLoopKey)
-        {
-            var ret = await RunRealPingAsync(selecteds, exitLoopKey);
-            if (ret == false)
-            {
-                return false;
-            }
-
-            await Task.Delay(1000);
-
-            var ret2 = await RunSpeedTestMultiAsync(selecteds, exitLoopKey);
-            if (ret2 == false)
-            {
-                return false;
-            }
-            return true;
-        }
-
-        private async Task<string> GetRealPingTime(DownloadService downloadHandle, IWebProxy webProxy)
+        private async Task DoRealPing(DownloadService downloadHandle, ServerTestItem it)
         {
+            var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
             var responseTime = await downloadHandle.GetRealPingTime(_config.SpeedTestItem.SpeedPingTestUrl, webProxy, 10);
-            return FormatOut(responseTime, Global.DelayUnit);
+            var output = FormatOut(responseTime, Global.DelayUnit);
+
+            ProfileExHandler.Instance.SetTestDelay(it.IndexId, output);
+            UpdateFunc(it.IndexId, output);
+        }
+
+        private async Task DoSpeedTest(DownloadService downloadHandle, ServerTestItem it)
+        {
+            ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1");
+            UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
+
+            var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
+            var url = _config.SpeedTestItem.SpeedTestUrl;
+            var timeout = _config.SpeedTestItem.SpeedTestTimeout;
+            await downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) =>
+            {
+                decimal.TryParse(msg, out var dec);
+                if (dec > 0)
+                {
+                    ProfileExHandler.Instance.SetTestSpeed(it.IndexId, msg);
+                }
+                UpdateFunc(it.IndexId, "", msg);
+            });
         }
 
         private async Task<int> GetTcpingTime(string url, int port)
@@ -438,6 +339,24 @@ namespace ServiceLib.Services
             return responseTime;
         }
 
+        private List<List<ServerTestItem>> GetTestBatchItem(List<ServerTestItem> lstSelected, int pageSize)
+        {
+            List<List<ServerTestItem>> lstTest = new();
+            var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard)).ToList();
+            var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard).ToList();
+
+            for (var num = 0; num < (int)Math.Ceiling(lst1.Count * 1.0 / pageSize); num++)
+            {
+                lstTest.Add(lst1.Skip(num * pageSize).Take(pageSize).ToList());
+            }
+            for (var num = 0; num < (int)Math.Ceiling(lst2.Count * 1.0 / pageSize); num++)
+            {
+                lstTest.Add(lst2.Skip(num * pageSize).Take(pageSize).ToList());
+            }
+
+            return lstTest;
+        }
+
         private string FormatOut(object time, string unit)
         {
             return $"{time}";
diff --git a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs
index ff74b377..fddb48d7 100644
--- a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs
@@ -173,7 +173,7 @@ namespace ServiceLib.ViewModels
             var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}");
             var configDirTemp = Path.Combine(configDirZipTemp, _guiConfigs);
 
-            FileManager.CopyDirectory(configDir, configDirTemp, false, true, "cache.db");
+            FileManager.CopyDirectory(configDir, configDirTemp, false, true, "");
             var ret = FileManager.CreateFromDirectory(configDirZipTemp, fileName);
             Directory.Delete(configDirZipTemp, true);
             return await Task.FromResult(ret);