News

Bandwidth Throttling & Network-Aware Backups for Distributed Teams

Remote backups shouldn't ruin your team's video calls or blow through mobile data caps. Discover how to optimize Duplicati with bandwidth throttling, metered-network scripts, and `ServerUtil` automation to keep endpoint protection completely invisible during the workday.

The modern workforce is no longer confined to a centralized office with enterprise-grade, symmetrical fiber internet. Today’s distributed teams operate from suburban home offices, coffee shops, and on-the-go via mobile hotspots.

While this flexibility drives productivity, it introduces a significant challenge for IT and data protection: How do you ensure reliable endpoint backups without completely crippling a remote worker’s residential internet connection?

There is nothing more frustrating for a remote employee than experiencing severe network latency, robotic audio, or frozen video during a critical Zoom or Microsoft Teams call, all because a background backup job decided to saturate their limited upload bandwidth.

Fortunately, Duplicati offers a robust set of advanced configurations and automation capabilities designed specifically to support remote and hybrid workforces. By implementing bandwidth throttling, network-aware rules, and programmatic off-peak transfer windows, you can secure distributed data without interrupting workday productivity.


1. Taming the Pipeline: Setting Upload and Download Limits

Residential internet connections are typically asynchronous, offering fast download speeds but significantly slower upload speeds. When an endpoint backup kicks off, it is the upload bandwidth that gets maxed out. Saturated upload bandwidth immediately causes high ping times and packet loss, destroying the quality of real-time video calls and cloud applications.

Duplicati allows you to strictly control network consumption using built-in bandwidth throttling parameters.

The Solution

By configuring the --upload-limit and --download-limit options, you can cap Duplicati’s network usage to leave plenty of headroom for essential workplace tools.

  • --upload-limit: Caps the maximum upload speed (e.g., --upload-limit=1MB restricts uploads to 1 Megabyte per second).


  • --download-limit: Caps the maximum download speed (useful during restores or database recreations to avoid saturating download capacity).


Best Practice for Distributed Teams: Calculate the average upload speed of your remote workers (often around 10–20 Mbps on standard residential connections). Cap Duplicati’s upload limit to roughly 20–30% of that capacity (e.g., 500KB or 1MB). This ensures continuous, quiet background backups that users won't even notice.


2. Implementing Network-Aware Rules: Avoiding the Hotspot Trap

Remote workers are constantly moving between networks. One hour they are on home Wi-Fi; the next, they are tethered to a 5G mobile hotspot while traveling. Automatically pushing gigabytes of encrypted backup data over a metered cellular connection can lead to massive data overages or throttled carrier speeds.


Backups need to be network-aware, ensuring they only run when connected to unmetered networks.


The Solution

You can prevent Duplicati from starting on metered connections by utilizing pre-backup scripts via --run-script-before.


  • Using --run-script-before: Point Duplicati to a script (PowerShell on Windows, or Bash on macOS/Linux) that inspects the active network connection before execution. If the script detects a metered network or mobile hotspot (e.g., checking if the connection is set to metered or if the SSID matches mobile devices), it can return a non-zero exit code (exit 1). This signals Duplicati to safely abort the backup run until the next scheduled window.


  • OS Task Scheduler Integration: If you invoke Duplicati via the Command Line Interface (CLI) or orchestrate it via OS tools, you can leverage native conditions like Windows Task Scheduler’s "Do not run on metered networks" or "Start only if the following network connection is available."


3. Structuring Off-Peak Transfer Windows with ServerUtil

The first time Duplicati runs on a new endpoint, it must upload an initial baseline backup. Even with deduplication and compression, a 100GB initial backup takes time—and keeping bandwidth throttled to 500KB/s during work hours could drag out the initial seed for days.


To solve this, organizations can enforce strict off-peak transfer windows so heavy lifting happens overnight without impacting business hours.


The Solution

Instead of relying solely on basic UI schedules, you can programmatically control backup windows using Duplicati.CommandLine.ServerUtil (or duplicati-server-util on Linux/macOS) alongside lightweight orchestration scripts.


ServerUtil communicates directly with the local Duplicati service API, allowing you to trigger, pause, and resume jobs on demand.

Example: Python Automation Script

The following Python script starts a backup at the beginning of the off-peak window and automatically pauses the server before the workday begins:


import subprocess
import time

# Path to ServerUtil (use 'duplicati-server-util' on Linux/macOS)
SERVER_UTIL_PATH = "Duplicati.CommandLine.ServerUtil.exe"
BACKUP_ID = "1"     # Backup ID or Name configured in Duplicati
WINDOW_HOURS = 8    # Maximum allowed transfer duration (e.g., 10 PM to 6 AM)

