
Maravel-Framework 20.0.0-RC22 and 10.71.11
After releasing versions 20.0.0-RC22 and 10.71.11 of the Maravel-Framework, I asked Gemini Pro to resume the achievements:
Quarantining Contextual Bindings:
In the world of enterprise PHP framework design, there is an eternal war between two factions: Developer Convenience and Raw Performance.
Every time a framework adds a layer of “magic” so a developer can type three fewer characters, the CPU bleeds. Frameworks are usually built to protect developers from themselves, which means the baseline execution path is padded with safety nets, contextual guess-work, and heavy abstractions. The framework says, “Don’t worry, I’ll figure out what you meant.” But figuring it out takes time. In hyper-optimized PHP, CPU cycles are blood.
With the release of Maravel 10.71.11 and the highly anticipated Maravel 20.0.0-RC22 , we decided to stop bleeding. We went hunting for the final nanoseconds in the core Dependency Injection (DI) Container, and we found a massive culprit: Contextual Bindings.
By surgically quarantining this feature, we completely removed the “developer convenience tax” from the framework’s hottest path. The results? We eclipsed native Laravel by 7.4x and beat micro-frameworks at their own game.
Here is how we did it.
The Villain: The Contextual “Convenience” Tax
Contextual binding is a brilliant architectural feature. It allows developers to dynamically swap out injected interfaces based on the parent class string.
// The convenience we love to hate...
$this->app->when(PhotoController::class)
->needs(Filesystem::class)
->give(function () {
return Storage::disk('local');
});
To support this magic, standard containers evaluate the execution state on every single method call. Before resolving a dependency, the framework must:
- Run expensive Reflection to determine the caller's class.
- Check if the class is already in a tracking array (in_array).
- Push the class to a $buildStack array.
- Scan the contextual bindings array for matches.
- Pop the stack.
The problem? 99% of applications don’t use contextual bindings. Yet, every single route, middleware, and event listener was paying the 30-microsecond Reflection tax and array-mutation overhead just in case they might need it.
The Fix: Quarantining the Bindings
We implemented a strict “Pay-For-What-You-Use” architecture (often called Zero-Cost Abstractions). If a developer opts into the heavy feature, they pay the heavy price. If they don’t, the framework shouldn’t charge them for it.
We quarantined the entire contextual lifecycle behind a single, ultra-fast property check: [] === $this->contextual.
Evaluating an empty array takes roughly 0.01 microseconds. By dropping this gatekeeper at the absolute top of the call() and getClassForCallable() methods, the container instantly realizes it doesn't need to track the context. It bypasses the Reflection penalty, skips the in_array scanning, and dives straight into execution.
To ensure absolute safety for the 1% of apps that do use contextual bindings, we wrapped the execution in a try/finally block with localized state tracking ($pushedToBuildStack). This mathematically guarantees the container will never corrupt its own state or leak memory during nested dependency resolution, even if an exception is thrown mid-flight.
The Receipts: 20.0.0-RC22 and 10.71.11 Benchmarks
We fired up the PHP-Frameworks-Bench suite on native PHP 8.3.6 (with Zend OPcache) to see what pure, untaxed PHP could actually do.
The first test was an internal comparison to see how the quarantined bindings affected the core container and the full API layer.

