iOS Peripheral Throughput is low due to updateValue return false

I’ve been testing the iOS Peripheral throughput using a modified version of Apple’s “Transferring Data Between Bluetooth Low Energy Devices” sample app.

I attempted to send 1 MB (1,048,576 bytes) of data in 512-byte notification packets from a Peripheral iPhone (iPhone SE 3rd gen) to a Central iPhone (iPhone 13 Pro). The transfer took 40.7 seconds, resulting in an effective throughput of approximately 206.11 kbps. I noticed that nearly all the delay occurs while waiting for the peripheralManagerIsReady(toUpdateSubscribers:) callback after the second packet is sent.

I’ve seen reports of throughput around 1300 kbps on 2M PHY (or 700 kbps on 1M PHY). Could anyone advise how to optimize my Peripheral implementation to achieve throughput closer to 1300 kbps?

Thank you!

Answered by Engineer in 824818022

Performance effecting attributes of a BLE connection, like connection interval, MTU, PHY, etc. can only be requested by a connecting accessory. There is no way for an app to change these. When a BLE connection is between two iPhones, they will decide what the connection parameters will be as appropriate and depending on device state and what else might be going on at that time.

If you are looking into making a final product that needs better throughput for large transfers, you may want to look at implementing L2CAP Channels which will dramatically your throughput by reducing GATT protocol overhead.


Argun Tekant /  DTS Engineer / Core Technologies

Accepted Answer

Performance effecting attributes of a BLE connection, like connection interval, MTU, PHY, etc. can only be requested by a connecting accessory. There is no way for an app to change these. When a BLE connection is between two iPhones, they will decide what the connection parameters will be as appropriate and depending on device state and what else might be going on at that time.

If you are looking into making a final product that needs better throughput for large transfers, you may want to look at implementing L2CAP Channels which will dramatically your throughput by reducing GATT protocol overhead.


Argun Tekant /  DTS Engineer / Core Technologies

Hi,

Thanks for your response. I understand that connection parameters are negotiated automatically and we can't directly control them from the app.

We're testing with BLE 5.2 using 2M PHY, but our throughput (~206 kbps) is far below the expected values (around 1300 kbps). We haven't identified any implementation errors on our side.

Could this low throughput be due to iOS’s internal flow control when acting as a Peripheral? Or is there something else we're missing? Would implementing L2CAP channels be the recommended solution to boost throughput?

Any guidance is greatly appreciated. Thanks!

Additionally, we've observed that even when the data is only 1 byte, the first call to updateValue returns true, but all subsequent calls return false. We must wait for the peripheralManagerIsReady callback before we can call updateValue again—otherwise, the second call still returns false. Even if we wait 5 ms (using usleep(5000)) after the first updateValue call before trying again, it still fails.

Could you please confirm whether this behavior is expected?

I take the comment out here.:

Sorry I forgot to say that the PeripheralManagerIsReady callback time might ranging in 0.01ms ~ 250ms. Is it unstable normal?

iOS limits the packet number to 4 per connection event for instance, so if the connection interval is 30ms, then I can just send 4 packet during 30ms, is that right? I'm trying to find out the low throughput issue

And if IOS support DLE? If yes, how to enable it?

iOS Peripheral Throughput is low due to updateValue return false
 
 
Q