PHPackages                             tuupola/server-timing-middleware - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. tuupola/server-timing-middleware

ActiveLibrary[HTTP &amp; Networking](/categories/http)

tuupola/server-timing-middleware
================================

PSR-7 and PSR-15 server timing middleware

0.12.0(4mo ago)20187.3k—8.8%10[2 issues](https://github.com/tuupola/server-timing-middleware/issues)[1 PRs](https://github.com/tuupola/server-timing-middleware/pulls)1MITPHPPHP ^8.1CI passing

Since Mar 8Pushed 4mo ago6 watchersCompare

[ Source](https://github.com/tuupola/server-timing-middleware)[ Packagist](https://packagist.org/packages/tuupola/server-timing-middleware)[ Docs](https://github.com/tuupola/server-timing-middleware)[ RSS](/packages/tuupola-server-timing-middleware/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (13)Versions (18)Used By (1)

PSR-7 and PSR-15 Server Timing Middleware
=========================================

[](#psr-7-and-psr-15-server-timing-middleware)

[![Latest Version](https://camo.githubusercontent.com/16cdddd76165ec6e8771beb9364acb002c35c1af3a9220c97cbf3a47af1415bb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f747575706f6c612f7365727665722d74696d696e672d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tuupola/server-timing-middleware)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Build Status](https://camo.githubusercontent.com/08d7a2b5e85e8e9494ad64eb7ca8f0cb8c3d650a7b79678cd73b38436230bc83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f747575706f6c612f7365727665722d74696d696e672d6d6964646c65776172652f74657374732e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)](https://github.com/tuupola/server-timing-middleware/actions)[![Coverage](https://camo.githubusercontent.com/583a4aa3efafe35e3c030244fe53e3e02f7e203807d7aef30adccc2cc8473163/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f747575706f6c612f7365727665722d74696d696e672d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/github/tuupola/server-timing-middleware)

This middleware implements the [Server-Timing](http://wicg.github.io/server-timing/) header which can be used for displaying server side timing information on Chrome DevTools.

[![Server Timing](https://camo.githubusercontent.com/a6046fe71ce6401e8edae63f78dafbbac81c8fb85e5f9877284faa7e1a3c2985/68747470733a2f2f617070656c7369696e692e6e65742f696d672f7365727665722d74696d696e672d313430302e706e67)](https://camo.githubusercontent.com/a6046fe71ce6401e8edae63f78dafbbac81c8fb85e5f9877284faa7e1a3c2985/68747470733a2f2f617070656c7369696e692e6e65742f696d672f7365727665722d74696d696e672d313430302e706e67)

Install
-------

[](#install)

Install using [Composer](https://getcomposer.org/):

```
$ composer require tuupola/server-timing-middleware
```

Simple usage
------------

[](#simple-usage)

To get the default timings add the middleware to the pipeline. With [Zend Expressive](https://github.com/zendframework/zend-expressive/) this goes go to the file named `config/pipeline.php`.

```
use Tuupola\Middleware\ServerTimingMiddleware;

$app->pipe(ServerTimingMiddleware::class);
```

[Slim Framework](https://github.com/slimphp/Slim) does not have specific config files. Otherwise adding the middleware is similar with previous.

```
$app->add(new Tuupola\Middleware\ServerTimingMiddleware);
```

You should now see the default timings when doing a request.

1. `Bootstrap` is the time taken from start of the request to execution of the first incoming middleware
2. `Process` is the time taken for server to generate the response and process the middleware stack
3. `Total` is the total time taken

```
$ curl --include http://localhost:8080

HTTP/1.1 200 OK
Server-Timing: Bootstrap;dur=54, Process;dur=2, Total;dur=58

```

Note that `ServerTimingMiddleware` must be added as last middleware. Otherwise timings will be inaccurate.

Changing the defaults
---------------------

[](#changing-the-defaults)

If you are not happy with the above you can change the description by using an optional settings array. To disable any of the defaults set the description to `null`.

```
use Tuupola\Middleware\ServerTimingMiddleware;
use Tuupola\Middleware\ServerTiming\Stopwatch;

$app->add(new ServerTimingMiddleware(
    new Stopwatch,
    [
        "bootstrap" => "Startup",
        "process" => null,
        "total" => "Sum"
    ])
);
```

```
$ curl --include http://localhost:8080

HTTP/1.1 200 OK
Server-Timing: Startup;dur=52, Sum;dur=57

```

Advanced usage
--------------

[](#advanced-usage)

Example below uses [Slim Framework](https://github.com/slimphp/Slim). Note again that `ServerTimingMiddleware` must be added as last middleware. Otherwise timings will be inaccurate.

You can add your own timings by using the `Stopwatch` instance. See example below.

```
require __DIR__ . "/vendor/autoload.php";

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Tuupola\Middleware\ServerTimingMiddleware;
use Tuupola\Middleware\ServerTiming\Stopwatch;

$app = new Slim\App;
$container = $app->getContainer();

$container["stopwatch"] = function ($container) {
    return new Stopwatch;
};

$container["ServerTimingMiddleware"] = function ($container) {
    return new ServerTimingMiddleware($container["stopwatch"]);
};

$container["DummyMiddleware"] = function ($container) {
    return function ($request, $response, $next) {
        usleep(200000);
        return $next($request, $response);
    };
};

$app->add("DummyMiddleware");
$app->add("ServerTimingMiddleware");

$app->get("/test", function (Request $request, Response $response) {
    $this->stopwatch->start("External API");
    usleep(100000);
    $this->stopwatch->stop("External API");

    $this->stopwatch->closure("Magic", function () {
        usleep(50000);
    });

    $this->stopwatch->set("SQL", 34);

    return $response;
});

$app->run();
```

```
$ curl --include http://0.0.0.0:8080/test

HTTP/1.1 200 OK
Server-Timing: Bootstrap;dur=9, externalapi;dur=101;desc="External API", Magic;dur=50, SQL;dur=34, Process;dur=360, Total;dur=369

```

Usage with Doctrine DBAL
------------------------

[](#usage-with-doctrine-dbal)

If you use Doctrine DBAL you can automate SQL query timings by using the provided `QueryTimer`. It implements the DBAL `SQLLogger` interface and can be used as standalone or in a `LoggerChain`. You must use the same `Stopwatch` instance with both `QueryTimer` and `ServerTimingMiddleware` middleware.

```
use Doctrine\DBAL\Logging\EchoSQLLogger;
use Doctrine\DBAL\Logging\LoggerChain;

use Tuupola\Middleware\ServerTiming\QueryTimer;
use Tuupola\Middleware\ServerTiming\Stopwatch;

$logger = new LoggerChain;
$echo = new EchoSQLLogger;
$stopwatch = new Stopwatch;
$timer = new QueryTimer($stopwatch);

$logger->addLogger($echo);
$logger->addLogger($timer);

/* Use your Doctrine DBAL connection here. */
$connection->getConfiguration()->setSQLLogger($logger);
```

Testing
-------

[](#testing)

You can run tests either manually or automatically on every code change. Automatic tests require [entr](http://entrproject.org/) to work.

```
$ make test
```

```
$ brew install entr
$ make watch
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance76

Regular maintenance activity

Popularity47

Moderate usage in the ecosystem

Community22

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 93.5% 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 ~248 days

Recently: every ~466 days

Total

14

Last Release

129d ago

PHP version history (5 changes)0.2.0PHP ^5.5 || ^7.0

0.6.0PHP ^7.1

0.9.0PHP ^7.1|^8.0

0.11.0PHP ^7.2|^8.0

0.12.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/3325405a7d8a43bc40dd0e760a4b7f268fba32a7150cf0327f64f13d1661df0b?d=identicon)[tuupola](/maintainers/tuupola)

---

Top Contributors

[![tuupola](https://avatars.githubusercontent.com/u/21913?v=4)](https://github.com/tuupola "tuupola (101 commits)")[![mbolli](https://avatars.githubusercontent.com/u/722725?v=4)](https://github.com/mbolli "mbolli (2 commits)")[![jyggen](https://avatars.githubusercontent.com/u/264300?v=4)](https://github.com/jyggen "jyggen (1 commits)")[![drewm](https://avatars.githubusercontent.com/u/225402?v=4)](https://github.com/drewm "drewm (1 commits)")[![lex111](https://avatars.githubusercontent.com/u/4408379?v=4)](https://github.com/lex111 "lex111 (1 commits)")[![laurinomme-other](https://avatars.githubusercontent.com/u/23099765?v=4)](https://github.com/laurinomme-other "laurinomme-other (1 commits)")[![esetnik](https://avatars.githubusercontent.com/u/664434?v=4)](https://github.com/esetnik "esetnik (1 commits)")

---

Tags

psr-15psr-7psr-7middlewarepsr-15

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StyleECS

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tuupola-server-timing-middleware/health.svg)

```
[![Health](https://phpackages.com/badges/tuupola-server-timing-middleware/health.svg)](https://phpackages.com/packages/tuupola-server-timing-middleware)
```

###  Alternatives

[tuupola/slim-basic-auth

PSR-7 and PSR-15 HTTP Basic Authentication Middleware

4442.0M26](/packages/tuupola-slim-basic-auth)[mezzio/mezzio

PSR-15 Middleware Microframework

3883.6M97](/packages/mezzio-mezzio)[tuupola/cors-middleware

PSR-7 and PSR-15 CORS middleware

1331.8M24](/packages/tuupola-cors-middleware)[relay/relay

A PSR-15 server request handler.

3302.1M86](/packages/relay-relay)[laminas/laminas-stratigility

PSR-7 middleware foundation for building and dispatching middleware pipelines

586.6M81](/packages/laminas-laminas-stratigility)[hkarlstrom/openapi-validation-middleware

PSR-7 and PSR-15 OpenAPI Validation Middleware

95198.8k1](/packages/hkarlstrom-openapi-validation-middleware)

PHPackages © 2026

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