manski's blog

Windows Performance Counter Types

There are several types of performance counters in Windows. However, I had a hard time of understanding all these types just from their documentation. So I decided to compile some examples for each counter type.

I also wrote some C# code to demonstrate how to use performance counters. You’ll find it at the end of this article.

Notes:

  • You can watch performance counters with the Performance Monitor (perfmon) that comes with Windows. However, it can’t display negative values so some counters can’t be monitored properly.
  • I use the .NET names for performance counter types in this article.
  • Categorization of the counter types follows the official documentation.

Terminology

Performance counter
A counter to monitor performance of a running system (e.g. CPU usage). Is basically just an int.
Sampling, Measurement
Read the value of a performance counter (at a certain point in time)
Sampling rate
How often a performance counter is sampled (e.g. every second)
Time frame
Time between two samplings (usually one second)
Monotonicity

Whether you can increase and/or decrease the value of a performance counter. (Some counters require you to always increase – but not decrease – their values.)

Composite Counters

Before we begin, a word about (what I call) “composite counters”.

As the name suggests, these counters are composited of two counters – a parent counter and a base counter. Parent counters can be monitored, base counters cannot.

To register (new/custom) performance counters in Windows, you need to pass a list of performance counter creation data to PerformanceCounterCategory.Create(). In this list the base counter data must come immediately after the parent counter data.

The following table lists which base counter type can be used with which parent counter type:

Base counter type Parent (composite) counter types
AverageBase AverageTimer32, AverageCount64
CounterMultiBase CounterMultiTimer, CounterMultiTimerInverse, CounterMultiTimer100Ns, CounterMultiTimer100NsInverse
RawBase RawFraction
SampleBase SampleFraction

Instantaneous Counters

Displays: the most recent measurement

Types NumberOfItems32, NumberOfItems64, NumberOfItemsHEX32, NumberOfItemsHEX64
Description The simplest counter; just displays the raw number without any calculations; the HEX variants indicate that the values should be displayed as hexadecimal (instead of decimal)
Example Overall database operations
Displays as raw count
Composite no
Monotonicity increasing, decreasing, remain static

 

Types RawFraction
Description Used to display fractions (instead of integers like with NumberOfItems); usually interpreted as percentage
Example Percentage of maximum allowed concurrent database connections; RawFraction: current connection count; RawBase: maximum connection count
Displays as (RawFraction / RawBase) * 100
Composite yes (base: RawBase)
Monotonicity increasing, decreasing, remain static

Average Counters

Displays: average of values during time frame

Types AverageCount64
Description Used to describe how many items were processed per operation in average
Example Database operations per transaction; for each operation, you’d increment AverageCount64 and for each completed transaction you’d increment AverageBase
Displays as average items per operation (during the last time frame)
Composite yes (AverageBase)
Monotonicity increasing, decreasing, remain static
Note

The difference to RawFraction is that RawFraction would be displayed as the average since the creation/last reset of the counter, while AverageCount64 would be displayed as average during the last time frame (usually a second).

Types AverageTimer32
Description Used to describe how long an operation takes in average
Example Average time each database transaction takes; for each transaction, you’d measure the execution time of the transaction with Stopwatch and increment AverageTimer32 by Stopwatch.ElapsedTicks; and for each completed transaction you’d increment AverageBase by one
Displays as average time per operation (during the last time frame)
Composite yes (AverageBase)
Monotonicity increasing, decreasing, remain static

 

Types CountPerTimeInterval32, CountPerTimeInterval64
Description Usually used to describe the average count of items in a queue; if you have 0 items at the beginning, and 10 items after 5 seconds, then the rate would be displayed as 2.
Example Monitoring a worker queue that contains jobs to run in the background
Displays as average count change per time frame
Composite no
Monotonicity increasing, decreasing, remain static
Note

I found the information about CountPerTimeInterval somewhere on the internet. However, in my test I couldn’t get it working properly. The values of this counter would display as extremely small in Performance Monitor; something like 10.5E-06 – although it should be something like 10.5. Also Performance Monitor doesn’t seem capable of displaying negative values. They are necessary however when the queue handles requests faster than new requests get placed into it.

Types SampleCounter
Description Shows the average number of operations completed in one second (according to MSDN). Seems to be identical to RateOfCountsPerSecond (see below).
Example Web requests served per second; for each served request, you would call Increment() on the counter
Displays as average operation per second (during the last time frame)
Composite no
Monotonicity increasing, decreasing, remain static

Rate Counters

Displays: rate of item count growth

