PHP Framework Benchmarks 2026
Each test measured average requests per second using a minimal application route, sufficient to exercise each framework's full bootstrap and routing pipeline with application logic held constant across all tests.
Fig. 1 - Average requests per second. PHP frameworks only. PHP 8.5, debug off, live environment.
| Framework | Avg. Req / Second | Relative to Laravel 12 |
|---|---|---|
| Laravel 12 | 460 | baseline |
| Symfony 8 | 1,000 | 2.2x |
| CodeIgniter 4 | 1,170 | 2.5x |
| Yii 2 | 1,637 | 3.6x |
| CakePHP 5 | 1,775 | 3.9x |
| Trongate v1 | 4,800 | 10.4x |
| Trongate v2 | 13,965 | 30.4x |
Trongate v2 recorded 13,965 requests per second, approximately 30 times the throughput of Laravel 12 and nearly three times that of Trongate v1. The nearest PHP competitor, CakePHP 5, recorded 1,775 RPS - a factor of roughly 7.9 behind.
The gaps between the mainstream frameworks are also significant. Laravel at 460, Symfony at 1,000, CodeIgniter at 1,170: each step reflects the overhead cost of different architectural choices. The same factors that separate those frameworks from one another separate all of them, collectively, from Trongate v2.
Why Benchmark Results Matter
A common argument in parts of the PHP community holds that raw throughput benchmarks are academic exercises with little bearing on production applications. The argument is more sophisticated than it might first appear, and it deserves a fair hearing before being challenged.
The case against benchmarks rests on several points. Synthetic tests measure minimal routes, not real applications with authentication, queuing, and complex database interactions. Real-world slowness typically originates in poor indexing, N+1 query problems, or slow external APIs rather than the framework core. Network latency and browser rendering usually dwarf server-side processing time. And mature frameworks offset speed disadvantages through developer productivity, ecosystem depth, and built-in tools such as route caching and queue workers.
These points are not wrong. For applications with modest traffic and straightforward data models, framework overhead is rarely the binding constraint. A developer who ships features quickly on a slower framework may produce a better product than one who optimises infrastructure at the expense of delivery.
Where the argument breaks down is in what it leaves unexamined.
Overhead is Additive, Not Separate
Framework overhead does not compete with database latency. It compounds it. Every database query, external API call, and authentication check the application performs happens on top of whatever the framework has already consumed. The question is not whether database queries are slower than framework bootstrap - they usually are. The question is whether paying both costs is acceptable when one is largely avoidable.
Overhead Defines the Margin for Imperfect Code
Laravel 12 consumes approximately 15,312 RPS of the 15,772 available just operating its own internals, leaving 460 RPS for application code. Trongate v2 consumes 1,807, leaving 13,965. When a developer introduces an N+1 query problem or an unoptimised loop, the framework with 13,965 RPS of headroom absorbs that cost very differently from the one with 460. The argument that real-world bottlenecks come from application code, not the framework, is precisely the argument for choosing a framework that leaves as much capacity as possible for that application code to consume.
Scale and Latency
At low traffic volumes, framework overhead is largely invisible. At scale, it becomes a fixed infrastructure cost that compounds with every additional server required. For financial dashboards, real-time systems, auction platforms, and high-frequency APIs, it carries functional significance that no amount of ecosystem richness compensates for.
Benchmarks do not matter equally for every project. They matter a great deal for some, and less for others. What they always provide is a precise measurement of what a framework costs before application code runs. That figure is worth knowing.
A Note on Phalcon
Any treatment of PHP framework performance must address Phalcon, which has held the top position in throughput benchmarks for much of the past decade. The comparison requires context, because Phalcon is not a PHP framework in the conventional sense.
Phalcon is a PHP extension written in C, compiled to native machine code and loaded into the PHP runtime as a binary module. Its framework internals execute as pre-compiled C code, not interpreted PHP. This places it in a different architectural category from every other framework in these tests.
The practical consequences are significant. Phalcon requires server-level extension installation, cannot run on most shared hosting environments, and must be recompiled following PHP version upgrades. Its ecosystem and community are substantially smaller than those of mainstream PHP frameworks. These are not arguments against its quality; they are the context in which its benchmark position should be understood.
With that established, the results are as follows.
Fig. 2 - Same test conditions, Phalcon 5 included. PHP 8.5, debug off, live environment.
| Framework | Avg. Req / Second | Type |
|---|---|---|
| Phalcon 5 | 13,689 | C extension |
| Trongate v2 | 13,965 | native PHP |
Trongate v2 recorded 13,965 requests per second against Phalcon 5's 13,689 - a margin of 276 RPS, or roughly 2%. The difference is narrow and could plausibly reverse under different hardware conditions. What it does establish is that a framework written entirely in PHP, with no compiled extensions and no special runtime requirements, is capable of matching a C-compiled extension that has held benchmark records for years.
It also suggests that the performance ceiling for native PHP is considerably higher than mainstream framework results imply.
Comparison Against Raw PHP
A baseline test was run using a minimal PHP file with no routing, no MVC, and no framework:
<?php
echo 'hello world';
?>
Fig. 3 - Same test conditions, unframed PHP baseline included. PHP 8.5, debug off, live environment.
The baseline recorded 15,772 requests per second. Trongate v2 recorded 13,965. The difference of 1,807 RPS is the total measurable overhead of Trongate v2's complete stack: session initialisation, configuration loading, URL parsing, routing, autoloading, module instantiation, and controller dispatch. Trongate v2 delivers 88.5% of the throughput of a single, bare PHP file.
The table below shows the overhead cost for each framework - the processing capacity consumed before any application code runs.
| Framework | Avg. Req / Second | % of Raw PHP | Overhead (RPS) |
|---|---|---|---|
| Raw PHP | 15,772 | 100% | - |
| Trongate v2 | 13,965 | 88.5% | 1,807 |
| Trongate v1 | 4,800 | 30.4% | 10,972 |
| CakePHP 5 | 1,775 | 11.3% | 13,997 |
| Yii 2 | 1,637 | 10.4% | 14,135 |
| CodeIgniter 4 | 1,170 | 7.4% | 14,602 |
| Symfony 8 | 1,000 | 6.3% | 14,772 |
| Laravel 12 | 460 | 2.9% | 15,312 |
Laravel 12 consumes 15,312 of the available 15,772 RPS operating its own internals. Trongate v2 consumes 1,807. Every other framework tested sits between those two figures, but each consumes more than six times the overhead of Trongate v2 before the first line of application code runs.
Raw PHP without a framework provides no routing, no input handling, no security primitives, and no maintainable structure. Its value here is as a fixed reference point that expresses framework overhead as an absolute figure rather than a relative one.
How Trongate v2 Achieves This
The performance gap is not the result of a single optimisation. It is the compounded effect of several architectural decisions, each removing a category of overhead that other frameworks carry on every request.
Linear Bootstrap Sequence
Trongate's startup sequence is a fixed series of require_once
calls with no dynamic resolution. There is no service container to
construct, no provider registration phase, and no deferred binding
resolution. Frameworks such as Laravel construct a full application
container and boot a collection of service providers on every request,
regardless of which services that request actually requires.
Custom Two-Path Autoloader
Rather than using Composer's PSR-4 autoloader, which traverses a
namespace-to-directory map and may check multiple candidate paths,
Trongate registers an spl_autoload_register callback that
checks exactly two known filesystem locations and returns. For a
framework with a predictable, convention-driven module structure, this
reduces autoloading to a near-constant-time operation.
Lazy Module Loading via __get()
The Trongate base class uses PHP's __get()
magic method to instantiate modules only when they are accessed. There
is no constructor injection, no dependency graph computed at startup,
and no wiring of services the current request does not use. The
Model class applies the same pattern to database
connections.
Direct Controller Dispatch
The routing layer constructs a filesystem path directly from URL
segments and issues a single require_once call. There are
no intermediate routing abstractions, no route collection to compile,
and no reflection-based method resolution. OPcache handles repeated
inclusion of known files with negligible overhead.
Opt-In Interceptors
Trongate has no default middleware pipeline. Its interceptor mechanism is array-driven and executes only when explicitly configured. Requests to routes with no interceptors defined incur a single array check. By contrast, Laravel and Symfony route every request through a middleware stack, including global middleware that runs regardless of the route being served.
Compounding Overhead Reduction
Each of the above decisions eliminates a distinct category of per-request overhead. In combination, no container boot, no PSR-4 traversal, no upfront dependency resolution, and no mandatory middleware execution, the reductions compound. The benchmark results are a measurement of that compounding effect under controlled conditions.
Conclusion
The most striking result in these benchmarks is not the gap between Trongate v2 and Laravel. It is the comparison with raw PHP. A framework that delivers 88.5% of the throughput of a bare PHP file - while providing routing, MVC architecture, session handling, and a full module system - demonstrates something the mainstream frameworks have not: that high framework overhead is a design decision, not an engineering necessity.
The mainstream frameworks are slow because of deliberate choices: service containers, PSR-4 autoloading, mandatory middleware pipelines, and deep dependency injection. Those choices delivered real gains in developer experience and ecosystem richness. They also made those frameworks slow, and that slowness has largely been accepted rather than questioned.
These benchmarks give developers and business owners a concrete basis for questioning it. A productive, full-featured PHP framework can run at 13,965 requests per second. That figure reframes the conversation. The ceiling for native PHP, when a framework is built to respect it, is considerably higher than the industry has come to expect.
DC (written by David Connelly but with a little help from Claude AI)