# How to Monitor Download/Upload Speed Programmatically in qBittorrent

> Learn how to monitor qBittorrent download and upload speed programmatically. Access real-time transfer stats using BitTorrent SessionStatus and Qt signals for custom applications.

- Repository: [qBittorrent project/qBittorrent](https://github.com/qbittorrent/qBittorrent)
- Tags: how-to-guide
- Published: 2026-05-05

---

**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`](https://github.com/qbittorrent/qBittorrent/blob/main/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`](https://github.com/qbittorrent/qBittorrent/blob/main/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.

```cpp
#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`](https://github.com/qbittorrent/qBittorrent/blob/main/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.

```cpp
#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`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/speedmonitor.cpp), this helper calculates time-weighted averages suitable for graph rendering or trend analysis.

```cpp
#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`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/sessionimpl.cpp)** – Handles the `session_stats` alert, updates `m_status`, and emits `statsUpdated()` at lines 6293-6296.
- **[`src/base/bittorrent/sessionstatus.h`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/sessionstatus.h)** – Defines the `SessionStatus` structure with fields such as `payloadDownloadRate`, `payloadUploadRate`, `downloadRate`, and `uploadRate`.
- **[`src/base/bittorrent/session.h`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/session.h)** – Declares the abstract `status()` getter and the `statsUpdated` signal in the public interface.
- **[`src/gui/properties/speedwidget.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/gui/properties/speedwidget.cpp)** – Demonstrates UI integration by connecting to `statsUpdated` to refresh speed displays at lines 112-115.
- **[`src/base/bittorrent/speedmonitor.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/speedmonitor.cpp)** – Implements the rolling average calculator for bandwidth smoothing.

## Summary

- qBittorrent computes transfer rates inside `SessionImpl` by processing `session_stats` alerts from libtorrent and storing results in `BitTorrent::SessionStatus`.
- Retrieve current speeds synchronously via `Session::instance()->status()`, which returns a structure containing `payloadDownloadRate` and `payloadUploadRate` in bytes per second.
- Subscribe to asynchronous updates by connecting to the `statsUpdated()` signal to react immediately when new statistics are available.
- Use the `SpeedMonitor` helper 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`](https://github.com/qbittorrent/qBittorrent/blob/main/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.