# Adapt the sending bitrate (/en/realtime-media/iot/build/manage-connections-and-quality/bitrate-adaptation)

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

To optimize data transmission and avoid network congestion, best practice is to adjust the sending bit rate in real-time according to changes in network conditions.

Configure BandWidth Estimation (BWE) parameters before joining a channel to set the minimum, maximum, and starting bit rate values according to your actual bandwidth and bit rate needs. When the network bandwidth changes, IoT SDK triggers an event to prompt your app to adjust the sending bit rate in real time. The bit rate returned by the callback is the maximum recommended encoding bit rate of the video encoder.

This page shows you how to configure bandwidth estimation and respond to bitrate changes in your IoT SDK app.

## Prerequisites

In order to follow this procedure you must have:

* Implemented the basic IoT SDK functionality. See [Build from scratch](../../build-from-scratch.mdx).

## Configure bandwidth estimation parameters

Configure bandwidth estimation parameters before joining a channel. Suppose your webcam has the following definition levels:

| Level    | Resolution     | Frame rate | Bit rate range (kbps) |
| :------- | :------------- | :--------: | :-------------------: |
| SD       | L1: 640\*360   |     15     |       400 - 800       |
| HD       | L2: 1280\*720  |     15     |      1130 - 2260      |
| Ultra HD | L3: 1920\*1080 |     15     |      1130 - 4160      |

Based on these levels, set the minimum bit rate value to 400 kbps, and the maximum value to 4200 kbps. Set the starting value between the minimum and the maximum values. If the initial encoding is SD, set the initial bit rate to 500 kbps.

<CalloutContainer type="info">
  <CalloutDescription>
    Call `agora_rtc_set_bwe_param` before `agora_rtc_join_channel`. Bandwidth estimation parameters set after joining a channel have no effect.
  </CalloutDescription>
</CalloutContainer>

To specify these parameters, replace the `agora_rtc_set_bwe_param` call in `main()` with the following:

```cpp
// Configure bandwidth estimation parameters
// Min, max, and starting bit rates in bps
uint32_t min_bps = 400000;
uint32_t max_bps = 4200000;
uint32_t start_bps = 500000;
agora_rtc_set_bwe_param(min_bps,  max_bps,  start_bps);
```

## Respond to target bit rate changes

When network bandwidth changes, IoT SDK triggers the `on_target_bitrate_changed` callback to prompt the app to adjust the sending bit rate. The `target_bps` value returned by the callback is the maximum recommended encoding bit rate of the video encoder.

<CalloutContainer type="info">
  <CalloutDescription>
    `on_target_bitrate_changed` returns `target_bps` in bits per second (bps). Don't confuse this with kbps or Bytes per second (Bps) when you use it to set your encoder's bitrate.
  </CalloutDescription>
</CalloutContainer>

This example uses the webcam's definition levels to switch resolution depending on the reported target bit rate. To do this, replace the `__on_target_bitrate_changed` handler with the following:

```cpp
int curTargetBitrate, diffTargetBitrate, lastTargetBitrate = 500;
int lowBitrateL1 = 400, highBitrateL1 = 800;
int lowBitrateL2 = 1130 , highBitrateL2 = 2260, highBitrateL3 = 4160;
int curResolutionLevel = 1 , lastResolutionLevel = 1;

static void __on_target_bitrate_changed(const char *channel, uint32_t target_bps)
{ // Adjust the sending code rate in real time
    // The current code rate is graded according to 100 K, rounded down
    curTargetBitrate = target_bps/100000 * 100;
    diffTargetBitrate = abs(curTargetBitrate - lastTargetBitrate);

    // If the difference between the detected bandwidth and the set
    // encoding rate is more than 100K, adjust the encoding parameters
    if ( (diffTargetBitrate >= 100 ) && (lowBitrateL1 < curTargetBitrate < highBitrateL3) )
    {
        if (lowBitrateL1 < curTargetBitrate < highBitrateL1)
        {
            curResolutionLevel = 1;
        }
        else if (lowBitrateL2 < curTargetBitrate < highBitrateL2)
        {
            curResolutionLevel = 2;
        }
        else
        {
            curResolutionLevel = 3;
        }

        if (curResolutionLevel != lastResolutionLevel)
        {
            // Adjust encoding resolution
            // setEncodeResolution(curResolutionLevel);
        }

        // Set the encoding rate
        // setEncodeBitrate(curTargetBitrate);

        lastResolutionLevel = curResolutionLevel;
        lastTargetBitrate = curTargetBitrate;
    }
}
```

## Reference

* [agora\_rtc\_set\_bwe\_param](https://api-ref.agora.io/en/iot-sdk/linux/1.x/agora__rtc__api_8h.html#ae274291aadd1afb9974a4672ed6c2bb8)
* [on\_target\_bitrate\_changed](https://api-ref.agora.io/en/iot-sdk/linux/1.x/structagora__rtc__event__handler__t.html#a2cd16998c0834bac5c47c0e2b9f47fcc)
