What FPS should I be getting?

A great question that often comes up is, what FPS should I expect to get with a GPU that can do 1080 resolution with the High profile? Unlike resolution, profile is the level of detail and effects in the scene and can not be chosen by the user.

45 FPS is the answer, according to the data.

For 1080 resolution with the basic profile, the answer is 35

For 1080 resolution with the ultra profile, the answer is 60

At the top end, running 4K Ultra you should expect to get 60 average FPS.

I arrived at these numbers by loading the zwiftalizer raw data set into a Jupyter notebook and plotting the average FPS over time for different resolution and profiles. I have a theory that the Zwift graphics programmers know exactly what they would like the average FPS to be and tune the level of detail up and down to maintain this number as new worlds get built out. Continuing the theory, if the GPU can do more than 60 FPS average on High, then it will be promoted to the Ultra profile and have more polygons thrown at it. The targets at basic, high, ultra (profile) appear to be 35, 45, 60.

Here’s the Jupyter notebook python.

Zwift Average Frames Per Second investigation

using matplotlib and pandas, read the zwiftalizer raw data dump

%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
logs = pd.read_json("/Users/Mike Hanney/Documents/Personal/Zwiftalizer/dump_formatted.json")

Create a dataframe starting at June 2017, indexed by timestamp

df = pd.DataFrame(logs, columns=['gameVersion','avgFps','maxFps','minFps','profileId','resolution', 'timestamp'])
timeframe_filter = df['timestamp'] > '2017-06-01'
df['year_month'] = df['timestamp'].apply(lambda x: x.strftime('%y-%m'))
df2 = df[timeframe_filter]

Create dataframes for basic, high and ultra profiles where resolution is 1080

is_hd = df2['resolution']==1080 
is_basic = df2['profileId']==1
is_high = df2['profileId']==2
is_ultra = df2['profileId']==3
basic = df2[is_hd & is_basic][['year_month','avgFps']]
basic.index = basic['year_month']
high = df2[is_hd & is_high][['year_month','avgFps']]
high.index = high['year_month']
ultra = df2[is_hd & is_ultra][['year_month','avgFps']]
ultra.index = ultra['year_month']

What is the average FPS for 1080 Basic over all time?

print("Average 1080 Basic FPS %d" % basic[['avgFps']].mean())
Average 1080 Basic FPS 35

What is the average FPS for 1080 Basic for each month?

basic_groups = basic.groupby(pd.Grouper('year_month')).mean()
basic_groups.sort_values(by=['year_month']).plot(kind='bar', title='1080 Basic FPS over time', figsize=(22, 10))


What is the average FPS for 1080 High over all time?

print("Average 1080 High FPS %d" % high[['avgFps']].mean())
Average 1080 High FPS 43

What is the average FPS for 1080 High for each month?

high_groups = high.groupby(pd.Grouper('year_month')).mean()
high_groups.sort_values(by=['year_month']).plot(kind='bar', title='1080 High FPS over time', figsize=(22, 10))


What is the average FPS for 1080 Ultra for all time?

print("Average 1080 Ultra FPS %d" % ultra[['avgFps']].mean())
Average 1080 Ultra FPS 58

What is the average FPS for 1080 Ultra for each month?

ultra_groups = ultra.groupby(pd.Grouper('year_month')).mean()
ultra_groups.sort_values(by=['year_month']).plot(kind='bar', title='1080 Ultra FPS over time', figsize=(22, 10))


Create a dataframe for 4K resolution, Ultra profile

is_4k = df2['resolution']==2160
is_ultra = df2['profileId']==3
ultra_4k = df2[is_4k & is_ultra][['year_month','avgFps']]
ultra_4k.index = ultra_4k['year_month']

What is the average FPS for 4K Ultra over all time?

print("Average 4K Ultra FPS %d" % ultra_4k[['avgFps']].mean())
Average 4K Ultra FPS 57

What is the average FPS for 4K Ultra for each month?

ultra_4k_groups = ultra_4k.groupby(pd.Grouper('year_month')).mean()
ultra_4k_groups.sort_values(by=['year_month']).plot(kind='bar', title='4K Ultra FPS over time', figsize=(22, 10))



FPS is largely subjective. This post is simply speculation on what the game creators might have set as desirable targets for average FPS at each resolution and profile. We know there is a threshold at which a GPU may be blessed with high or ultra capabilities according to some scoring mechanism, and this exploration into the data attempts to figure out what that threshold might be. At the end of the day, if it looks ok to you, then that is all that matters. Almost any system purchased in the last 3 to 5 years will perform pretty well because the game engine upgrades or downgrades the level of detail and effects automatically for you.

Mike Hanney