Common Configuration Use-Cases

After you went through Configuration Quick Start and got familiar with the handling of rTorrent, it’s time to look at settings that you should consider for your configuration, but which weren’t necessary to start using it.

The Common Tasks in rTorrent wiki page contains more of these typical configuration use-cases.

Load ‘Drop-In’ Config Fragments

The examples here and in the wiki are mostly short snippets written to serve a specific purpose. To easily add those by just dropping them into a new file, add this to your main configuration file (which then can be the last change you apply to it).

method.insert = cfg.drop_in, private|const|string, (cat, (cfg.basedir), "config.d")
execute.nothrow = bash, -c, (cat,\
    "find ", (cfg.drop_in), " -name '*.rc' ",\
    "| sort | sed -re 's/^/import=/' >", (cfg.drop_in), "/.import")
try_import = (cat, (cfg.drop_in), "/.import")

To test the change, excute these commands:

mkdir -p ~/rtorrent/config.d
echo 'print="Hello from config.d!"' >$_/hello.rc

Then restart rTorrent, and you should see Hello from config.d! amongst the initial console messages.


If a drop-in file just contains commands that can be repeated several times, they can be re-imported making them way easier to test after changes. For example, schedules can be redefined, but method definitions can not (under the same name).

Log Rotation, Archival, and Pruning

The following longer snippet adds logs that don’t endlessly grow, get archived after some days, and are finally deleted after a while. See rtorrent.d/15-logging.rc for the full snippet.


If you include this, take care to comment out any conflicting logging commands that you already have in your main configuration.

The time spans for archival and pruning are set using pyro.log_archival.days (default: 2) and pyro.log_retention.days (default: 7). You can change these in your main configuration, after including the snippet via import.

# Note that the "main" log is only rotated when using rTorrent-PS 1.1+ (after 2017-03-26),
# since 'log.open_file' needed to learn how to re-open first. Otherwise, you'll get a daily
# console warning.

# Settings for archival delay, and retention [days]
method.insert.value = pyro.log_retention.days, 7
method.insert.value = pyro.log_archival.days,  2

Log files are time stamped (see pyro.date_iso.log_stamp and pyro.log_stamp.current). Full log file paths for different types are created using pyro.logfile_path, which takes the type as an argument.

# Create a "YYYY-mm-dd-HHMMSS" time stamp
method.insert = pyro.date_iso.log_stamp, simple|private,\
    "execute.capture_nothrow = bash, -c, \"echo -n $(date +%Y-%m-%d-%H%M%S)\""

# String value for the currently used time stamp, changed on rotation
method.insert = pyro.log_stamp.current, string

# Create a full logfile path using the current stamp
method.insert = pyro.logfile_path, simple|private,\
    "cat = (cfg.logs), (argument.0), \"-\", (pyro.log_stamp.current), .log"

The pyro.log_rotate multi-method takes care of calculating a new time stamp, and rotating all the log files by re-opening them with their new name. A daily schedule calls this method and thus triggers the rotation.

# (Re-)open all logs with a current time stamp; the main log file
# is just opened, you need to add some logging scopes yourself!
method.insert = pyro.log_rotate, multi|rlookup|static
method.set_key = pyro.log_rotate, !stamp,\
    "pyro.log_stamp.current.set = (cat, (pyro.date_iso.log_stamp))"
method.set_key = pyro.log_rotate, execute,\
    "log.execute = (pyro.logfile_path, execute)"
method.set_key = pyro.log_rotate, messages,\
    "branch = (pyro.extended), ((log.messages, (pyro.logfile_path, messages) ))"
method.set_key = pyro.log_rotate, xmlrpc,\
    "log.xmlrpc = (pyro.logfile_path, xmlrpc)"
method.set_key = pyro.log_rotate, ~main,\
    "log.open_file = log, (pyro.logfile_path, rtorrent)"

# Logrotate schedule (rotating shortly after 1AM, so DST shenanigans
# are taken care of, and rotation is always near the next day's begin)
schedule2 = pyro_daily_log_rotate, 01:05:00, 24:00:00, ((pyro.log_rotate))

Finally, two schedules take care of daily archival (1:10 AM) and pruning (1:20 AM), passing the command built by pyro._logfile_find_cmd to bash for execution. The pyro.log_rotate method is used near the end to open log files at startup.

# Log file archival and pruning
method.insert = pyro._logfile_find_cmd, simple|private,\
     "cat = \"find \", (cfg.logs),\
            \" -type f -name '*.\", (argument.0),\"'\",\
            \" -mtime +\", (argument.1),\
            \" -exec nice \", (argument.2), \" '{}' ';'\""

schedule2 = pyro_logfile_archival, 01:10:00, 24:00:00,\
    "execute.nothrow = bash, -c, (pyro._logfile_find_cmd, log, (pyro.log_archival.days), gzip)"

schedule2 = pyro_logfile_pruning, 01:20:00, 24:00:00,\
    "execute.nothrow = bash, -c, (pyro._logfile_find_cmd, log.gz, (pyro.log_retention.days), rm)"

# Open logs initially on startup

Set a Download to “Seed Only”

The d.seed_only command helps you to stop all download activity on an item. Select any unfinished item, press Ctrl-X, and enter d.seed_only= followed by . Then all files in that item are set to off, and any peers still sending you data are cut off. The data you have is still seeded, as long as the item is not stopped.

method.insert = d.seed_only, private|simple,\
    "f.multicall = *, f.priority.set=0 ;\
     d.update_priorities= ;\

f.multicall calls f.priority.set on every file, d.update_priorities makes these changes known, and finally d.disconnect.seeders kicks any active seeders.

Scheduled Bandwidth Shaping

This example shows how to use schedule2 with absolute start times, to set the download rate depending on the wall clock time, at 10AM and 4PM. The result is a very simple form of bandwidth shaping, with full speed transfers enabled while you’re at work (about 16 MiB/s in the example), and only very moderate bandwidth usage when you’re at home.

schedule2 = throttle_full, 10:00:00, 24:00:00, ((throttle.global_down.max_rate.set_kb, 16000))
schedule2 = throttle_slow, 16:00:00, 24:00:00, ((throttle.global_down.max_rate.set_kb,  1000))

Use throttle.global_up.max_rate.set_kb for setting the upload rate.

If you call these commands via XMLRPC from an outside script, you can implement more complex rules, e.g. throttling when other computers are visible on the network.

External scripts should also be used when saving money is the goal, in cases where you have to live with disadvantageous ISP plans with bandwidth caps. Run such a script very regularly (via cron), to enforce the bandwidth rules continuously.