Types RateOfCountsPerSecond32, RateOfCountsPerSecond64
Description Used to display how many items were – in average – processed per second during the last time frame. Seems to be identical to SampleCounter.
Example Web requests served per second; for each served request, you would call Increment() on the counter
Displays as average item per second (during the last time frame)
Composite no
Monotonicity increasing, decreasing, remain static

Percentage (of Time) Counters

Displays: calculated values as a percentage

Types CounterTimer, CounterTimerInverse, Timer100Ns, Timer100NsInverse
Description Used to display the percent of time that a component is active (CounterTimer) or inactive (CounterTimerInverse).
Example % of time an operation is running; you’d measure the time the operation takes to execute and then increase the counter’s value by this amount
Displays as % of time a component was active during the last second (or other time frame)
Composite no
Monotonicity increasing, decreasing, remain static

Notes:

  • CounterTimerInverse is like CounterTimer but measures how long the component is inactive. So, you’d measure the time from when the component became inactive to the next time it becomes active and increase the counter’s value by this amount.
  • For CounterTimer and CounterTimerInverse, use Stopwatch.ElapsedTicks as counter value. For Timer100Ns and Timer100NsInverse, use DateTime.Ticks instead. (Note that these ticks have different lengths, as stated here.)

Types CounterMultiTimer, CounterMultiTimerInverse, CounterMultiTimer100Ns, CounterMultiTimer100NsInverse
Description Work exactly as their non-multi counterparts (e.g. CounterTimer for CounterMultiTimer), except that the result is divided by CounterMultiBase
Example % of time an operation is running, if multiple calls to the operation can run in parallel; you’d measure the time the operation takes to execute and then increase the counter’s value by this amount; CounterMultiBase would be set to the number of parallel operations
Displays as % of time a component was active during the last second (or other time frame)
Composite yes (CounterMultiBase)
Monotonicity increasing, decreasing, remain static

 

Types SampleFraction
Description Average ratio during the last time frame in percent
Example Average ratio (%) of successful operations during the last time frame; you would increment SampleBase for every operation, and SampleFraction for each successful one.
Displays as average ratio in %
Composite yes (SampleBase)
Monotonicity increasing, decreasing, remain static

Difference Counters

Displays: difference between value at the beginning and the end of the time frame

Types CounterDelta32, CounterDelta64
Description Displays the difference between the raw value at the beginning and the end of the measured time frame
Example Anything you need to display as difference
Displays as difference
Composite no
Monotonicity increasing, decreasing, remain static
Note

Performance Monitor can’t display negative values.

Types ElapsedTime
Description Time in seconds since the counter was created sometime in the past. Note that you can’t set the value of this counter manually; it automatically increases.
Example System up time
Displays as seconds
Composite no
Monotonicity increasing, decreasing, remain static
Note

I have no clue what start time is chosen for the counter. It’s certainly not the time the counter was created. In my example, where I created the counter just a couple of seconds ago, it already had a value of about 27 hours (was even longer than my system up time).

Example Code

Here’s an example project that demonstrates the various performance counters:

PerformanceCounters.zip (15 KB)

7 comments

  1. Stephan Volmer said:

    The StartTime of the ElapsedTime performance counter is set via RawValue. The value of the performance counter is then simply calculated by the samples TimeStamp – RawValue.

    • hanu replied:

      hi stepehn. can u pelase exlpain elaboratly about how to use ElapsedTime in performance counters

  2. Eric T. said:

    Thanks – very useful as reference.

    When I add a performanceCounter programmatically, is it possible to change the default scale from 1.0 that will be used when the counter is viewed in Perfmon? Currently I always have to manually adjust the scale for viewing.

    • Sebastian Krysmanski (post author) replied:

      No, I don’t think that’s possible. At least I haven’t seen anything like this.

  3. Vladimir Kravtsov said:

    Thanks, Sebastian. It is very useful work because counter type definitions are sometime vague. I still can not understand if it is possible to derive rate from the value of CounterDelta32. After reading your post I started to think that it is necessary to have counter of type ElapsedTime and to get rate in counts-per-second I have to divide the value of CounterDelta32 by the value of ElapsedTime. Please, let me know if I understood things correctly.

  4. Patrick said:

    Best article I’ve read so far for performance counters. Thanks for distilling the information!

  5. Michael said:

    Hey, thanks.

    For AverageTimer32, you were clear:
    “measure the execution time of the transaction with Stopwatch and increment AverageTimer32 by Stopwatch.ElapsedTicks”

    The Microsoft docs were not so clear. The sample code shows:
    PC.RawValue = Stopwatch.GetTimestamp();
    which I think is incorrect. It should be:
    PC.IncrementBy(Stopwatch.GetTimestamp())

    So thank you for helping me see why my AverageTimer32 values were so strange.

    Sample from https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.performancecountertype?view=netframework-4.8

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.