# Multipath network transmission (/en/realtime-media/video/build/manage-connection-and-quality/multipath-transmission)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

A growing number of electronic devices support simultaneous network access through multiple connections, such as Wi-Fi and cellular, or Wi-Fi and dual-SIM cellular. Each connection is independent of the actual network transmission path and does not share bandwidth bottlenecks.

This page explains how to implement multipath network transmission in your Video Calling project.

## Understand the tech [#understand-the-tech]

Starting with v4.6.0, Video SDK adds a network transmission feature called Multipath. This feature is designed for devices that support multiple network interfaces, including 5G, Wi-Fi, and LAN. Multipath helps reduce or even eliminate poor user experiences caused by weak network conditions. In lab tests, under weak network conditions with frequent bandwidth jitter, enabling Multipath reduces lag by more than 50% while maintaining image quality and latency.

Multipath improves real-time audio and video experiences that require stable transmission in poor network conditions, including video conferencing, online education, IoT parallel operations, and remote production and broadcasting.

## Prerequisites [#prerequisites]

Before you begin, make sure you have:

<_PlatformTabsGroup groupMode="structured" canonicalPlatform="android" platforms="[&#x22;android&#x22;,&#x22;ios&#x22;,&#x22;macos&#x22;,&#x22;windows&#x22;]" showTabs="true">
  <_PlatformPanel platform="android">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="android" />

    * A mobile device running Android 7.0 (API level 24) or later, with two or more active network connections.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="ios">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="ios" />

    * A mobile device running iOS 12.0 or later, with two or more active network connections.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="macos">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="macos" />

    * A device running macOS with two or more active network connections.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="windows">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="windows" />

    * A Windows device running Vista or later, with two or more active network interfaces such as Wi-Fi and Ethernet.

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>
</_PlatformTabsGroup>

* Basic audio and video interaction functions already implemented in your project. See [Quickstart](/en/realtime-media/video/get-started-sdk).

## Implementation [#implementation]

