diff --git a/Duplicati/Library/Main/Backend/BackendManager.PendingOperation.cs b/Duplicati/Library/Main/Backend/BackendManager.PendingOperation.cs
index 4291f2cce..9efd7830b 100644
--- a/Duplicati/Library/Main/Backend/BackendManager.PendingOperation.cs
+++ b/Duplicati/Library/Main/Backend/BackendManager.PendingOperation.cs
@@ -21,6 +21,7 @@ partial class BackendManager
/// The upload throttle manager
/// The download throttle manager
/// The task reader
+ /// Whether throttling is disabled
/// The options
private sealed record ExecuteContext(
ProgressHandler ProgressHandler,
@@ -29,6 +30,7 @@ partial class BackendManager
ThrottleManager UploadThrottleManager,
ThrottleManager DownloadThrottleManager,
ITaskReader TaskReader,
+ bool IsThrottleDisabled,
Options Options);
///
diff --git a/Duplicati/Library/Main/Backend/BackendManager.cs b/Duplicati/Library/Main/Backend/BackendManager.cs
index f888cf6f2..072307bfe 100644
--- a/Duplicati/Library/Main/Backend/BackendManager.cs
+++ b/Duplicati/Library/Main/Backend/BackendManager.cs
@@ -59,14 +59,17 @@ internal partial class BackendManager : IBackendManager
if (string.IsNullOrWhiteSpace(backendUrl))
throw new ArgumentNullException(nameof(backendUrl));
+ var isThrottleDisabled = options.DisableThrottle || options.ThrottleDisabledBackends.Contains(Library.Utility.Utility.GuessScheme(backendUrl) ?? string.Empty);
+
// To avoid excessive parameter passing, the context is captured here
context = new ExecuteContext(
new ProgressHandler(backendWriter, taskReader),
backendWriter ?? throw new ArgumentNullException(nameof(backendWriter)),
new DatabaseCollector(),
- new ThrottleManager() { Limit = options.MaxUploadPrSecond },
- new ThrottleManager() { Limit = options.MaxDownloadPrSecond },
+ new ThrottleManager() { Limit = isThrottleDisabled ? 0 : options.MaxUploadPrSecond },
+ new ThrottleManager() { Limit = isThrottleDisabled ? 0 : options.MaxDownloadPrSecond },
taskReader ?? throw new ArgumentNullException(nameof(taskReader)),
+ isThrottleDisabled,
options ?? throw new ArgumentNullException(nameof(options))
);
@@ -393,6 +396,9 @@ internal partial class BackendManager : IBackendManager
/// The maximum download speed in bytes per second
public void UpdateThrottleValues(long maxUploadPrSecond, long maxDownloadPrSecond)
{
+ if (context.IsThrottleDisabled)
+ return;
+
context.UploadThrottleManager.Limit = maxUploadPrSecond;
context.DownloadThrottleManager.Limit = maxDownloadPrSecond;
}
diff --git a/Duplicati/Library/Main/Options.cs b/Duplicati/Library/Main/Options.cs
index 8628a5320..59c39a852 100644
--- a/Duplicati/Library/Main/Options.cs
+++ b/Duplicati/Library/Main/Options.cs
@@ -94,6 +94,11 @@ namespace Duplicati.Library.Main
///
private const int DEFAULT_ASYNCHRONOUS_CONCURRENT_UPLOAD_LIMIT = 4;
+ ///
+ /// The backends where throttling is disabled by default
+ ///
+ private const string DEFAULT_THROTTLE_DISABLED_BACKENDS = "file";
+
///
/// The default retry delay
///
@@ -375,6 +380,8 @@ namespace Duplicati.Library.Main
new CommandLineArgument("throttle-upload", CommandLineArgument.ArgumentType.Size, Strings.Options.ThrottleuploadShort, Strings.Options.ThrottleuploadLong, "0kb"),
new CommandLineArgument("throttle-download", CommandLineArgument.ArgumentType.Size, Strings.Options.ThrottledownloadShort, Strings.Options.ThrottledownloadLong, "0kb"),
+ new CommandLineArgument("throttle-disabled", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisablethrottleShort, Strings.Options.DisablethrottleLong, "false"),
+ new CommandLineArgument("throttle-disabled-backends", CommandLineArgument.ArgumentType.String, Strings.Options.DisablethrottlebackendsShort, Strings.Options.DisablethrottlebackendsLong("disable-throttle"), DEFAULT_THROTTLE_DISABLED_BACKENDS),
new CommandLineArgument("skip-files-larger-than", CommandLineArgument.ArgumentType.Size, Strings.Options.SkipfileslargerthanShort, Strings.Options.SkipfileslargerthanLong),
new CommandLineArgument("upload-unchanged-backups", CommandLineArgument.ArgumentType.Boolean, Strings.Options.UploadUnchangedBackupsShort, Strings.Options.UploadUnchangedBackupsLong, "false"),
@@ -871,6 +878,17 @@ namespace Duplicati.Library.Main
}
}
+ ///
+ /// A value indicating if the throttling is disabled
+ ///
+ public bool DisableThrottle => GetBool("throttle-disabled");
+
+ ///
+ /// The backends where the throttling is disabled
+ ///
+ public HashSet ThrottleDisabledBackends
+ => GetString("throttle-disabled-backends", DEFAULT_THROTTLE_DISABLED_BACKENDS)?.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)?.ToHashSet(StringComparer.OrdinalIgnoreCase) ?? new HashSet();
+
///
/// A value indicating if the backup is a full backup
///
diff --git a/Duplicati/Library/Main/Strings.cs b/Duplicati/Library/Main/Strings.cs
index bed53542e..8b29d3dca 100644
--- a/Duplicati/Library/Main/Strings.cs
+++ b/Duplicati/Library/Main/Strings.cs
@@ -59,6 +59,10 @@ namespace Duplicati.Library.Main.Strings
public static string ThrottledownloadShort { get { return LC.L(@"Max number of kilobytes to download pr. second"); } }
public static string ThrottleuploadLong { get { return LC.L(@"By setting this value you can limit how much bandwidth Duplicati consumes for uploads. Setting this limit can make the backups take longer, but will make Duplicati less intrusive."); } }
public static string ThrottleuploadShort { get { return LC.L(@"Max number of kilobytes to upload pr. second"); } }
+ public static string DisablethrottleLong { get { return LC.L(@"Disable the throttling of upload and download speeds for this task. If there is a throttle set, it will be ignored when running this task."); } }
+ public static string DisablethrottleShort { get { return LC.L(@"Disable throttling"); } }
+ public static string DisablethrottlebackendsLong(string option) { return LC.L(@"Disable the throttling of upload and download speeds for specific backends. If there is a throttle set, it will be ignore when running this task, if the backend is one of the specified backends. Multiple backends can be specified with a comma separator. This option has no effect if there is no throttle or if --{0} is set", option); }
+ public static string DisablethrottlebackendsShort { get { return LC.L(@"Disable throttling for specific backends"); } }
public static string NoencryptionLong { get { return LC.L(@"If you store the backups on a local disk, and prefer that they are kept unencrypted, you can turn of encryption completely by using this switch."); } }
public static string NoencryptionShort { get { return LC.L(@"Disable encryption"); } }
public static string NumberofretriesLong { get { return LC.L(@"If an upload or download fails, Duplicati will retry a number of times before failing. Use this to handle unstable network connections better."); } }