Stackwatch

A minimalist multi-metric PHP Profiler.

composer require bakame/stackwatch:^0.15.0
Love this package ? Sponsor its development
!

Once a new major version is released, the previous stable release remains supported for six more months with patches and security fixes.

Introduction

Stackwatch is a lightweight profiler for PHP 8.1+. It helps you measure performance with precision—without unnecessary complexity.

Once installed, it will allow you to

Profile any block using closures

$duration = stack_bench(function () {
    // code that will be profiled
})->executionTime;
// $duration is the execution time in nanosecond using hrtime instead of microtime

Segment code with named checkpoints

use Bakame\Stackwatch\Timeline;

$timeline = Timeline::start('start');
// the piece of code to be profiled
$timeline->capture('middle');
// another piece of code
$duration = $timeline->take('end')->metrics->executionTime;
// $duration is expressed in nanoseconds

Use a CLI command to profile your codebase

Let’s say you have the following file /path/to/profiling/code.php:

<?php

declare(strict_types=1);

namespace Foobar\Baz;

use Bakame\Stackwatch\Profile;

use function random_int;
use function usleep;

require 'vendor/autoload.php';

trait TimerTrait {
    #[Profile]
    private function test() : int {
        usleep(100);

        return random_int(1, 100);
    }
}

enum MyEnum
{
    use TimerTrait;

    case Case1;
    case Case2;
}

If you mark your code with the Bakame\Stackwatch\Profile attribute and run the CLI command:

php vendor/bin/stackwatch --path=/path/to/profiling/code.php

It will output the following with no complex setup.

stackwatch v0.15.0 (Ouagadougou) by Ignace Nyamagana Butera and contributors.

Runtime: PHP 8.3.25 OS: Linux Memory Limit: 64M

............................

Target: Foobar\Baz\MyEnum::test; Path: /path/to/profiling/code.php; Iterations: 3; Warmup: 0; Type: Full;

+-------------------------------+------------+------------+------------+------------+------------+------------+--------------+---------------+-----------+-----------+
| Metrics                       | iterations | Min Value  | Max Value  | Range      | Sum        | Average    | Median Value | Variance      | Std Dev   | Coef Var  |
+-------------------------------+------------+------------+------------+------------+------------+------------+--------------+---------------+-----------+-----------+
|CPU Time                       |           3|19.000 µs   |78.000 µs   |59.000 µs   |134.000 µs  |44.667 µs   |37.000 µs     |609.556 μs²    |24.689 µs  |55.2743 %  |
|Execution Time                 |           3|143.500 µs  |192.375 µs  |48.875 µs   |486.625 µs  |162.208 µs  |150.750 µs    |463.774 μs²    |21.535 µs  |13.2764 %  |
|Memory Usage                   |           3|3.292 MB    |3.392 MB    |101.578 KB  |10.076 MB   |3.359 MB    |3.391 MB      |2,287.987 KB²  |47.833 KB  |1.3908 %   |
|Memory Usage Growth            |           3|568.000 B   |568.000 B   |0.000 B     |1.664 KB    |568.000 B   |568.000 B     |0.000 B²       |0.000 B    |0.0000 %   |
|Real Memory Usage              |           3|4.000 MB    |4.000 MB    |0.000 B     |12.000 MB   |4.000 MB    |4.000 MB      |0.000 B²       |0.000 B    |0.0000 %   |
|Real Memory Usage Growth       |           3|0.000 B     |0.000 B     |0.000 B     |0.000 B     |0.000 B     |0.000 B       |0.000 B²       |0.000 B    |0.0000 %   |
|Peak Memory Usage              |           3|3.358 MB    |3.513 MB    |159.164 KB  |10.384 MB   |3.461 MB    |3.513 MB      |5,629.600 KB²  |75.031 KB  |2.1168 %   |
|Peak Memory Usage Growth       |           3|0.000 B     |0.000 B     |0.000 B     |0.000 B     |0.000 B     |0.000 B       |0.000 B²       |0.000 B    |0.0000 %   |
|Real Peak Memory Usage         |           3|4.000 MB    |4.000 MB    |0.000 B     |12.000 MB   |4.000 MB    |4.000 MB      |0.000 B²       |0.000 B    |0.0000 %   |
|Real Peak Memory Usage Growth  |           3|4.000 MB    |4.000 MB    |0.000 B     |12.000 MB   |4.000 MB    |4.000 MB      |0.000 B²       |0.000 B    |0.0000 %   |
+-------------------------------+------------+------------+------------+------------+------------+------------+--------------+---------------+-----------+-----------+

PHPUnit helper traits

A fluent, unit-aware PHPUnit helper for asserting profiler metrics.

use Bakame\Stackwatch\Test\PerformanceAssertions;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class ExampleTest extends TestCase
{
    use PerformanceAssertions;

    #[Test]
    public function it_can_test_callback_performance(): void
    {
        $performance = $this
             ->iterations(5)
             ->warmup(2)
             ->assertPerformance($service->calculateHeavyStuff(...));

        $performance->median()->executionTime()->lessThan(200, 'milliseconds');
        $performance->range()->memoryUsage()->greaterThan(10, 'mb');
    }
}

Motivation

Stackwatch bridges the gap between basic timers and heavy profiling tools like PHPBench, Xdebug or Blackfire. It is perfect for:

  • Isolated performance testing
  • Annotated profiling of large codebases
  • Lightweight integration into dev workflows
Logo