<_PlatformTabsGroup groupMode="structured" canonicalPlatform="android" platforms="[&#x22;android&#x22;,&#x22;ios&#x22;,&#x22;macos&#x22;,&#x22;windows&#x22;]" showTabs="true">
  <_PlatformPanel platform="android">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="android" />

    ### Add network permissions [#add-network-permissions]

    Multipath requires permission to access and manage the device network state. Add the following permissions to `/app/src/main/AndroidManifest.xml`:

    ```xml
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    ```

    ### Multipath APIs [#multipath-apis]

    Video SDK supports enabling and configuring Multipath through the following `ChannelMediaOptions` fields:

    ```java
    public class ChannelMediaOptions {
      // ...
      public Boolean enableMultipath;
      public Integer uplinkMultipathMode;
      public Integer downlinkMultipathMode;
      public Integer preferMultipathType;
    }
    ```

    Use `enableMultipath` to enable multipath transmission. Once enabled, the SDK supports two transmission modes:

    * **Dynamic mode** (default): Dynamically selects the optimal transmission path based on network conditions. This mode is suitable for traffic-sensitive scenarios with high user experience requirements, such as conferences and education. In this mode, you can use `preferMultipathType` to specify a preferred network path, such as Wi-Fi or mobile network.

    * **Full redundancy mode**: Sends data simultaneously across all available network paths. This mode is suitable for scenarios where traffic use is less sensitive but a highly reliable user experience is required, such as outdoor production, broadcasting, and parallel operation. This mode incurs additional fees. Contact [support@agora.io](mailto\:support@agora.io) to enable it.

    You can configure the transmission mode separately for uplink (`uplinkMultipathMode`) and downlink (`downlinkMultipathMode`).

    When Multipath is enabled, the SDK reports transmission statistics for each path in real time through the `onMultipathStats` callback. These statistics include traffic consumption for each network type and real-time performance metrics for each path, making it easier to monitor and optimize network performance.

    ```java
    public static class MultipathStats {
      public int lanTxBytes;
      public int lanRxBytes;
      public int wifiTxBytes;
      public int wifiRxBytes;
      public int mobileTxBytes;
      public int mobileRxBytes;
      public int activePathNum;
      public PathStats[] pathStats;
    }
    ```

    ### Sample code [#sample-code]

    ```java
    private String multipathModeStr = "";
    private int activePathNum = 0;

    mediaOptions.enableMultipath = true;

    multipathModeStr = spinner_multipath_mode.getSelectedItem().toString();
    Constants.MultipathMode multipathMode = Constants.MultipathMode.valueOf(multipathModeStr);

    mediaOptions.uplinkMultipathMode = Constants.MultipathMode.getValue(Constants.MultipathMode.DYNAMIC);
    mediaOptions.downlinkMultipathMode = Constants.MultipathMode.getValue(Constants.MultipathMode.DYNAMIC);
    mediaOptions.preferMultipathType = Constants.MultipathType.MULTIPATH_TYPE_WIFI.getValue();

    @Override
    public void onMultipathStats(MultipathStats stats) {
      super.onMultipathStats(stats);
      activePathNum = stats.activePathNum;
    }
    ```

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="ios">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="ios" />

    ### Multipath APIs [#multipath-apis-1]

    Video SDK supports enabling and configuring Multipath through the following `AgoraRtcChannelMediaOptions` fields:

    ```objc
    __attribute__((visibility("default"))) @interface AgoraRtcChannelMediaOptions : NSObject
    // ...
    @property(assign, nonatomic) BOOL enableMultipath;
    @property(assign, nonatomic) AgoraMultipathMode uplinkMultipathMode;
    @property(assign, nonatomic) AgoraMultipathMode downlinkMultipathMode;
    @property(assign, nonatomic) AgoraMultipathType preferMultipathType;
    @end
    ```

    Use `enableMultipath` to enable multipath transmission. Once enabled, the SDK supports two transmission modes:

    * **Dynamic mode** (default): Dynamically selects the optimal transmission path based on network conditions. This mode is suitable for traffic-sensitive scenarios with high user experience requirements, such as conferences and education. In this mode, you can use `preferMultipathType` to specify a preferred network path, such as Wi-Fi or mobile network.

    * **Full redundancy mode**: Sends data simultaneously across all available network paths. This mode is suitable for scenarios where traffic use is less sensitive but a highly reliable user experience is required, such as outdoor production, broadcasting, and parallel operation. This mode incurs additional fees. Contact [support@agora.io](mailto\:support@agora.io) to enable it.

    You can configure the transmission mode separately for uplink (`uplinkMultipathMode`) and downlink (`downlinkMultipathMode`).

    When Multipath is enabled, the SDK reports transmission statistics for each path in real time through the `multiPathStats` callback. These statistics include traffic consumption for each network type and real-time performance metrics for each path, making it easier to monitor and optimize network performance.

    ```objc
    __attribute__((visibility("default"))) @interface AgoraMultipathStats : NSObject
    @property (assign, nonatomic) NSUInteger lanRxBytes;
    @property (assign, nonatomic) NSUInteger lanTxBytes;
    @property (assign, nonatomic) NSUInteger wifiRxBytes;
    @property (assign, nonatomic) NSUInteger wifiTxBytes;
    @property (assign, nonatomic) NSUInteger mobileRxBytes;
    @property (assign, nonatomic) NSUInteger mobileTxBytes;
    @property (assign, nonatomic) NSUInteger activePathNum;
    @property (copy, nonatomic) NSArray<AgoraPathStats *> *_Nullable pathStats NS_SWIFT_NAME(pathStats);
    @end
    ```

    ### Sample code [#sample-code-1]

    ```swift
    @IBOutlet weak var selectModePicker: Picker!
    func initSelectModePicker() {
      selectModePicker.label.stringValue = "Mode".localized
      selectModePicker.picker.addItems(withTitles: ["dynamic", "duplicate"])
      selectModePicker.picker.selectItem(at: 0)
    }

    channelMediaOption.enableMultipath = (multipathSwitch.state == .on)
    channelMediaOption.uplinkMultipathMode = (selectModePicker.picker.indexOfSelectedItem == 0) ? .dynamic : .duplicate
    channelMediaOption.downlinkMultipathMode = (selectModePicker.picker.indexOfSelectedItem == 0) ? .dynamic : .duplicate

    func rtcEngine(_ engine: AgoraRtcEngineKit, multiPathStats stats: AgoraMultipathStats) {
      videos[0].statsInfo?.updateMultipathStats(stats)
    }
    ```

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="macos">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="macos" />

    ### Multipath APIs [#multipath-apis-2]

    Video SDK supports enabling and configuring Multipath through the following `AgoraRtcChannelMediaOptions` fields:

    ```objc
    __attribute__((visibility("default"))) @interface AgoraRtcChannelMediaOptions : NSObject
    // ...
    @property(assign, nonatomic) BOOL enableMultipath;
    @property(assign, nonatomic) AgoraMultipathMode uplinkMultipathMode;
    @property(assign, nonatomic) AgoraMultipathMode downlinkMultipathMode;
    @property(assign, nonatomic) AgoraMultipathType preferMultipathType;
    @end
    ```

    Use `enableMultipath` to enable multipath transmission. Once enabled, the SDK supports two transmission modes:

    * **Dynamic mode** (default): Dynamically selects the optimal transmission path based on network conditions. This mode is suitable for traffic-sensitive scenarios with high user experience requirements, such as conferences and education. In this mode, you can use `preferMultipathType` to specify a preferred network path, such as Wi-Fi or mobile network.

    * **Full redundancy mode**: Sends data simultaneously across all available network paths. This mode is suitable for scenarios where traffic use is less sensitive but a highly reliable user experience is required, such as outdoor production, broadcasting, and parallel operation. This mode incurs additional fees. Contact [support@agora.io](mailto\:support@agora.io) to enable it.

    You can configure the transmission mode separately for uplink (`uplinkMultipathMode`) and downlink (`downlinkMultipathMode`).

    When Multipath is enabled, the SDK reports transmission statistics for each path in real time through the `multiPathStats` callback. These statistics include traffic consumption for each network type and real-time performance metrics for each path, making it easier to monitor and optimize network performance.

    ```objc
    __attribute__((visibility("default"))) @interface AgoraMultipathStats : NSObject
    @property (assign, nonatomic) NSUInteger lanRxBytes;
    @property (assign, nonatomic) NSUInteger lanTxBytes;
    @property (assign, nonatomic) NSUInteger wifiRxBytes;
    @property (assign, nonatomic) NSUInteger wifiTxBytes;
    @property (assign, nonatomic) NSUInteger mobileRxBytes;
    @property (assign, nonatomic) NSUInteger mobileTxBytes;
    @property (assign, nonatomic) NSUInteger activePathNum;
    @property (copy, nonatomic) NSArray<AgoraPathStats *> *_Nullable pathStats NS_SWIFT_NAME(pathStats);
    @end
    ```

    ### Sample code [#sample-code-2]

    ```swift
    @IBOutlet weak var selectModePicker: Picker!
    func initSelectModePicker() {
      selectModePicker.label.stringValue = "Mode".localized
      selectModePicker.picker.addItems(withTitles: ["dynamic", "duplicate"])
      selectModePicker.picker.selectItem(at: 0)
    }

    channelMediaOption.enableMultipath = (multipathSwitch.state == .on)
    channelMediaOption.uplinkMultipathMode = (selectModePicker.picker.indexOfSelectedItem == 0) ? .dynamic : .duplicate
    channelMediaOption.downlinkMultipathMode = (selectModePicker.picker.indexOfSelectedItem == 0) ? .dynamic : .duplicate
    ```

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="windows">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="windows" />

    ### Multipath APIs [#multipath-apis-3]

    Video SDK supports enabling and configuring Multipath through the following `ChannelMediaOptions` fields:

    ```cpp
    struct ChannelMediaOptions {
      // ...
      Optional<bool> enableMultipath;
      Optional<MultipathMode> uplinkMultipathMode;
      Optional<MultipathMode> downlinkMultipathMode;
      Optional<MultipathType> preferMultipathType;
    };
    ```

    Use `enableMultipath` to enable multipath transmission. Once enabled, the SDK supports two transmission modes:

    * **Dynamic mode** (default): Dynamically selects the optimal transmission path based on network conditions. This mode is suitable for traffic-sensitive scenarios with high user experience requirements, such as conferences and education. In this mode, you can use `preferMultipathType` to specify a preferred network path, such as Wi-Fi or mobile network.

    * **Full redundancy mode**: Sends data simultaneously across all available network paths. This mode is suitable for scenarios where traffic use is less sensitive but a highly reliable user experience is required, such as outdoor production, broadcasting, and parallel operation. This mode incurs additional fees. Contact [support@agora.io](mailto\:support@agora.io) to enable it.

    You can configure the transmission mode separately for uplink (`uplinkMultipathMode`) and downlink (`downlinkMultipathMode`).

    When Multipath is enabled, the SDK reports transmission statistics for each path in real time through the `onMultipathStats` callback. These statistics include traffic consumption for each network type and real-time performance metrics for each path, making it easier to monitor and optimize network performance.

    ```cpp
    struct MultipathStats {
      uint32_t lanTxBytes;
      uint32_t lanRxBytes;
      uint32_t wifiTxBytes;
      uint32_t wifiRxBytes;
      uint32_t mobileTxBytes;
      uint32_t mobileRxBytes;
      int activePathNum;
      const PathStats* pathStats;
    };
    ```

    ### Sample code [#sample-code-3]

    ```cpp
    // Initialize UI elements related to multipath transmission
    m_cmbMultipathMode.InsertString(0, _T("Duplicate"));
    m_cmbMultipathMode.InsertString(1, _T("Dynamic"));
    m_cmbMultipathMode.SetCurSel(0);

    // Initialize multipath transmission controls
    m_staEnableMultipath.SetWindowText(_T("Enable Multipath:"));
    m_chkEnableMultipath.SetCheck(BST_UNCHECKED);

    ChannelMediaOptions options;
    options.enableMultipath = (m_chkEnableMultipath.GetCheck() == BST_CHECKED);

    int modeIndex = m_cmbMultipathMode.GetCurSel();
    MultipathMode mode = (modeIndex == 0) ? Duplicate : Dynamic;

    options.uplinkMultipathMode = mode;
    options.downlinkMultipathMode = mode;
    options.preferMultipathType = WIFI;

    void CMultipathRtcEngineEventHandler::onMultipathStats(const MultipathStats& stats)
    {
      if (m_hMsgHanlder)
      {
        MultipathStats* statsPtr = new MultipathStats(stats);
        ::PostMessage(m_hMsgHanlder, WM_MSGID(EID_MULTIPATH_STATS), (WPARAM)statsPtr, 0);
      }
    }
    ```

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>
</_PlatformTabsGroup>

