Bandwidth usage is being recorded under the incorrect device inside the Plex Media Server database statistics_bandwidth table and reported under the incorrect device through the Plex Media Server API. This bug is not noticeable on the Plex Web dashboard because it aggregates all devices into a single bandwidth graph. It appears that each server has a “fallback” device (with a missing clientIdentifier) that it dumps all the incorrect bandwidth under. The total bandwidth (shown on the Plex Web dashboard) is correct, but the individual device bandwidth are incorrect for certain clients.
Myself and 4 other users have tested this across 6 different servers and the behaviour is identical. Obviously Plex Pass is required for access to the Plex Media Server bandwidth API.
Tested Plex Media Server versions:
- 1.22.1.4228 (FreeNAS 12.2)
- 1.22.2.4264 (Linux (CentOS 7))
- 1.22.2.4282 (FreeNAS 11.3, Windows Server 2016, Windows 10, Unraid (Docker))
Tested incorrect clients:
- Plex Web 4.54.5
- Plex for Android 8.15.1 (Nvidia Shield)
Tested correct clients:
- Plex for Windows 1.30.1
- Plex HTPC for Windows 1.1.0
- Plex for Android 8.15.1 (Mobile phone)
- Plex for Roku 6.7.18
Reason to fix this bug
To be able to identify per stream/device bandwidth usage through the API.
Steps to Reproduce
Here are the manual steps to demonstrate the issue. There is a Python script below to automatically perform all these steps to make it easier to identify.
- Play media using Plex Web. Make sure no other streams are active on your server and using a large high bitrate file at original quality will help make this stream easier to identify.
- Visit the
http://SERVER-IP:32400/status/sessionsAPI endpoint to retrieve themachineIdentifierfor the<Player>.- e.g. The
machineIdentifierfor the following player is0g4fscmj510shbxqycmy7qno.<Player address="192.168.0.100" device="Windows" machineIdentifier="0g4fscmj510shbxqycmy7qno" model="hosted" platform="Chrome" platformVersion="89.0" product="Plex Web" profile="Web" remotePublicAddress="xxx.xxx.xxx.xxx" state="paused" title="Chrome" vendor="" version="4.54.5" local="1" relayed="0" secure="1" userID="1"/>
- e.g. The
- Visit the
http://SERVER-IP:32400/statistics/bandwidth?timespan=6API endpoint to look at the bandwidth usage. Locate the<Device>with the matchingclientIdentifieras themachineIdentifierabove and note theidof the device.- e.g. The
idfor the following device is610.<Device id="610" name="Chrome" platform="Chrome" clientIdentifier="0g4fscmj510shbxqycmy7qno" createdAt="1572812716"/>
- e.g. The
- Scroll to the bottom of the
/statistics/bandwidthXML and look at the number ofbytesused by the device (id="649"in my example) during the stream. Refresh the page as necessary to view updated bandwidth data. There will be multiple<StatisticsBandwidth>events so you will have to look at multiple events. The number of bytes being used by the device is very small and does not correlate to the file being played.- e.g. The bandwidth used by device id
610is very small.<StatisticsBandwidth accountID="1" deviceID="610" timespan="6" at="1617726284" lan="0" bytes="872"/>
- e.g. The bandwidth used by device id
- Scroll back to the top of the
/statistics/bandwidthXML and look for the<Device>with a missingclientIdentifierand note theidof the device.- e.g. The following device
474does not have aclientIdentifier.<Device id="474" name="Chromecast" platform="Chromecast" clientIdentifier="" createdAt="1544706982"/>
- e.g. The following device
- Scroll back to the bottom of the
/statistics/bandwidthXML and look at the number ofbytesused by the device with the missingclientIdentifier(id="474"in my example). The bandwidth being used by the device with the missingclientIdentifiercorrelates with the file being played.- e.g. The bandwidth used by device id
474is large.<StatisticsBandwidth accountID="1" deviceID="474" timespan="6" at="1617727158" lan="0" bytes="1673107"/>
- e.g. The bandwidth used by device id
- Repeat the steps above for a correct client (e.g. Plex for Windows) and the reported bandwidth is correct.
Here is a Python script using the plexapi wrapper that will perform all the steps above to print out the bandwidth usage every 5 seconds. Play media before starting this script.
import time
from datetime import datetime, timedelta
from plexapi.server import PlexServer
# Fill in SERVER-IP and token
plex = PlexServer('http://SERVER-IP:32400', token='XXXXXXXXXXXXXXXXXXXX')
accountID = 1 # 1 = admin account
dash = '-'
headers = ['Title', 'Platform', 'Name', 'Identifier']
print('Active Sessions:\n')
print(f'| {headers[0]:<50} | {headers[1]:<15} | {headers[2]:<15} | {headers[3]:<50} |')
print(f'| {dash*50} | {dash*15} | {dash*15} | {dash*50} |')
for session in plex.sessions():
player = session.players[0]
print(f'| {session.title:<50} | {player.platform:<15} | {player.title:<15} | {player.machineIdentifier:<50} |')
headers = ['ID', 'Platform', 'Name', 'Identifier', 'Bandwidth']
print('\nBandwidth Usage:\n')
print(f'| {headers[0]:<4} | {headers[1]:<15} | {headers[2]:<20} | {headers[3]:<50} | {headers[4]:<10} |')
while True:
print(f'| {dash*4} | {dash*15} | {dash*20} | {dash*50} | {dash*10} |')
now = datetime.now() - timedelta(seconds=5)
for bandwidth in plex.bandwidth(accountID=accountID, **{'at>': now}):
device = bandwidth.device()
print(f'| {device.id:<4} | {device.platform:<15} | {device.name:<20} | {device.clientIdentifier:<50} | {bandwidth.bytes/1048576:>7.2f} MB |')
time.sleep(5)
The script will print out the following tables.
Active Sessions:
| Title | Platform | Name | Identifier |
|---|---|---|---|
| The Lord of the Rings: The Return of the King | Chrome | Chrome | 0g4fscmj510shbxqycmy7qno |
Bandwidth Usage:
| ID | Platform | Name | Identifier | Bandwidth |
|---|---|---|---|---|
| 610 | Chrome | Chrome | 0g4fscmj510shbxqycmy7qno | 0.00 MB |
| 474 | Chromecast | Chromecast | 10.15 MB |