PHPackages                             sandstorm/plumber - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Debugging &amp; Profiling](/categories/debugging)
4. /
5. sandstorm/plumber

ActiveNeos-flow-package[Debugging &amp; Profiling](/categories/debugging)

sandstorm/plumber
=================

Profiling Toolkit for Neos Flow and Neos

5.1.0(6mo ago)384.9k9[1 issues](https://github.com/sandstorm/Plumber/issues)GPL-3.0+JavaScript

Since Oct 8Pushed 3mo ago13 watchersCompare

[ Source](https://github.com/sandstorm/Plumber)[ Packagist](https://packagist.org/packages/sandstorm/plumber)[ RSS](/packages/sandstorm-plumber/feed)WikiDiscussions 5.0 Synced 1w ago

READMEChangelog (8)Dependencies (1)Versions (19)Used By (0)

Plumber - Profiling Neos Flow
=============================

[](#plumber---profiling-neos-flow)

Versioning Scheme
-----------------

[](#versioning-scheme)

Package VersionNeos / Flow VersionReleased?SupportedRemarks1.x-3.x☑️⛔️ not maintained anymorewas still having Plumber and PhpProfiler separated4.0.x8.3☑️☑️Use this for Neos or Flow Projects up to Neos 8.34.1.x8.4☑️☑️Neos 8.45.0.x9.0☑️☑️Neos 9.0 and up\-- Measuring the flow of your application --

Plumber is a profiling and tracing GUI with the following features:

- **list** all profiling runs in an overview
- show a **graphical timeline** for a single profiling run
- **filter** the graphical timeline
- show the **xhprof** analyzer for a single profiling run
- **compare** two profiling runs with the timeline
- **tag** your profiling runs
- show **aggregated statistics** in the overview

It relies on PhpProfiler for gathering the needed information.

Installation
------------

[](#installation)

Warning: Do not install Plumber on production websites. If you do, make sure to disallow access to the profiler URLs.

To install, just use composer:

```
composer require --dev sandstorm/plumber
```

The system will automatically install PhpProfiler and use XHProf if it is installed.

### Installing XHProf / Tideways on mac

[](#installing-xhprof--tideways-on-mac)

XHProf is not supported anymore, but the Tideways data format is still 100% compatible - and the Tideways PHP Extension is still 100% open source

```
# for PHP 8.1
brew install kabel/pecl/php@8.1-tideways-xhprof

# for older versions
brew install  tideways/homebrew-profiler/php71-tideways --env=std
echo "tideways.auto_prepend_library=0" >> /usr/local/etc/php/7.1/conf.d/ext-tideways.ini
```

PhpProfiler -- Profiling Neos Flow Applications
===============================================

[](#phpprofiler----profiling-neos-flow-applications)

\-- Measuring the flow of your application --

PhpProfiler is a profiling and tracing tool that measures time spent in various parts of your application flow and can leverage XHProf to profile applications.

It stores data in a format understood by Plumber and can also store to the databases used by XHProf.io () and XHGui ().

Installation
------------

[](#installation-1)

To install, just use composer:

```
composer require --dev sandstorm/phpprofiler ^3.0.0
```

The system will automatically install PhpProfiler and use XHProf if it is installed.

Configuration
-------------

[](#configuration)

This is the default configuration:

```
Sandstorm:
  Plumber:
    profilePath: '%FLOW_PATH_DATA%Logs/Profiles'

    # xhprof.io settings (see http://xhprof.io/)
    'xhprof.io':
      enable: false
      dsn: 'mysql:dbname=xhprofio;host=localhost;charset=utf8'
      username: ''
      password: ''

    # preinheimer-xhgui settings (see https://github.com/preinheimer/xhgui)
    'xhgui':
      enable: false
      host: 'mongodb://localhost:27017'
      dbname: 'xhprof'

```

To enable the XHProf.io and XHGui backends adjust the configuration as needed, but keep in mind that any needed setup (e.g. databasae creation) needs to be done as described in the respective documentation.

### Limiting Profiling Run Probability

[](#limiting-profiling-run-probability)

Using the environment variable `PHPPROFILER_SAMPLINGRATE` the probability of runs being profiled can be changed. If the variable is not set, every run will be profiled. If a float between 0 and 1 is given, that represents a probability between 0% and 100% for every run to trigger profiling.

If limiting the probability to a low enough value, it is feasible to leave PhpProfiler running on production instances.

Profiling Custom Code
---------------------

[](#profiling-custom-code)

PhpProfiler collects regular XHProf data and some data specific to TYPO3 Flow, Neos and CMS.

To collect profiling information on critical parts of a custom application, various options exist.

### Profiling method calls using an Aspect (NEW!)

[](#profiling-method-calls-using-an-aspect-new)

You can use the `Sandstorm\Plumber\Core\Annotations\Profile` annotation on a method in order to profile it:

```
class MyClass {

	/**
	 * @Sandstorm\Plumber\Core\Annotations\Profile
	 */
	public function myMethod() {
	}
}
```

### Adding custom timers

[](#adding-custom-timers)

When hunting for performance bottlenecks, it often makes sense to add custom timers throughout your application. Doing so is quite easy, as the following example demonstrates:

```
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->startTimer('My Timer');
// run some code
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->stopTimer('My Timer');
```

If the timer name contains a colon (`:`), related timers are grouped together in the User Interface:

```
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->startTimer('Security: Authentication');
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->stopTimer('Security: Authentication');

\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->startTimer('Security: Authorization');
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->stopTimer('Security: Authorization');
```

It's not a problem if multiple timers are active at the same time; even the same timer can be active multiple times at the same time. The following example is perfectly valid:

```
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->startTimer('t1');
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->startTimer('t1');
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->stopTimer('t1');
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->stopTimer('t1');
```

Furthermore, the `startTimer` allows a second `array` argument containing additional information which is shown in the UI.

### Setting Options

[](#setting-options)

Furthermore, you can set meta-information on the current run (which is called `options` currently):

```
\Sandstorm\Plumber\Core\Profiler::getInstance()->getRun()->setOption('context', 'DEV');
```

Viewing the results
-------------------

[](#viewing-the-results)

For the Plumber UI install the Plumber package as described in it's manual.

For XHProf.ui and XHGui follow the instructions given on the project websites.

Credits
-------

[](#credits)

Originally developed by Sebastian Kurfürst, Sandstorm Media UG (haftungsbeschränkt)

Code from the XHProf.io and XHGui projects is included for storing the data.

License
-------

[](#license)

All the code is licensed under the GPL license.

Configuration
-------------

[](#configuration-1)

Some settings are available in Plumber and PhpProfiler as well as the TYPO3 CMS extension, none of which are needed for basic operation. Feel free to investigate them if you feel like it.

Usage
-----

[](#usage)

Just use your web application as normal. To browse profiling reports, go to `http://yourhost/profiler/`.

For each run, the profiler collects the following data:

- meta-information for the current run (like: the context the request was invoked in, the controller being used)
- timers which can be started and stopped, measuring the details of the application flow.
- the full XHProf profile, containing the (almost) complete call-graph of the run. This is only enabled if XHProf is installed.

### Overview Page

[](#overview-page)

[![Overview](https://camo.githubusercontent.com/729993c9ad4e1f903aac4f7d3912d30b1c5f9bcb4f78462cfa45599d714a1be7/687474703a2f2f73616e6473746f726d2e6769746875622e696f2f506c756d6265722f446f63756d656e746174696f6e2f4f76657276696577506167652e6a7067)](https://camo.githubusercontent.com/729993c9ad4e1f903aac4f7d3912d30b1c5f9bcb4f78462cfa45599d714a1be7/687474703a2f2f73616e6473746f726d2e6769746875622e696f2f506c756d6265722f446f63756d656e746174696f6e2f4f76657276696577506167652e6a7067)

The overview page is the main entry point to the profiler. It shows the different profiling runs. For each profiling run, it can display overview information like the number of created objects or the memory consumption. Each of the columns of the table is called a *dimension*.

On top, the bar charts show how the values in a given dimension are distributed, and allow you to filter the different dimensions to the wanted values.

You can easily create your own dimensions; how to do that is explained later.

### Timeline Page

[](#timeline-page)

The timeline page gives a visual overview of a request, showing the timers of the request, and how memory consumption changed.

[![Timeline](https://camo.githubusercontent.com/9ff8546cdae622dd478e85290adf60ecc3f223b6dabeabf30ef142c294f4a0a0/687474703a2f2f73616e6473746f726d2e6769746875622e696f2f506c756d6265722f446f63756d656e746174696f6e2f54696d656c696e65506167652e706e67)](https://camo.githubusercontent.com/9ff8546cdae622dd478e85290adf60ecc3f223b6dabeabf30ef142c294f4a0a0/687474703a2f2f73616e6473746f726d2e6769746875622e696f2f506c756d6265722f446f63756d656e746174696f6e2f54696d656c696e65506167652e706e67)

### XHProf Page

[](#xhprof-page)

You can also drill down to the XHProf page, showing the detailed statistics of the run.

Configuring Custom Dimensions
-----------------------------

[](#configuring-custom-dimensions)

The available dimensions are configured inside the `Settings.yaml` and that's also how you can add new dimensions.

Let's check how the default dimensions work:

```
Sandstorm:
  Plumber:
    calculations:
      methodCallsOnObject:
        label: 'No. of Method Calls'
        type: regexSum
        regex: '#==>(.*)::.*#'
      totalRuntime:
        label: 'Runtime (ms)'
        type: timerSum
        timerName: 'Profiling Run'
      totalMemory:
        label: 'Memory (kb)'
        type: maxMemory
```

It defines three dimensions, and gives each of them a label. Each dimension has a `type` which specifies how the data inside this dimension is aggregated.

We support the following types:

### maxMemory

[](#maxmemory)

**Parameters:** None

Output the maximum memory which has been used in kilobytes.

### totalRuntime

[](#totalruntime)

**Parameters:** `timerName`

This one sums up the total runtime in milliseconds of a timer specified by `timerName`.

### regexSum

[](#regexsum)

**Parameters:** `regex`

This is the most versatile counter. **It needs XHProf to be installed**, else it does not work.

It counts the number of method invocations in an XHProf trace. To know how the `regex`parameter works, we need to check how an XHProf trace is built:

An XHProf trace is a big array with elements like the following:

```
	'Sandstorm\Plumber\Core\Domain\Model\ProfilingRun::startTimer==>microtime' (76) => array(2)
	   'ct' (2) => integer 10
	   'wt' (2) => integer 9
```

This means: "From inside the method `startTime` in `ProfilingRun` the function `microtime` has been called 10 times. All these calls to microtime together needed 9 milliseconds."

I'm currently not sure about the time scale, whether it's micro- or milliseconds...

Now, the `regexSum` loops over such a trace, and if the regex matches the array key, it counts the number of calls together.

As an example, let's demonstrate that with some regexes:

```
#==>.*__construct#              Matches all constructor invocations
#==>.*TextNode::__construct#    Matches all constructor invocations of classes which end with TextNode

#.*#                            Matches all method calls
#.*==>Doctrine\\Common.*::__construct#'
                                Matches all object creations inside the Doctrine\Common package

```

Furthermore, the regex might contain exactly one submatch pattern. In this case, a popover is displayed with the top 10 invocations grouped by the regex. Example:

```
#==>(.*)::__construct#                Matches all constructor invocations, displaying a Top 10 list of constructor invocations
#==>TYPO3\\Fluid\\(.*)::__construct#  Matches constructor invocations in Fluid, displaying a Top 10 list of constructor invocations inside the fluid package

```

### regex

[](#regex)

**Paramters:**

- `regex`: '...' (see `regexSum`)
- `metric`: `time|calls|memory`
- `subtype`: `sum|average`

### Your custom type

[](#your-custom-type)

Custom types are currently not possible.

The calculation happens inside `Sandstorm\Plumber\Service\CalculationService`, if you want to extend it. Make sure to submit a pull request then :-).

Profiling Custom Code
---------------------

[](#profiling-custom-code-1)

The PhpProfiler documentation has instructions on how to profile custom code.

Credits
-------

[](#credits-1)

Developed by Sebastian Kurfürst, Sandstorm Media GmbH. Pull requests by various authors.

License
-------

[](#license-1)

All the code is licensed under the GPL license.

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance74

Regular maintenance activity

Popularity34

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity72

Established project with proven stability

 Bus Factor1

Top contributor holds 92% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~286 days

Recently: every ~40 days

Total

18

Last Release

94d ago

Major Versions

1.1.0 → 2.0.02014-02-06

2.1.0 → 3.0.02017-12-27

3.1.0 → 4.0.02025-09-04

4.1.0 → 5.0.02025-09-04

4.0.x-dev → 5.1.02025-11-03

### Community

Maintainers

![](https://www.gravatar.com/avatar/2ced0d63cfdae881c32128c7f66451a013d3e24d9eed210d6a846b6d8e95fa3b?d=identicon)[sandstorm](/maintainers/sandstorm)

---

Top Contributors

[![skurfuerst](https://avatars.githubusercontent.com/u/190777?v=4)](https://github.com/skurfuerst "skurfuerst (297 commits)")[![kdambekalns](https://avatars.githubusercontent.com/u/95873?v=4)](https://github.com/kdambekalns "kdambekalns (21 commits)")[![dfeyer](https://avatars.githubusercontent.com/u/221173?v=4)](https://github.com/dfeyer "dfeyer (2 commits)")[![afoeder](https://avatars.githubusercontent.com/u/1125168?v=4)](https://github.com/afoeder "afoeder (1 commits)")[![apocalip](https://avatars.githubusercontent.com/u/189795?v=4)](https://github.com/apocalip "apocalip (1 commits)")[![farconada](https://avatars.githubusercontent.com/u/469221?v=4)](https://github.com/farconada "farconada (1 commits)")

---

Tags

profilerdebuggingprofilingbenchmarkflowNeosxhprofNeos CMSNeos Flow

### Embed Badge

![Health badge](/badges/sandstorm-plumber/health.svg)

```
[![Health](https://phpackages.com/badges/sandstorm-plumber/health.svg)](https://phpackages.com/packages/sandstorm-plumber)
```

###  Alternatives

[laracraft-tech/laravel-xhprof

Easy XHProf setup to profile your laravel application!

235321.4k](/packages/laracraft-tech-laravel-xhprof)[bavix/laravel-xhprof

Quick profiling of your code for Laravel

22156.6k](/packages/bavix-laravel-xhprof)[upscale/swoole-blackfire

Blackfire profiler integration for Swoole web-server

22114.0k8](/packages/upscale-swoole-blackfire)[shel/nodetypes-analyzer

Graphical analysis &amp; visualizer for the Neos CMS nodetypes as backend module

2160.6k](/packages/shel-nodetypes-analyzer)[koriym/xdebug-mcp

Universal PHP Xdebug MCP Server with AI-optimized debugging support

4011.6k1](/packages/koriym-xdebug-mcp)[staabm/xhprof.io

GUI to analyze the profiling data collected using XHProf - A Hierarchical Profiler for PHP.

424.4k](/packages/staabm-xhprofio)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
