BandwidthPolicy is the high-level upload throttle for WebTorrentClient. It lets callers express intent (be unlimited / be conservative on a residential connection / be metered on cellular / pause seeding entirely) without picking a bytes/sec number.
Shipped in 3.2.0 (2026-04-25). Default is Unlimited — existing 3.1.x code keeps running unchanged.
BitTorrent seeders default to "as fast as possible", which is the right call on a wired desktop with unlimited bandwidth and the wrong call on:
- A metered mobile hotspot where every byte costs money or counts against a cap
- A battery-constrained laptop on cellular
- A residential connection where saturating upload kills latency for everyone else in the house
UploadLimit (long, bytes/sec) was already there for the precise case. BandwidthPolicy is the convenience layer for the four common deployment shapes plus an explicit-Custom escape hatch.
public enum BandwidthPolicy
{
/// Default. No upload throttle - mirror legacy behavior.
/// Use on wired desktops, dedicated servers, or anywhere the operator
/// has already chosen the upload ceiling at the OS / network level.
Unlimited = 0,
/// ~256 KiB/s upload ceiling. Won't saturate residential cable
/// (typical 5-25 Mbps upstream), keeps room for video calls / gaming.
/// Reasonable default for a torrent client running in the background
/// on a shared home connection.
Conservative = 1,
/// ~64 KiB/s upload ceiling. Designed for cellular / metered
/// connections where every byte costs money or counts against a cap.
/// High enough to seed slowly (still earn ratio), low enough to not
/// notice on a phone bill.
Metered = 2,
/// Stop seeding entirely (rate = 0). The client will accept
/// connections and download but won't serve pieces.
SeedingDisabled = 3,
/// Sentinel - paired with WebTorrentClientOptions.UploadLimit
/// and WebTorrentClient.ThrottleUpload when the caller supplies an
/// exact bytes/sec value.
Custom = 4,
}| Policy | UploadRateLimiter.Rate |
Comment |
|---|---|---|
Unlimited |
-1 |
No throttle (default) |
Conservative |
262_144 (256 KiB/s) |
BandwidthPolicyExtensions.ConservativeBytesPerSec |
Metered |
65_536 (64 KiB/s) |
BandwidthPolicyExtensions.MeteredBytesPerSec |
SeedingDisabled |
0 |
Paused |
Custom |
unchanged | Caller pins the rate via UploadLimit / ThrottleUpload |
Conversion is exposed as policy.ToUploadBytesPerSec().
await using var client = new WebTorrentClient(new WebTorrentClientOptions
{
BandwidthPolicy = BandwidthPolicy.Metered, // 64 KiB/s upload ceiling
});When WebTorrentClientOptions.UploadLimit is set explicitly (>= 0), it wins over the policy — the policy is the convenience layer, the explicit value is the override:
await using var client = new WebTorrentClient(new WebTorrentClientOptions
{
BandwidthPolicy = BandwidthPolicy.Custom,
UploadLimit = 12_345 * 1024, // exactly 12,345 KiB/s
});
// client.UploadRateLimiter.Rate == 12_345 * 1024
// client.BandwidthPolicy == BandwidthPolicy.Customclient.ApplyBandwidthPolicy(BandwidthPolicy.Unlimited); // back to full speed
client.ApplyBandwidthPolicy(BandwidthPolicy.Metered); // back to 64 KiB/s
client.ApplyBandwidthPolicy(BandwidthPolicy.SeedingDisabled); // pause seedingApplyBandwidthPolicy updates BandwidthPolicy AND UploadRateLimiter.Rate in lockstep so the two can't drift. Passing BandwidthPolicy.Custom is a no-op for the rate — caller pins it via ThrottleUpload:
client.ApplyBandwidthPolicy(BandwidthPolicy.Custom);
client.ThrottleUpload(500 * 1024); // 500 KiB/sclient.ThrottleUpload(256 * 1024); // 256 KiB/s
// equivalent to: client.UploadRateLimiter.Rate = 256 * 1024
// BandwidthPolicy is NOT updated; flip it explicitly if you care.BandwidthPolicy.AutoDetect() returns a recommended policy based on platform-specific signals. Today it returns Unlimited on every platform — so 3.1.x consumers see no behavior change unless they call this explicitly. The hook exists so the detection logic can fill in over time:
| Platform | Signal source | Status |
|---|---|---|
| Windows desktop | WinRT NetworkInformation.GetInternetConnectionProfile().GetConnectionCost().NetworkCostType |
Not wired today (UWP API, not in BCL net10.0) |
| Linux / macOS | NetworkInterface.GetAllNetworkInterfaces() + name heuristics (wwan* / ppp*) |
Not wired today |
| Browser | navigator.connection.saveData (NetworkInformation API) via SpawnDev.BlazorJS |
Not wired today |
Until detection lands, opt in explicitly:
// "Be conservative unless I say otherwise." - works today.
new WebTorrentClient(new WebTorrentClientOptions
{
BandwidthPolicy = BandwidthPolicy.Conservative,
});
// What AutoDetect WILL do once wired - but for now do it manually:
var policy = OperatingSystem.IsBrowser()
? BandwidthPolicy.Conservative // or read navigator.connection yourself
: BandwidthPolicy.Unlimited;
new WebTorrentClient(new WebTorrentClientOptions { BandwidthPolicy = policy });- Download throttle. Use
WebTorrentClientOptions.DownloadLimit(orDownloadRateLimiter.Rate) directly. Download throttling is rarer and the policy enum stays focused on upload. - Per-torrent overrides. The policy is client-wide. To throttle a single torrent differently, set
WebTorrentClient.UploadRateLimiterfor the global limit and rely on the choke algorithm's per-peer fairness, or maintain separate clients. - Smart-piece prioritization. Bandwidth-aware seeding could prioritize rare pieces over abundant ones when bandwidth is constrained — that's a future change to the choke-rotation algorithm, not part of this policy.
- Source:
SpawnDev.WebTorrent/BandwidthPolicy.cs - Tests:
PlaywrightMultiTest/DesktopWebRtcTest.cs→Desktop_BandwidthPolicy_AppliesToUploadRateLimiter,_ExplicitUploadLimitWins,_ApplyAtRuntimeSwitchesRate - Call site:
WebTorrentClientconstructor inSpawnDev.WebTorrent/WebTorrentClient.cs - Related:
WebTorrentClient.UploadRateLimiter,WebTorrentClient.ThrottleUpload(long),WebTorrentClient.ApplyBandwidthPolicy(BandwidthPolicy)