konradmichalik / typo3-request-profiler
Dev-only TYPO3 frontend request profiler that records SQL queries, N+1 patterns, cache state and timing as compact JSON profiles for AI coding assistants.
Package info
github.com/konradmichalik/typo3-request-profiler
Type:typo3-cms-extension
pkg:composer/konradmichalik/typo3-request-profiler
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
- doctrine/dbal: ^3.9 || ^4.0
- psr/http-message: ^1.0 || ^2.0
- psr/http-server-handler: ^1.0.2
- psr/http-server-middleware: ^1.0.2
- typo3/cms-core: ^13.4 || ^14.0
- typo3/cms-frontend: ^13.4 || ^14.0
Requires (Dev)
- eliashaeussler/version-bumper: ^4.0
- phpunit/phpcov: ^9.0 || ^10.0 || ^11.0 || ^13.0
- phpunit/phpunit: ^10.5 || ^11.0 || ^12.0
- typo3/cms-base-distribution: ^13.4 || ^14.0
- typo3/cms-lowlevel: ^13.4 || ^14.0
- typo3/testing-framework: ^8.2 || ^9.0
This package is auto-updated.
Last update: 2026-06-15 15:13:59 UTC
README
TYPO3 extension typo3_request_profiler
A dev-only TYPO3 frontend request profiler. It instruments live frontend requests and writes one compact JSON profile per request — SQL queries, N+1 patterns, cache state, and timing — to var/log/profiles/{request_id}.json.
Important
This extension is active only in a Development context (Environment::getContext()->isDevelopment()). It registers no middleware and collects no data in production.
The profiler is a thin, standalone collector with no external dependencies. It is inspired by the Symfony Profiler — and by some of the metrics the TYPO3 Admin Panel surfaces — but records them as compact, machine-readable JSON instead of an interactive panel.
Warning
This package is in early development stage and may change significantly in the future. I am working steadily to release a stable version as soon as possible.
What it captures per request:
- Wall-clock and SQL timing, peak memory usage
- Full query count + top slow queries + N+1 duplicate detection
- Cache hit/miss state with disabled reasons
- Optional call-site origin (
Class::method (file:line)) for every flagged query
🔥 Installation
Requirements
- TYPO3 13.4 LTS & 14.0+
- PHP 8.2+
- Doctrine DBAL 3.x or 4.x
Supports
| Version | TYPO3 | PHP |
|---|---|---|
| 0.x | 13-14 | 8.2-8.5 |
Composer
composer require --dev konradmichalik/typo3-request-profiler
⚙️ Configuration
The profiler is controlled entirely via environment variables:
| Variable | Default | Effect |
|---|---|---|
TYPO3_REQUEST_PROFILER |
(on) | Set to 0 to disable profiling for a request/process. |
TYPO3_REQUEST_PROFILER_MIN_MS |
0 |
Only persist requests whose total time exceeds this threshold (ms). |
TYPO3_REQUEST_PROFILER_KEEP |
50 |
Number of most-recent profiles to retain; older files are pruned automatically. |
TYPO3_REQUEST_PROFILER_TRACE |
(off) | Set to 1 to capture the calling Class::method (file:line) for each query (added as origin to slow_queries/duplicate_queries). |
Tip
TYPO3_REQUEST_PROFILER_TRACE=1 uses debug_backtrace per query and is therefore opt-in for performance. No bound parameter values are ever captured — only the call site.
💡 Profile Format
Each request produces one JSON file at var/log/profiles/{request_id}.json:
{
"token": "<RequestId>",
"time": "2026-06-15T10:00:00+00:00",
"method": "GET",
"url": "https://example.ddev.site/",
"status": 200,
"page": { "id": 1, "type": 0 },
"cache": { "hit": false, "cacheable": false, "disabled_reasons": ["&no_cache=1 query parameter was given"] },
"timing": { "total_ms": 142.5 },
"memory": { "peak_mb": 16.1 },
"queries": { "count": 101, "total_ms": 38.2 },
"slow_queries": [
{ "sql": "SELECT * FROM pages WHERE slug = ? ORDER BY slug desc", "ms": 12.4 }
],
"duplicate_queries": [
{ "sql": "SELECT COUNT(*) FROM tt_content WHERE pid = ? AND deleted = ?", "count": 100, "total_ms": 31.4 }
]
}
🧑💻 Contributing
Please have a look at CONTRIBUTING.md.
⭐ License
This project is licensed under GNU General Public License 2.0 (or later).