## Reference [#reference]

This section contains content that completes the information on this page, or points you to documentation that explains other aspects of this feature.

<_PlatformTabsGroup groupMode="structured" canonicalPlatform="android" platforms="[&#x22;android&#x22;,&#x22;ios&#x22;,&#x22;macos&#x22;,&#x22;windows&#x22;]" showTabs="true">
  <_PlatformPanel platform="android">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="android" />

    ### API reference [#api-reference]

    * [`ChannelMediaOptions`](/en/api-reference/rtc/android/class-and-enum/classes/class-channelmediaoptions)
    * [MultipathStats](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_multipathstats.html)
    * [`onMultipathStats`](/en/api-reference/rtc/android/network-and-other#callback_irtcengineeventhandler_onmultipathstats)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="ios">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="ios" />

    ### API reference [#api-reference-1]

    * [AgoraRtcChannelMediaOptions](https://api-ref.agora.io/en/video-sdk/ios/4.x/Classes/AgoraRtcChannelMediaOptions.html)
    * [rtcEngine(\_:multiPathStats:)](https://api-ref.agora.io/en/video-sdk/ios/4.x/Protocols/AgoraRtcEngineDelegate.html)
    * [AgoraMultipathStats](https://api-ref.agora.io/en/video-sdk/ios/4.x/Classes/AgoraMultipathStats.html)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="macos">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="macos" />

    ### API reference [#api-reference-2]

    * [AgoraRtcChannelMediaOptions](https://api-ref.agora.io/en/video-sdk/macos/4.x/Classes/AgoraRtcChannelMediaOptions.html)
    * [rtcEngine(\_:multiPathStats:)](https://api-ref.agora.io/en/video-sdk/macos/4.x/Protocols/AgoraRtcEngineDelegate.html)
    * [AgoraMultipathStats](https://api-ref.agora.io/en/video-sdk/macos/4.x/Classes/AgoraMultipathStats.html)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>

  <_PlatformPanel platform="windows">
    <_PlatformProcessedMarker groupMode="structured" canonicalPlatform="android" platform="windows" />

    ### API reference [#api-reference-3]

    * [ChannelMediaOptions](https://api-ref.agora.io/en/video-sdk/cpp/4.x/API/class_channelmediaoptions.html)
    * [onMultipathStats](https://api-ref.agora.io/en/video-sdk/cpp/4.x/API/class_irtcengineeventhandler.html#callback_irtcengineeventhandler_onmultipathstats)

    <_PlatformProcessedMarker close="true" />
  </_PlatformPanel>
</_PlatformTabsGroup>