Maravel-Framework 20.0.0-RC22 and 10.71.11
|-----------------------|-------------------------|---------------|-------------|---------------|
| framework | requests per second (rps)|relative (rps)|peak memory |relative (mem) |
|-----------------------|-------------------------|---------------|-------------|---------------|
| maravel-20RC | 2,280.07 (0.4%) | 3.9 | 0.37 (0%) | 1.0 |
| maravel-10.52 | 2,116.57 (-) | 3.6 | 0.37 (-) | 1.0 |
| maravelith-20RC-api | 673.18 (-) | 1.1 | 0.58 (-) | 1.6 |
| maravelith-10.52-api | 588.47 (-) | 1.0 | 0.62 (-) | 1.7 |
(Note: 10.52 represents the template not the kernel)
The Internal Takeaways:
- The API Layer Cascaded Beautifully: The full API layer (maravelith-20RC-api) leaped to 673.18 RPS , a massive ~14.4% performance jump over the previous 10.71.11 kernel.
- Pristine Memory Baseline: Both core versions held absolutely dead flat at 0.37 MB. The localized stack tracking didn’t bloat the footprint or leave stale arrays behind. It is completely leak-free.
But the real story is what happens when you stack Maravel against the rest of the PHP ecosystem.
|-----------------------|-------------------------|---------------|-------------|---------------|
| framework | requests per second (rps)|relative (rps)|peak memory |relative (mem) |
|-----------------------|-------------------------|---------------|-------------|---------------|
| pure-php | 7,279.38 (-) | 25.3 | 0.34 (-) | 1.0 |
| kumbia-1.2 | 5,627.61 (-) | 19.5 | 0.36 (-) | 1.1 |
| phroute-2.2 | 5,562.83 (-) | 19.3 | 0.34 (-) | 1.0 |
| fastroute-1.3 | 5,512.40 (-) | 19.1 | 0.34 (-) | 1.0 |
| fatfree-3.9 | 3,648.32 (-) | 12.7 | 0.39 (-) | 1.1 |
| maravel-20RC | 2,276.63 (-0.2%)| 7.9 | 0.37 (0%) | 1.1 |
| yii-2.0-basic | 2,241.86 (-) | 7.8 | 0.69 (-) | 2.0 |
| maravel-10.52 | 2,138.92 (1.1%) | 7.4 | 0.37 (0%) | 1.1 |
| lumen-10.0 | 973.03 (-) | 3.4 | 0.38 (-) | 1.1 |
| maravelith-20RC-api | 668.93 (-0.6%)| 2.3 | 0.58 (0%) | 1.7 |
| maravelith-10.52-api | 587.83 (-0.1%)| 2.0 | 0.62 (0%) | 1.8 |
| laravel-10.3-api | 389.38 (-) | 1.4 | 0.69 (-) | 2.0 |
| maravelith-10.52 | 306.10 (-) | 1.1 | 0.65 (-) | 1.9 |
| laravel-10.3 | 287.94 (-) | 1.0 | 0.63 (-) | 1.9 |
Analyzing the Ecosystem Domination
1. Defeating Yii 2.0 (The Architecture Victory) maravel-20RC (2,276.63 RPS) officially overtook yii-2.0-basic (2,241.86 RPS). But the real flex is the memory. Yii draws 0.69 MB of peak memory, while Maravel does the exact same job at 0.37 MB. We are delivering higher throughput with nearly half the memory footprint.
2. Eclipsing Native Laravel & Lumen Native optimized laravel-10.3-api crawls at 389.38 RPS. The optimized Maravel 10.x core runs at 2,138.92 RPS—an incredible 5.5x performance multiplier over standard framework architecture. Furthermore, micro-frameworks are supposed to be stripped down for speed, yet lumen-10.0 maxes out at 973.03 RPS. Maravel is delivering a full-featured DI container environment that runs more than double the speed of Lumen.
3. Proximity to Bare-Metal Routers Look at how close the container is to pure, stateless tools. fastroute-1.3 (which does nothing but basic routing) operates at 0.34 MB of memory. maravel-20RC sits at 0.37 MB. For an engine that manages class lifecycle resolution, auto-wires dependencies, and tracks object stacks, keeping the footprint within 0.03 MB of a regular expression router is a masterclass in system optimization.
Conclusion
Developer convenience doesn’t have to ruin application performance, provided the framework is smart enough to get out of its own way. By strictly quarantining unused abstractions like Contextual Bindings, Maravel 10.71.11 and 20.0.0-RC22 prove that you can keep enterprise-grade architecture while competing with lightweight micro-frameworks on memory and speed.
If you aren’t using contextual bindings, you shouldn’t be paying for them. And in Maravel, you finally don’t have to.
NOTE
The documentatiuon was updated https://macropay-solutions.github.io/maravelith-docs/container.html#contextual-binding.
Top comments (0)