Profiler Pro

Helping you take ProcessWire performance to the next level

ProfilerPro is a commercial module for web developers that profiles all the important stuff going on in your ProcessWire 3.x powered site. It collects the data to determine where bottlenecks and issues are present in an easy-to-use admin tool. ProfilerPro also provides the support and services via our online support board (maintained by ProcessWire's lead developer), helping you to fix bottlenecks and optimize your site.

About Profiler Pro

The importance of website performance

Website performance is such an important aspect of web development. The performance of a site can literally make or break the effectiveness of it. When users wait, they leave. When Google sees slow performance, it penalizes you for it. This is why a first priority for the ProcessWire core has always been making it well optimized and fast. In addition, we care a lot about helping our users develop sites that perform well. ProfilerPro is a commercial module that takes that to the next level.

ProfilerPro times and profiles all the important stuff going on in a ProcessWire site from page rendering, file execution, API calls, hooks, and more. In addition, ProfilerPro can also profile front-end events like how long it takes the browser to load all the assets at each URL. ProfilerPro collects all this data from live traffic and combines it with other instances of the same data to produce a table of output that makes bottlenecks obvious.


ProfilerPro is part of the ProDevTools set of modules and currently requires ProcessWire 3.0.40 or newer. In the near future, ProfilerPro will also support ProcessWire 2.8 as well. ProfilerPro does not work with ProcessWire 2.7 and earlier.

Tracking down bottlenecks

ProfilerPro measures all the important stuff going on in your site and helps you isolate bottlenecks and other places that might need attention. ProcessWire is very flexible, but with that flexibility comes a lot of power that enables you to either develop things that run beautifully fast, or painfully slow. Sometimes it's not apparent when something is a bottleneck until a busy site launches or the combined effect of real traffic over multiple requests is observed. There are all kinds of other factors that may come into play as well. ProfilerPro is the perfect tool to help you identify and fix those issues.

Here to help you

I often find myself in the position of helping people locate and fix bottlenecks on websites and applications, and this tool is something I've always wished I had. While ProfilerPro is a tool to identify issues, the support board is dedicated to helping users analyze, fix and optimize performance issues. When you purchase ProfilerPro, you are purchasing a helpful support service with the ProcessWire core developer to help you use the tool and isolate and resolve bottlenecks. So ProfilerPro not only helps you find the bottlenecks, but provides the support to assist you in resolving them and develop more efficiently in ProcessWire.

Monitoring events

ProfilerPro is built to measure live-traffic on a site, rather than just testing things out during development. It gives you an actual real picture of what's going on, rather than one from an isolated development environment. Of course, ProfilerPro will be incredibly helpful on both development and live sites, but it opens the door to observe what's happening in actuality, rather than just in testing.

By default, ProfilerPro tracks all types of events, but you can specifically enable or disable any of them on the configuration screen. Regardless of which event types you are monitoring/tracking, they are all recorded and shown in the ProfilerPro page in the admin.

When using the ProfilerPro tool in the admin, you get a real-time live view of everything going on. When a new event occurs, it shows up on the screen without you having to refresh (though we do also provide a dedicated refresh button). As a result, using ProfilerPro is not only helpful, it's incredibly fun to watch what's going on in real-time.

Server-side events

Server-side event monitoring is the primary focus of ProfilerPro, and it lets you monitor several different types of them, including the following:

  • Pageviews – Monitors times taken to render entire pages.
  • FilesMonitors times taken to render individual files.
  • Hooks Monitors times taken to execute hooks.
  • $pages API Tracks times taken by common $pages API calls.
  • MyPHP Tracks times of specific events in PHP code (template files, etc.) that you designate.

Client-side events

ProfilerPro also can monitor client-side events. Meaning, it tracks times from the visitor's browser, and then sends them back to the server, in a completely transparent manner. This is a major advantage relative to monitoring this stuff in your own browser because you get a much bigger picture that covers all users and browsers hitting your site. It identifies specifically what pages users are waiting for and makes it clear which pages might be too heavyweight in terms of javascript, images or other client-side factors. It reveals bottlenecks that could be completely missed with your own browser's development tools. ProfilerPro monitors these types of client-side events:

  • JS ready: Tracks client-side time from when the browser starts parsing the HTML to when the DOM is ready.

  • JS load: Tracks client-side time from when the browser starts parsing the HTML to when the page is fully loaded with all assets, images, etc.

  • MyJS: Tracks times of specific events in Javascript that you designate.

The first two events mentioned above are tracked automatically, without you having to do anything at all other than checking the box to enable it in the ProfilerPro configuration. The last event (MyJS) lets you track any block of Javascript using the profiler Javascript API variable with simple start() and stop() methods.

Profiling event details

ProfilerPro maintains a name for each event, for instance, the name of a page view event would be the page's URL and request method. The more occurrences of an event having a given name, the more accurate ProfilerPro's data becomes. With that in mind, ProfilerPro collects the following information for each event:

  • Average execution time of event
  • Total combined execution time across all events of the same name
  • Total quantity of occurrences
  • The date/time of the oldest tracked occurrence
  • The date/time of the more recent tracked occurrence
  • Fastest execution time of an individual occurrence
  • Slowest execution time of an individual occurrence
  • The most recent execution time of an individual occurrence

The first two data points mentioned above (average and total times) can also have pie or donut graphs enabled, which makes comparison at a glance a simple matter. Of all these data points, the average execution time is generally the most useful, especially as the quantity of occurrences increases.

Configuring Profiler Pro

You can configure ProfilerPro by clicking the "Config" tab when in the application (Setup > ProfilerPro). You will see the following configurable fields:

Profiler enabled?

  • No: This disables the profiler
  • Yes: This enables the profiler for all traffic. This is the recommended setting when profiling.
  • Superuser only: This enables the profiler only for Superuser traffic. This is useful for testing things out on your own before enabling it for everyone else.

Event types to record

This is one of the most important settings in ProfilerPro, as it dictates what will be profiled. Initially you may want to record all event types to get a feel for the type of data they are collecting. Over time, disable the event types that you don't need. See the section on ProfilerPro event types for a description of each of these event types.

Columns to display

This determines what columns and data are shown in the ProfilerPro admin tool. At minimum we recommend always having a column that shows "average time" as this tends to be one of the most useful columns. See the ProfilerPro column types section for details on each of the columns.

Time precision

This affects the time precision shown in the ProfilerPro admin tool and does not affect the precision of the times that are actually recorded. A well selected time precision helps you focus in on real issues. For instance, if you are only concerned about tracking Pageview and File Render times after they get to be at least half a second (0.5) then you probably don't need to select a time precision any higher than "0.1". But such a precision would likely not be enough for the more granular timed events like Hooks or $pages API calls. The default setting of "0.001" or "0.01" are good places to start with this setting.

Note that time precision is not applicable when "milliseconds" are selected as the time format.

Time format

  • Seconds: Makes the time display as a number of seconds (floating point). This is the default setting.

  • Milliseconds: Makes the time display as milliseconds. Note that when milliseconds are selected, the "time precision" is no longer applicable.

Minimum time threshold

This represents the minimum elapsed time required for an event to consume before it will be considered important enough to record. If set too low, ProfilerPro will use more resources recording events that are likely irrelevant for analysis. If set too high, ProfilerPro might miss events that consume a lot of combined time over multiple instances. The default setting is 0.0001, which means ProfilerPro will be recording a lot of data. If your focus is purely on Pageview, File render, and JS times, a higher minimum time threshold would be appropriate. For instance, if you only want to track events that are taking 0.25 seconds or longer (250ms) then you'd set your minimum time threshold as 0.25.

Minimum quantity threshold

This specifies the minimum number of events required to be recorded before the times are shown in the admin tool. The reality is that if you see a high average time for an event that's only occurred once or twice, then you likely can't assign much value to it. It's only when high average times are combined with high quantities that bottlenecks become truly apparent. By specifying a minimum quantity threshold, you can simply exclude any events from appearing at all until they've reached that minimum quantity of occurrences. Once you are familiar with using ProfilerPro, we recommend setting the minimum quantity threshold to at least 3.

Refresh every [n] seconds

This specifies how often the ProfilerPro admin tool should refresh the displayed data. This enables you to get a real-time look at what's happening in your site, without constantly refreshing the page yourself. If your server is kind of slow, you might only want to automatically refresh it once every 10 seconds or so. Or on a fast server, you might want to automatically refresh every 3 seconds.

Skip templates

If you want the profiler to be disabled when rendering a page using any particular templates in your site, select them here. By default, the "admin" template is skipped over, as ProfilerPro is intended for profiling the front-end of your site, not the admin. If there are other templates in your site that really aren't applicable for profiling, you should select them here.

Limit templates

If you want to limit profiling only to rendering of pages using specific templates, select them here. When a page is using a template that's not selected here, no profiler events will be recorded. If no templates are selected here, then this field is not applicable.

Event types

Below are detailed descriptions and important notes for each of the event types recorded by ProfilerPro. This section can help you determine which event types you should record, as well as how to analyze the data that each records.


This records the entire time to render a page, and is one of the most useful event types to track in ProfilerPro. More specifically, this tracks the time it takes to execute the Page::render hook for the requested page, making it exclusive to timing your own front-end code.


This records the times required to render/execute files in your site, and is also one of the most useful event types in determining which files might have bottlenecks. It includes your site's template files, but also any other files rendered with $files->render() API method call, wireRenderFile() API function call, or the TemplateFile class.


This records execution time for common page finding methods from the $pages API variable. This is especially useful for spotting page-finding selectors that might need optimization.


This records the time required to execute hooks. This is primarily useful if you are wanting to determine if a 3rd party module has hooks that are executing slowly and might be causing a bottleneck.


When you record profiler events manually (with the $profiler API variable) this is where those events go. As a result, we recommend keeping this event type enabled.


This is a client-side (Javascript) event type that records the time to reach the DOM Ready (document.ready) state for users browsers, and better yet, the window.load state, when all assets are loaded in the user's browser. Because there's a diversity of bandwidth out there, it's best to collect a lot of data for this event type before drawing any conclusions. But this can be a great way to determine which URLs users are spending the most time waiting for. Note that the recorded times start from the moment their browser starts parsing the HTML <head> section.


This is also a client-side (Javascript) event type, except that it is specific to your own Javascript events. ProfilerPro provides a "profiler" API variable to your front-end with start/stop methods that you can use to time how long it takes to execute events in JS. Use this as an alternative to your browser's development tools when you want to track times across a broad range of visitors/traffic.

Column types

This section documents each of the column/data type that ProfilerPro can display in the admin tool. Discussion includes situations where you might want to use this column type and how you might want to analyze the data from it.

Average time (AVG)

This shows the average time to execute an event. Meaning, the total execution time across all events of the type, divided by the quantity that have been recorded. When you see high average times combined with high quantities, then it is indicative of a bottleneck. We recommend choosing one of the options that includes the pie or donut graph, as these graphs are a useful visual indicator that helps you focus in on what's most important.

Total accumulated time (TOTAL)

This represents the total time recorded across all occurrences of the same event. This is particularly useful in showing you where most of the time is being spent in your site. However, be careful not to assign to much value to this number, as it is not typically indicative of a bottleneck unless also combined with high average times.

Quantity of events (QTY)

This indicates the number of the same events recorded that form the total accumulated time and average time. The higher this number is, the more important you should consider the "average time" column. For instance, a high average Pageview time with only 2 recorded events for a given Page is likely not a call to action. Whereas a high average Pageview time with 200 recorded events strongly points to a bottleneck with that Page.

Newest recorded event time (NEWEST)

This indicates the last time that a particular event occurred. This is useful in determining whether a particular event is still applicable. For instance, if you are observing high average times for an event, but with the "newest" number more than a week ago, it could very well be that the issue has already been resolved, or at least is not often affecting visitors.

Oldest recoded event time (OLDEST)

This indicates the first time a particular event occurred. Combined with the "newest" column, it gives you the time span of events.

Fastest recorded time (FAST)

This records the fastest time recorded for a particular event, or the "best case scenario". If you are seeing a particular event with high average times, but with a "fastest" time that is significantly lower than the average, it could indicate that there are other conditions at play that affect how quickly the event can execute. Then again, it might also indicate something that was a bottleneck but no longer is. Please note that data does not start recording for this column unless/until it is selected in the configuration.

Slowest recorded time (SLOW)

This records the slowest time recorded for a particular event, or the "worst case scenario". If you are seeing a "slowest" time that's significantly lower than the average time, it could indicate that there are other conditions that affect the speed at which the event executes. It might also indicate something that was a bottleneck but no longer is. Please note that data does not start recording for this column unless/until it is selected in the configuration.

Last recorded time (LAST)

This column indicates the time taken by the most recent/last recorded event. This time may give you look at the current state relative to the combined state. For instance, if you see a fast time here, but a slow time for "average" than it could indicate something that was an issue but has already been fixed. However, since this "last" time is only indicative of a single recorded instance, it shouldn't be given too much weight.


When to use + performance considerations

ProfilerPro is not a tool that you would typically have permanently active. It is a tool for temporarily profiling performance of a site or application in order to identify and isolate bottlenecks. It does add some overhead to page delivery times since it is essentially timing everything that happens and recording it to the database. Though when testing on our site ( there is not a noticable difference in page delivery speed, and great effort has been made to ensure ProfilerPro adds as little overhead as possible. However, it does add some overhead, and it does record a lot of information to the database. So once you have reached resolution of issues identified with this tool, you will likely want to disable it until new items need testing.

Profiling live traffic

While usage of ProfilerPro is typically isolated to times when you are testing, it's also important to keep in mind that ProfilerPro is best when profiling live traffic. It will likely find things that would not otherwise be apparent when testing on your own or in a development environment. The more instances of a particular event that occur, the more actionable trends become apparent in ProfilerPro. We typically let ProfilerPro run for a day or two at a time in order to gather a large set enough set of data to make trends clear. If using ProfilerPro while also using ProCache, you'd want to let it run even longer, as traffic is only profiled when ProcessWire executes.

Choosing event types

ProfilerPro includes a lot of different event types that you can record. When you aren't sure what exactly you'll be looking for, it might be a good idea to enable them all. That should give you a better idea of where to focus. But once you do know where to focus, it's a good idea to disable the event types that you don't need. The fewer event types being recorded, the fewer resources needed.

Note that tracking of client-side (Javascript) events like load, ready, and MyJS events consume more resources than server-side events. That's because event data recorded from Javascript needs to be sent back to the server on every request.

Identifying and fixing bottlenecks

ProfilerPro collects data, but what happens with that data after its been collected is a matter of analysis and action. ProfilerPro can identify bottlenecks, but it can't fix them. That's why an important part of ProfilerPro is our support board (requires login). When you think you may have a bottleneck and aren't sure how to fix it, we recommend creating a new thread that contains the following information:

  • Summary of issue(s) you think you've found.
  • A CSV file of the ProfilerPro data, if helpful (use the built-in CSV export function.
  • If the issue can be isolated to a particular template file or other type of file, attach a copy of it to the post. Likewise, if isolated to a particular URL, API method call, or anything else, please provide as much detail as possible. If any information you need to include is confidential, please send it via private message (PM) to forum user "Ryan".

Profiling custom events

Server-side custom events (MyPHP)

Server-side event monitoring is the primary focus of ProfilerPro, and it lets you monitor several different types of them. All of the event types are monitored automatically for you, except for MyPHP events. Meaning, there is no need to use the ProfilerPro API unless you want to monitor your own custom events outside of those already included with ProfilerPro. For this reason, this section will focus on MyPHP (custom) events.

ProfilerPro provides an easy-to-use $profiler API variable with simple start() and stop() methods. Here's an example of tracking your own server-side events, like you might do from a template file:

$event = $profiler->start('event name');
// ...
// execute some code in between
// ...

Replace the 'event name' above with whatever text you'd like to use to refer to your event in the ProfilerPro admin tool. Once events have been recorded for your custom event, it will show up in the MyPHP tab of the ProfilerPro admin tool. If you don't see your event, double check that your "minimum time threshold" and "minimum quantity threshold" configuration settings allow it to be reported.

Client-side Javascript custom events (MyJS)

Note that regular JS events (ready and load times) are profiled automatically when JS events are enabled, so you don't have to do anything further. This section covers MyJS events, which is what you'd use when you want to time/profile your own custom things from the JS side.

Profiling of client-side (Javascript) events is a secondary focus of ProfilerPro. The API for client-side events is similar to that for server-side events, except that it is Javascript (rather than PHP) based. A Javascript "profiler" variable is provided in global variable scope when tracking of Javascript events is enabled in ProfilerPro.

var event = profiler.start('event name');
// ...

If preferred, you can also stop a MyJS event by providing the 'event-name' to the stop() method call. In this case, it's not necessary to store the event in a variable:

profiler.start('event name');
// ...
profiler.stop('event name');  

Note that the profiler variable won't be present when either Profiling is not enabled, or when Javascript events are not enabled. So if you want to write code that works in either scenario, you should do a typeof check:

if(typeof profiler != "undefined") {
  var event = profiler.start('event name');
// ...
if(typeof profiler != "undefined") {

ProfilerPro sends a batch of recorded events to the server when the document is fully loaded (window.load event). However, if you don't have tracking of Javascript ready and/or load events enabled, then this may not happen automatically. In that case, you'll want to call the send() method, which will immediately send any recorded events to the server.


If you DO have tracking of ready/load events enabled, then ProfilerPro will take care of sending them to the server for you automatically.

ProfilerPro automatically inserts the necessary <script> tags into your markup to make the "profiler" variable present. If for some reason, that's not working, you can insert it manually in your markup by placing the following immediately after your opening <head> tag in your markup:

<head><?php echo $profiler->js(); ?>

Fine print

Support and upgrades

The ProDevTools set of modules is a paid service provided by ProcessWire/Ryan Cramer Design, LLC with full support and upgrades provided for a period of one year from date of purchase. This period can optionally be renewed every year. It is not necessary to renew in order to continue using the modules. It is only necessary to renew if you want to continue the support and upgrades period.

Support is provided by the ProDevTools support board (requires login). When logged in with the account you purchased ProDevTools under, you will see a "ProDevTools Support" board in the "VIP Support" section. If you have difficulty accessing support while your service is still active, please send a PM to "Ryan" .

We encourage you to regularly check the support board for upgrades, as new features, fixes and optimizations are posted as they become available.

Terms and conditions

The ProDevTools modules are a commercial service and tools limited to usage by the purchaser. This includes ProfilerPro, API Explorer and any other modules added to the set after release. You may not copy or distribute the ProDevTools modules files, except on site(s) you have personally developed. Or for the Agency edition, this instead applies to sites your company has developed.

This service/software includes 1-year of support through the ProcessWire ProDevTools support board and/or email.

In no event shall Ryan Cramer Design, LLC or ProcessWire be liable for any special, indirect, consequential, exemplary, or incidental damages whatsoever, including, without limitation, damage for loss of business profits, business interruption, loss of business information, loss of goodwill, or other pecuniary loss whether based in contract, tort, negligence, strict liability, or otherwise, arising out of the use or inability to use ProcessWire ProfilerPro, even if Ryan Cramer Design, LLC / ProcessWire has been advised of the possibility of such damages.

The ProDevTools modules are provided "as-is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or correction. If within 7 days of purchase, you may request a full refund.

We are committed to making sure the ProDevTools modules work well for you, so if you run into any trouble with them, please visit the ProDevTools support board or contact us.

ProcessWire ProDevTools, ProfilerPro and API Explorer are Copyright 2016 by Ryan Cramer Design, LLC.


Pageviews tab

Below is the same Pageviews tab, after clicking the "TOTAL" column to sort by total time consumed by each URL:

Files tab

$pages tab

Hooks tab

MyPHP tab

In this screenshot, we've setup ProfilerPro to profile our site search engine.

JS tab

Config tab

More about Profiler Pro

  • Blog post introducing ProfilerPro
    In this blog post we walk you through more details on using ProfilerPro and specifically how we are using it on this site (