Expose Statistics API

This is now possible in Unity 2020.2, thank you for implementing it!

The Game View features the Statistics Overlay, which displays batches, triangle count, Shadow Casters, SetPass Calls and so on.
Screenshot [spoiler] [/spoiler]

Having access to this information in a (development) build, outside editor, would be extremely useful.

I want to have this in a build, because we run performance tests, where the build is started in a special mode that loads every level, places the camera at specific positions, measures the performance and collects those results for me to look at.

It would be very useful to include the "Render Statistics" in this report as well, because this would allow us to automatically detect whether a specific part in the game issues too many SetPass Calls for example.

Having this information available in a development build is helpful for the QA- and Art-department as well.

I believe a build (in development mode) does track these statistics already, since if I attach a Profiler, I can see the Render Statistics.

Would it be possible to expose the "Render Statistics" to be accessible in a build. Basically everything that is displayed in the Game View Overlay exposed to the Profiler API for example, which already contains various "GetMemory" API's.

I asked this question a few years ago already ( see here ).


Hi Peter,
This is indeed on our backlog and your detailed feedback here as well as in your old post is very valuable.

If you could indulge me for a bit, I'd like to dig a bit deeper to better understand the underlying problems you are looking to solve with this. I understand the general need for this and have some conceptions about use cases but I want to leverage your input here as well, while we're at it:
Could you maybe briefly specify which stats you would like to rely on for which purposes, to solve which problems?

This will help us not only with exposing the right stats in a way you'd expect them, but also informing development of other tools.

Thank you :)

Hi Martin,

thanks for your answer! The following text describes how we used to worked in a previous company...

When starting a new project, we usually defined performance budgets via Trial&Error on a particular platform. Finding out how many Render-State changes, Vertices, and so on the hardware can handle before dropping under the frame-rate we have to achieve.

Then we had different automated performance tests, some of these were continuous integration performance tests.

For example, each level had several pre-defined camera positions. The performance test placed the camera at each of these points for a certain time-frame and moved the camera around, for example a slow 360° degree turn around the Y-axis within 30 seconds for a first-person shooter like game.

The test measured the CPU performance during the entire time. At end end of the test, we have a graph similar to the one in this post . The test in the linked post is from my hobby-project though, but the idea is the same, just a simpler implementation in my hobby-project.

If we could also measure other statistics beside "Framerate", it would allow us to automatically detect what's most likely the issue for the frame-rate drop in a certain camera view.

For example, if one of these camera positions drops below 30 fps and we detect there were 10x the amount of vertices than our budget allows, it immediately gives a clue where to look in order to fix it. This allows non-programmers to understand where to look for performance issues. Also simple things like "are we CPU or GPU bound" is really useful to have.

If the performance test generates a text like:
Level "Harbour" camera position "Region 4" (Rotation=0,54,0) dropped to 20 fps, pushing 10000000 vertices more than in our budget.

... can be understood by non-programmers as well, for example by level builders. Especially if he/she just worked in this area and the test runs after he/she pushed the changes, then after the test "failed" generates an email with this text and sends it to him/her or a selected group of people.

Because we couldn't generate this detailed information why a performance test failed, a programmer needed to investigate always.

EDIT: We also had a "performance overlay" in the game that we could activate at any time. It displayed CPU ms, Memory consumption, etc. Adding more detail to this would also allow situation like this:
Inhouse QA tests game. Comes into a region that drops to 10 fps. Checks Performance Overlay. See's 100000 Draw-Calls. Moves over to level design "Didn't you add more items to this region yesterday? Yes I did, looks great right? It sure does, but maybe you placed a little too many objects. I'll create you a ticket". It's also something that will move work away from a programmer.

I hope this clears things up, otherwise please let me.

Edit2: something like "gc allocs per frame" would be nice too.


I'm here looking for this as well. It would be extremely useful in VR, as I am constantly looking around a scene, taking the HMD off to look at the computer monitor to check the stats. Its current implementation is incredibly tedious for VR development.