def manage_offpeak_backup():
    try:
        # 1. Ensure the server is active
        subprocess.run([SERVER_UTIL_PATH, "resume"], check=True)
        
        # 2. Trigger the scheduled backup job
        print(f"Starting off-peak backup (ID: {BACKUP_ID})...")
        subprocess.run([SERVER_UTIL_PATH, "run", BACKUP_ID], check=True)

        # 3. Wait out the allocated night-time transfer window
        print(f"Backup in progress. Allowing up to {WINDOW_HOURS} hours...")
        time.sleep(WINDOW_HOURS * 3600)

        # 4. Pause the server before business hours start
        print("Transfer window closing. Pausing active Duplicati jobs...")
        subprocess.run([SERVER_UTIL_PATH, "pause"], check=True)
        
    except subprocess.CalledProcessError as err:
        print(f"ServerUtil execution error: {err}")

if __name__ == "__main__":
    manage_offpeak_backup()
import subprocess
import time

# Path to ServerUtil (use 'duplicati-server-util' on Linux/macOS)
SERVER_UTIL_PATH = "Duplicati.CommandLine.ServerUtil.exe"
BACKUP_ID = "1"     # Backup ID or Name configured in Duplicati
WINDOW_HOURS = 8    # Maximum allowed transfer duration (e.g., 10 PM to 6 AM)

def manage_offpeak_backup():
    try:
        # 1. Ensure the server is active
        subprocess.run([SERVER_UTIL_PATH, "resume"], check=True)
        
        # 2. Trigger the scheduled backup job
        print(f"Starting off-peak backup (ID: {BACKUP_ID})...")
        subprocess.run([SERVER_UTIL_PATH, "run", BACKUP_ID], check=True)

        # 3. Wait out the allocated night-time transfer window
        print(f"Backup in progress. Allowing up to {WINDOW_HOURS} hours...")
        time.sleep(WINDOW_HOURS * 3600)

        # 4. Pause the server before business hours start
        print("Transfer window closing. Pausing active Duplicati jobs...")
        subprocess.run([SERVER_UTIL_PATH, "pause"], check=True)
        
    except subprocess.CalledProcessError as err:
        print(f"ServerUtil execution error: {err}")

if __name__ == "__main__":
    manage_offpeak_backup()
import subprocess
import time

# Path to ServerUtil (use 'duplicati-server-util' on Linux/macOS)
SERVER_UTIL_PATH = "Duplicati.CommandLine.ServerUtil.exe"
BACKUP_ID = "1"     # Backup ID or Name configured in Duplicati
WINDOW_HOURS = 8    # Maximum allowed transfer duration (e.g., 10 PM to 6 AM)

def manage_offpeak_backup():
    try:
        # 1. Ensure the server is active
        subprocess.run([SERVER_UTIL_PATH, "resume"], check=True)
        
        # 2. Trigger the scheduled backup job
        print(f"Starting off-peak backup (ID: {BACKUP_ID})...")
        subprocess.run([SERVER_UTIL_PATH, "run", BACKUP_ID], check=True)

        # 3. Wait out the allocated night-time transfer window
        print(f"Backup in progress. Allowing up to {WINDOW_HOURS} hours...")
        time.sleep(WINDOW_HOURS * 3600)

        # 4. Pause the server before business hours start
        print("Transfer window closing. Pausing active Duplicati jobs...")
        subprocess.run([SERVER_UTIL_PATH, "pause"], check=True)
        
    except subprocess.CalledProcessError as err:
        print(f"ServerUtil execution error: {err}")

if __name__ == "__main__":
    manage_offpeak_backup()

Alternative: Time-Checking Script Pre-Execution

If you prefer running backups on regular UI schedules, you can attach a --run-script-before script that checks the current system hour. If a user boots up their laptop at 10:00 AM and Duplicati attempts a catch-up run, the script checks the clock and aborts the run until the next off-peak window.


If a backup is paused or interrupted mid-transfer, Duplicati handles it gracefully. On the next transfer window, it verifies existing remote storage blocks and seamlessly picks up right where it left off.

The Bottom Line

Endpoint protection is only effective if it runs silently in the background without user intervention. If a backup solution disrupts video calls or consumes mobile data allowances, users will inevitably find ways to disable it, leaving critical organization data exposed.


By combining Duplicati’s --upload-limit, network-checking pre-scripts, and ServerUtil script automation, IT teams can build a completely invisible backup strategy. Remote employees maintain uninterrupted productivity, and IT maintains full peace of mind.


New to Duplicati? Then go get the free open-source Duplicati client now.

Get started for free

Pick your own backend and store encrypted backups of your files anywhere online or offline. For MacOS, Windows and Linux.

Pick your own backend and store encrypted backups of your files anywhere online or offline. For MacOS, Windows and Linux.

  • Example image