Developing with Performance Counters

Developing with Performance Counters

The new Performance Counter Library (PERFLIB version 2.0) included with Windows Vista® offers a number of advantages to the developer, including:

  • Redesigned so that performance counters can be exposed and consumed in a much simplified manner. Application developers no longer are required to create separate performance extension DLLs, and callback functions are typically no longer required.

  • Finer granularity queries are supported. Consumers can now ask for a specific counter within a specific instance, in addition to returning entire data sets. This greatly improves scalability of applications.

  • A standard inter-process communication (IPC) mechanism between a provider and consumer that is based on Event Tracing for Windows (ETW) notification, and which results in simplified development and more uniform and reliable code.

  • More reliable and secure operation because of design changes. For example, DLLs no longer use shared memory to communicate with their respective applications, risking possible data corruption. Previous versions sometimes required the user to modify the registry in order to fix certain problems, such as missing performance counters. Performance counter data is integrated with system security, including User Account Protection (UAP). Administrative or Performance Logs group privileges are required to access performance logs.

  • Developers should provide both 64-bit and 32-bit versions of the performance provider on 64-bit versions of Windows Vista.

  • Provides language-neutral universal identifiers, which are available across PCs.

  • The new Counter Preprocessor (CTRPP) tool generates skeleton code for performance counter providers.

For more information, see "Performance Counters" in the "System Services" section of the Windows SDK.

.NET Framework 3.0 applications can access performance counter information through the classes in the System.Diagnostics namespace, primarily through the PerformanceCounter class. For more information, see "Monitoring Performance Thresholds" in the Windows SDK. Managed applications also have access to performance data related to the CLR environment, such as JIT, managed exceptions, COM interop, thread and memory, and so on. For more information, see "Performance Counters in the .NET Framework" in the Windows SDK.

ASP.NET, ADO.NET and Developer Story Windows Communication Foundation supply rich sets of performance counters for their associated applications and administration tools. For more information, see "Performance Counters for ASP.NET", "Using ADO.NET Performance Counters" and "WCF Performance Counters" in the Windows SDK.

Windows Management Instrumentation (WMI) contains three pre-installed data providers and dozens of pre-defined performance counter classes, both of which can be extended by the developer. For more information, see "Monitoring Performance Data" in the "Windows Management Instrumentation" section of the Windows SDK.

Architecture and Concepts

The following diagram shows the relationship between the various runtime components, libraries and tools in the Windows Vista performance counter subsystem.


From a development and architectural standpoint, creating a performance counter provider is much more complex than consuming the data. Generally, a provider performs the following steps to create, load, and unload a counter.

  1. The developer describes the new counter in a XML-based counter manifest. This manifest contains attributes of the counter, such as parameters, groups of counter, name, and GUID. It is easiest to start with an existing sample manifest and modify it appropriately. For more information on the manifest schema, see "Performance Counters Schema" in the Windows SDK.

  2. After the manifest is prepared, the developer can generate the starting "skeleton" source files for the project using the command-line based preprocessor tool CTRPP. One important and time-saving operation in the generated code is the initialization of the provider.

  3. The developer adds customized code to report data information (instrumentation) and optional code during initialization, loading and unloading.

  4. The developer builds the counter executable.

  5. Using the deployment tool LODCTR, the provider registers and loads the developed performance counter. The provider is then available to consuming applications.

  6. When provider data is no longer necessary (or its executable must be updated), the counter should be unloaded by using the command line tool UNLODCTR.


Although providers created in the manner described above will run only on Windows Vista and later operating systems, the data they provide can be remotely accessed by PERFLIB V1 consumers on the same or remote PCs.

Developing a performance data consumer is more straightforward, and the Performance Data Helper (PDH) functions are provided for this purpose. Two general types of operations can be performed with these functions: user browsing and programmatic querying. User browsing is supported by the PdhBrowseCounters function, which displays a standard dialog-based UI that enables the user to specify the computer, the performance object and counters, and so on. Alternately, log files can be browsed with the same UI by using the PdhSelectDataSource function. For more information, see "Browsing Counters" in the Windows SDK.

Other PDH functions are used to query providers or log files for performance data using the following generalized steps:

  1. Create a query using the PdhOpenQuery function.

  2. Add counters to the query using either the PdhAddCounter or PdhAddEnglishCounter functions (one call for each counter).

  3. Collect the performance data, using one of the PdhCollectQueryData, PdhCollectQueryDataEx, or PdhCollectQueryDataWithTime functions.

  4. Display or use the performance data in either raw or normalized form. The functions PdhGetFormattedCounterValue and PdhGetFormattedCounterArray are used to display formatted single and sets of values, respectively. In contrast, PdhGetRawCounterValue or PdhGetRawCounterArray can be used to access unformatted values.

  5. Close the query using the PdhCloseQuery function.


It is also possible to access performance counter data through registry operations on pseudo-keys, but this is discouraged because it has several disadvantages: it is more error-prone, increases the risk of registry corruption, is less efficient when accessing individual counters, and cannot be used to access data from log files.

For more information, see "Consuming Counter Data" and "Performance Counters" in the Windows SDK.

Performance Alerts

Windows Vista also introduces a new feature, Performance Logs and Alerts (PLA), which enables applications to generate alert notifications based on specific performance counter thresholds. This COM API is targeted at C/C++ developers. For more information, see "Performance Logs and Alerts" in the Windows SDK.


The following new functions have been added in PERFLIB version 2.0. They are divided into the following two groups, for providers and consumers of performance counter data.

New PERFLIB 2.0 Consumer Functions

Consumer functions are for applications that query (and possibly modify) performance counter data. These functions are declared in Pdh.h and contained in Pdh.lib.




Adds the specified language-neutral counter to the query.


Collects the current raw data value for all counters in the specified query and updates the status code of each counter.


Validates that the specified counter is present on the computer or in the log file.

New PERFLIB 2.0 Provider Functions

Provider functions are either implemented by, or usable by applications that are the source of performance counter data. These functions are declared in Perflib.h and contained in Advapi32.lib.




Providers can implement this function to receive notification when consumers perform certain actions, such as adding or removing counters from a query. PERFLIB calls the callback before the consumer's request completes.


Creates an instance of the specified counter set.


Deletes an instance of the counter set created by the PerfCreateInstance function.


Retrieves a pointer to the specified counter set instance.


Updates the value of a counter whose value is a pointer to the actual data.


Specifies the layout of a particular counter set. The CTRPP tool generates the code that calls this function.


Updates the value of a counter whose value is a 4-byte unsigned integer.


Updates the value of a counter whose value is an 8-byte unsigned integer.


Registers the provider. The CTRPP tool generates the code that calls this function.


Removes the provider's registration from the list of registered providers and frees all resources associated with the provider. The CTRPP tool generates the code that calls this function.

Deprecated Functions

The following public functions are not intended to be used directly by application programmers: PdhCreateSQLTables, PdhGetLogSetGUID, PdhSetLogSetRunID, and PdhVerifySQLDB.