Is this still on your list? I’m asking, because I brought it up about 2.5 years ago and at that time you replied “We had this in plans”. :slight_smile:


Hi @Peter77 ! Thanks for reminding our promises! This time we are actively working on all profiler stats being available in dev players (and some in release players). We’ll share more info once we have an api ready


That’s great news! Thanks for your reply!

1 Like

Adding my vote to this, I was recently writing a custom SRP and would like to make runtime troubleshooting easier for our members, so far I only managed to extract active lights and reflection probe count from SRP.

I would love to see Drawcall, Shadow Caster, Renderer and even Tris count exposed in some ways.

You can check out the Rendering Profiler Module page that just got updated for 2020.2 to list all Counters and whether or not they are available in release players. It also includes a code snippet on how to use those in players. There is no single Counter for the count of all Renderers but the other three you listed are indeed Release Counters.


I couldn't find information how I would get the "Draw Calls" for example. I found this:
ProfilerRecorder.StartNew(ProfilerCategory.Render, "SetPass Calls Count");

I wonder what the "SetPass Calls Count" is. The docs say "Profiler marker or counter name", but is this a hard-coded identifier that I use to retrieve the actual "set pass calls", or is it just a name I specify myself to display it in an UI for example?

I couldn't find a listing of all available "Profiler marker or counter name" items if that's a hard-coded identifier.

I’m not sure why you didn’t find that. If that quote is from the page I linked to, then the info on how to get draw calls is one line underneath the one you quoted, as well as in the table, and is the Counter with the name of Draw Calls Count.

The "Statistic" Column in that manual page lists the hard coded Counter Names, that are used to create the Counters in Unity’s backend and these Counter Names (together with their category) are the ones you need to supply to the ProfilerRecorder in order to record these values.

Think of it this way: Whether it is us who defined Marker or Counter names in the Engine code, or you in your code via ProfilerMarker or ProfilerCounter (check here for more details on the data flow), doesn’t matter. The ProfilerRecorder will find the native representation for either of these by name and category from a lookup table and start recording their measurement. We also use their names in the Profiler UI and document them on each Profiler Module that is already using the new Counter API (in 2020.2 that would be the Rendering, Memory and Virtual Texturing modules). These names will also be used in the Profiler Module Editor and any custom Profiler Modules you’ll create with that editor.

If you are doing your own Editor or in-game UI then what name or generally how you want to display these values is entirely up to you.

As soon as the Profiler first receives data for a Counter, they will show up in the Profiler Module Editor and as soon as a Counter is initialized, they will also be contained in the list populated via ProfilerRecorderHandle.GetAvailable() in the runtime.

1 Like

Probably because I was looking at the Scripting API documentation and not the manual.

OK, so the names are hard-coded id's basically. Can you add a static class that contains all the names? Using hard-coded strings everywhere is error prone from an usage point of view and having that class basically provides documentation for free through code-completion.

It also gets rid of the problem when you suddenly rename an internal string, which occurred multiple times with those hard-coded platform id's one has to pass to various texture import API's. It falls apart quite easily.

static class ProfilerIds
    public const string drawCallsCount = "Draw Calls Count";

    // and so on...
1 Like

Probably not really your fault :slight_smile:
We are updating scripting api to reference manual pages.

Great suggestion! Thanks for the feedback - we’ll add constants (more likely as category/name pairs) in Unity.Profiling namespace.

Yes, definitely we already threat those names as a public api and have test coverage in place. Making constants public would give us extra protection.


It looks like this has landed in Unity 2020.2 :)

Thank you @alexeyzakharov @MartinTilo and the rest of the gang!


Is there a way to get the time taken by the render thread ?

1 Like

Yes. By setting ProfilerRecorders up that record the relevant Render Thread Base samples, like Camera.Render.

Keep in mind that some of these occur on the main thread and the Render Thread. So to isolate out the Render Thread times for those, set up 2 recorders each. One set to record from all threads, one to only record the current thread (i.e. main thread). Then subtract the main thread times from the Render thread ones. Be mindful when in the frame you measure this as the render thread might still be busy with some of those markers that started in the previous frame.