[Bug] Server bandwidth being reported under the incorrect device

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.

  1. 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.
  2. Visit the http://SERVER-IP:32400/status/sessions API endpoint to retrieve the machineIdentifier for the <Player>.
    • e.g. The machineIdentifier for the following player is 0g4fscmj510shbxqycmy7qno.
      <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"/>
      
  3. Visit the http://SERVER-IP:32400/statistics/bandwidth?timespan=6 API endpoint to look at the bandwidth usage. Locate the <Device> with the matching clientIdentifier as the machineIdentifier above and note the id of the device.
    • e.g. The id for the following device is 610.
      <Device id="610" name="Chrome" platform="Chrome" clientIdentifier="0g4fscmj510shbxqycmy7qno" createdAt="1572812716"/>
      
  4. Scroll to the bottom of the /statistics/bandwidth XML and look at the number of bytes used 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 610 is very small.
      <StatisticsBandwidth accountID="1" deviceID="610" timespan="6" at="1617726284" lan="0" bytes="872"/>
      
  5. Scroll back to the top of the /statistics/bandwidth XML and look for the <Device> with a missing clientIdentifier and note the id of the device.
    • e.g. The following device 474 does not have a clientIdentifier.
      <Device id="474" name="Chromecast" platform="Chromecast" clientIdentifier="" createdAt="1544706982"/>
      
  6. Scroll back to the bottom of the /statistics/bandwidth XML and look at the number of bytes used by the device with the missing clientIdentifier (id="474" in my example). The bandwidth being used by the device with the missing clientIdentifier correlates with the file being played.
    • e.g. The bandwidth used by device id 474 is large.
      <StatisticsBandwidth accountID="1" deviceID="474" timespan="6" at="1617727158" lan="0" bytes="1673107"/>
      
  7. 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
5 Likes

Bump.

Bump.

I’ll confirm something is weird.

It seems better with Direct Play.

@ChuckPa 17 days with no acknowledgement of a large metric accuracy concern. Could you take a look?

Thanks for alerting me.

I think the server failed to notify me given the overloading of tags. I’ve cleaned them up a bit since this is server-based with, apparently, Plex/Web as a reporting vehicle.

If I’m understanding @SwiftPanda16 correctly (please do correct me),

  1. If all devices have a valid, non-null, clientIdentifier then the reporting is correct.
  2. For those cases where the identifier is null (why is ChromeCast null ??? ), bandwidth is charged to the wrong device .

Please help me refine this.

Afterthought: When’s the last time the Devices list was cleaned out? That list is never purged. It can accumulate all kinds of junk. Every Plex/Web version can create a new instance.

  1. If all devices have a valid, non-null, clientIdentifier then the reporting is correct.

Nope, I tried this. I deleted the row with the empty clientIdentifier from the devices table in my database. Without the row in the database, the incorrect streams would still report bandwidth, but now all the device info is just blank. The bandwidth is not charged to any device.

Example of the bandwidth output from my script above with the device deleted from the database:

ID Platform Name Identifier Bandwidth
610 Chrome Chrome 0g4fscmj510shbxqycmy7qno 0.00 MB
10.15 MB
  1. For those cases where the identifier is null (why is ChromeCast null ??? ), bandwidth is charged to the wrong device .

I don’t know why but the blank clientIdentifier is always a “Chromecast”. This was the same for all 4 users that tested it for me. Always a “Chromecast” with a blank clientIdentifier. There are many “Chromecast” devices in my database. A lot of real Chromecasts with real clientIdentifier, and one broken “Chromecast” with a blank clientIdentifier.

The identifier is correct in the sessions XML data, but charged to the wrong device in the bandwidth XML data.

Afterthought: When’s the last time the Devices list was cleaned out? That list is never purged. It can accumulate all kinds of junk. Every Plex/Web version can create a new instance.

Correct. The devices table in the database is created from first install of Plex Media Server and is never purged.

  1. After deleting from the PMS devices table, were the corresponding plex.tv devices purged from https://app.plex.tv/desktop/#!/settings/devices/all ?

  2. Am I correct this issue seems centered around the ChromeCast or are other players involved ?

  1. After deleting from the PMS devices table, were the corresponding plex.tv devices purged from https://app.plex.tv/desktop/#!/settings/devices/all ?

No, the device is not purged from Plex.tv. There is no way to correlate the devices in the database with devices on Plex.tv. The identifier in the database is different from the identifier on Plex.tv.

There is also no “Chromecast” device listed under my devices.

The issue is with the server devices and not with devices linked to an account on Plex.tv.

  1. Am I correct this issue seems centered around the ChromeCast or are other players involved ?

No, the stream is playing on a different player (i.e. Plex Web or Nvidia Shield), but is being reported as a “Chromecast” in the bandwidth API.

Does this device have a null clientIdentifier ?

No, my Plex Web and Nvidia Shield have proper clientIdentifiers which are listed in the devices table in the database.

I’m trying to define the specific conditions of the failure and avoid saying “It’s broke”.

Is this possible ?

I don’t know how else to explain it.

  1. Play something using Plex Web. This instance of Plex Web has a proper clientIdentifier which is listed in the devices table in the database and matches the one shown in the server’s sessions API.
  2. The bandwidth API shows the bandwidth from this stream in Plex Web under a “Chromecast” device. This “Chromecast” device has a blank clientIdentifier.

Playing something in a different client such as Plex for Windows, all the clientIdentifier match across the database, sessions API, and bandwidth API.

I will attempt to recreate that here again.

In all I’ve done so far, I cannot.

Give me a few.

I need to setup an environment here for this.

I need another sandbox to install this plexapi code in isolation.

i will tackle tomorrow

I will be honest, I don’t know how much interest there will be in remedying any issue given the supported reporting is via Plex/Web which is working

Here is a screenshot showing the link between the sessions API and the bandwidth API. No plexapi required, just manually looking at the XML.

I know the bandwidth is wrong because of the large number of bytes shown under device 474.

You’re in a different world than I am with this.
This is not my forte.
I need time.

Maybe defer this to someone else who is more familiar with the server code? @drzoidberg33

whatever you want.

out.

Bump.