How to Monitor Download/Upload Speed Programmatically in qBittorrent
qBittorrent exposes real-time transfer statistics through the BitTorrent::SessionStatus structure and the statsUpdated() signal, allowing developers to either poll current speeds via Session::status() or receive push updates through Qt signal connections.
The qBittorrent client aggregates peer-to-peer transfer metrics inside the core BitTorrent session management layer. Whether you are building a custom UI component, automating bandwidth controls, or integrating with external monitoring tools, understanding how to access these metrics programmatically is essential. This guide examines the source code implementation in the qbittorrent/qBittorrent repository to show exactly how to retrieve live download and upload speeds.
How qBittorrent Tracks Transfer Statistics Internally
Every second, the underlying libtorrent library emits a session_stats alert containing raw counter values. In src/base/bittorrent/sessionimpl.cpp, the SessionImpl class processes this alert to compute per-second rates for payload data, protocol overhead, DHT traffic, and tracker communications. These calculated values are stored in the m_status member variable, which is an instance of BitTorrent::SessionStatus defined in src/base/bittorrent/sessionstatus.h. Immediately after updating the status structure, the implementation emits the Qt signal statsUpdated() to notify all connected observers.
Accessing Real-Time Speed Data via the Public API
The BitTorrent::Session interface provides two patterns for consuming speed data: synchronous polling and asynchronous event-driven updates.
Pull-Based Retrieval with Session::status()
For components that need to check speeds on demand, call the status() method to obtain a const reference to the current SessionStatus structure. This approach requires no signal-slot connections and works well for periodic checks triggered by timers or user actions.
#include "base/bittorrent/session.h"
using namespace BitTorrent;
// Obtain the current session status
const SessionStatus &st = Session::instance()->status();
// Rates are expressed in bytes per second
qint64 downloadRate = st.payloadDownloadRate; // payload download (useful data)
qint64 uploadRate = st.payloadUploadRate; // payload upload
qint64 totalDLRate = st.downloadRate; // includes protocol overhead
qint64 totalULRate = st.uploadRate;
// Example: log the rates
qDebug() << "DL:" << downloadRate << "B/s"
<< "UL:" << uploadRate << "B/s";
Push-Based Updates with the statsUpdated Signal
To react immediately when statistics change, connect to the statsUpdated() signal declared in src/base/bittorrent/session.h. This method eliminates the need for polling loops and ensures your component refreshes the instant new data arrives from libtorrent.
#include "base/bittorrent/session.h"
#include <QObject>
class SpeedMonitor : public QObject
{
Q_OBJECT
public:
SpeedMonitor(QObject *parent = nullptr) : QObject(parent)
{
// Listen for any statistics change
connect(BitTorrent::Session::instance(),
&BitTorrent::Session::statsUpdated,
this,
&SpeedMonitor::onStatsUpdated);
}
private slots:
void onStatsUpdated()
{
const auto &st = BitTorrent::Session::instance()->status();
qDebug() << "Updated – DL:" << st.payloadDownloadRate
<< "UL:" << st.payloadUploadRate;
}
};
Using the SpeedMonitor Helper for Averaged Rates
When you need smoothed values rather than instantaneous spikes, the repository includes a SpeedMonitor utility class that maintains a rolling window of recent samples. Located in src/base/bittorrent/speedmonitor.cpp, this helper calculates time-weighted averages suitable for graph rendering or trend analysis.
#include "base/bittorrent/speedmonitor.h"
SpeedMonitor monitor;
// Add a new sample (e.g., from the UI timer)
monitor.addSample({currentDownloadBytes, currentUploadBytes});
// Retrieve the average over the last N samples
SpeedSampleAvg avg = monitor.average();
qDebug() << "Average DL:" << avg.download << "bytes/s"
<< "Average UL:" << avg.upload << "bytes/s";
Key Source Files for Speed Monitoring
The following files contain the core logic for monitoring download/upload speed in qBittorrent:
src/base/bittorrent/sessionimpl.cpp– Handles thesession_statsalert, updatesm_status, and emitsstatsUpdated()at lines 6293-6296.src/base/bittorrent/sessionstatus.h– Defines theSessionStatusstructure with fields such aspayloadDownloadRate,payloadUploadRate,downloadRate, anduploadRate.src/base/bittorrent/session.h– Declares the abstractstatus()getter and thestatsUpdatedsignal in the public interface.src/gui/properties/speedwidget.cpp– Demonstrates UI integration by connecting tostatsUpdatedto refresh speed displays at lines 112-115.src/base/bittorrent/speedmonitor.cpp– Implements the rolling average calculator for bandwidth smoothing.
Summary
- qBittorrent computes transfer rates inside
SessionImplby processingsession_statsalerts from libtorrent and storing results inBitTorrent::SessionStatus. - Retrieve current speeds synchronously via
Session::instance()->status(), which returns a structure containingpayloadDownloadRateandpayloadUploadRatein bytes per second. - Subscribe to asynchronous updates by connecting to the
statsUpdated()signal to react immediately when new statistics are available. - Use the
SpeedMonitorhelper class to compute averaged rates over time windows instead of relying on raw instantaneous values. - All speed-related functionality is centralized in
src/base/bittorrent/, making it straightforward to extend or customize for plugins and forks.
Frequently Asked Questions
How does qBittorrent calculate download and upload speeds internally?
qBittorrent receives raw byte counters from libtorrent through the session_stats alert. The SessionImpl class compares these counters against previously stored values to calculate deltas, then divides by the time interval to produce per-second rates for payload data, protocol overhead, DHT, and tracker traffic.
What is the difference between payloadDownloadRate and downloadRate in SessionStatus?
The payloadDownloadRate field represents useful data transferred to peers, excluding protocol overhead. The downloadRate field includes additional bytes consumed by BitTorrent protocol messages, encryption overhead, and IP headers, providing a total bandwidth utilization figure.
Can I monitor qBittorrent speeds from an external Python script or API?
While the internal C++ API requires compiling against the qBittorrent core libraries, external monitoring is typically accomplished through the Web UI API endpoints that expose session statistics in JSON format. The internal programmatic methods described here are intended for developers modifying the qBittorrent source code or building linked plugins.
Where does qBittorrent emit the statsUpdated signal in the source code?
The statsUpdated() signal is emitted in src/base/bittorrent/sessionimpl.cpp immediately after the m_status structure is updated with new speed calculations derived from the latest libtorrent session statistics alert.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →