Problem
Without proper caching, Drupal is SLOW, just like many extensible PHP frameworks. Despite the great cache tag feature of Drupal 8, not everything can be fully cached.
One major problem is Drupal's bootstrap is very resource-intensive. Regardless of how much time we put into optimizing it, it can only become slightly faster. The reason for this as i believe is because we're using the wrong approach. Bootstrapping the whole application for every request is just wrong. Things get even worse when one wants to use Drupal as a headless REST API for something like a progressive application with many small simultaneous requests.
Why is this critical
The web is becoming much faster and the content is extremely customized. In many cases caching just wouldn't cut it.
just to name few related technologies: Progressive Apps, HTTP2, IoT, REST, Li-Fi, 5G, etc.
With Drupal headless initiative which makes using Drupal for modern web much easier and semantic versioning which makes it possible to add many new features to core every several months, can Drupal really compete with Walled Garden ? Will 200-300ms for dynamics content acceptable for users and clients? Drupal can be used for sites with heavy traffic and dynamic content, but if we put aside how challenging it's, it can never deliver the same performance as more modern Web solutions written by likes of Node.js
I think this is important enough to become an initiative.
Solution
It's simple, not to bootstrap Drupal every time. Up until a few years ago, there wasn't any reliable solution fast enough worth the effort. But now there are several open-source projects already in production (PHP-PM, PHPFastCGI, Icicle, AppServer.io , etc). And it is fast, we're talking about 10-30ms and few kilobytes of memory usage without any caching or optimization against 100-150ms and megabytes of memory usage (The numbers come from my experiment with ReactPHP HTTP server and a custom Silex application). This is without any optimization, just changing the approach! But when the application bootstraps only once and objects are persistent, a lot of things can be greatly optimized.
Demonstration
I haven't been able to find any benchmarks for Drupal, but for other frameworks the are several :
- https://github.com/Blackshawk/SymfonyReactorBundle
- https://medium.com/laravel-4/eaa550829538
- https://drupal.org/project/drushd
- Benchmarking Codswallop: NodeJS v PHP
- 280 rq/s to 1770 rq/s - Speed up Symfony, Silex and Slim with PHPFastCGI
- Bring High Performance Into Your PHP App (with ReactPHP)
- PHPFastCGI Benchmarks - Symfony, Silex and Slim
More information on the wiki page: https://groups.drupal.org/node/417723
Work already done
There has been several attempts, discussions and experiments so far using different approaches :
- https://drupal.org/project/daemoncli
- https://drupal.org/project/daemon
- https://drupal.org/project/drushd
- https://groups.drupal.org/node/192173
- Drupal8 Adaptor for PHP-PM: https://github.com/php-pm/php-pm-drupal
Roadmap
- Making core compatible with app servers: https://github.com/php-pm/php-pm-drupal/tree/master/patches
- Using one of the available solutions like PHP-PM in core
- Adding new tests for app-server, this also helps contrib module developer to make their modules compatible
Comments
Comment #1
sinasalek commentedReactPHP take a very different approach to PHP's performance problem, it's more memory efficient and can be used in combination with HHVM.
It's i believe how it should be, Drupal as we all know has a very expensive bootstrapping specially when many modules are installed so the performance boost we get from using ReactPHP is amazingly high! it's not comparable to any other solution available right now 1000x - 2000x boost and even more if the application is written in an asynchronous way.
Sine Drupal 8 is service based and using symphony components as core it seems possible and within reach
Also event driven design is not only for ReactPHP, there are other solutions and more will come in the future
It would be great if we could have opinion of some of core developer regarding how difficult this task is and how we can help to make it happen
Comment #2
sinasalek commentedSome efforts have been made in the past, might be useful
https://drupal.org/project/daemoncli
https://drupal.org/project/daemon
https://drupal.org/project/drushd
Comment #3
sinasalek commentedThere are also libraries for supporting push technology (web socks) using reactphp which eliminate the need for nodejs. Since it's already in PHP this support can be added to Drupal out of the box.
https://groups.drupal.org/node/192173
http://socketo.me/
Comment #4
sinasalek commentedA symfony bundle to run symfony under reactphp https://github.com/Blackshawk/SymfonyReactorBundle
Realtime chat using Laravel4 and Reactphp https://medium.com/laravel-4/eaa550829538
Comment #5
sinasalek commentedI created a wiki page : https://groups.drupal.org/node/417723
Comment #8
sinasalek commentedCorrecting the title
This is still the best way to significantly improve Drupal's performance.
New attempt on this https://github.com/php-pm/php-pm-drupal
Comment #9
sinasalek commentedNote that this is not possible without patching the core https://github.com/php-pm/php-pm-drupal/tree/master/patches
Comment #10
sinasalek commentedTargeting against 8.3.x
Comment #11
sinasalek commentedWrong update
Comment #12
sinasalek commentedUpdating the summary
Comment #13
sinasalek commentedComment #14
dawehnerIs there an issue for https://github.com/php-pm/php-pm-drupal/blob/master/patches/kentr-allow-... out there?
Comment #15
sinasalek commentedNot that i know of, so lets ask https://github.com/php-pm/php-pm-drupal/issues/14
Comment #16
sinasalek commentedI added the related issues for patches
Comment #17
sinasalek commentedComment #18
kentr commented@dawehner, @sinasalek I'll add my patch.
Glad to see that support for the PHP-PM integration is growing.
Comment #19
fgmTried it today, got a bunch of problems:
* the second patch in
kentr/stop_using-2505339-24.patchno longer applies on 8.3.x HEAD*
php-pm/React/RequestParseruses non-existentReact\Http\RequestParser, which seems to have been replaced byRequestHeaderParser*
php-pm/httpKernel-adapter/Bridges/HttpKernel::mapRequest()uses non existent methodsgetFiles()andgetPost()onReact\Http\RequestThe two last ones look like depending on an incorrect version of React.
Comment #20
kentr commentedCreated #2829346: Allow repeated calls to DrupalKernel::setSitePath()
Comment #23
Anonymous (not verified) commentedHaving Drupal support ReactPHP will be insane! Both child issues are "basically" done. 8.5 is closing in...can't wait.
Nice, up-to-date, overview: https://www.youtube.com/watch?v=fQxxm4vD8Ok
Also, the second part of this is awesome: https://www.youtube.com/watch?v=VjJBR8YAxoE
Comment #24
andypost2 related issues are not done
- #2613044: Requests are pushed onto the request stack twice, popped once is very close, just needs to explain chosen approach
- second one needs tests #2708827: Allows DrupalKernel::handle to handle more than one requests (rough support for PHP-PM)
Also it's not clear how to handle static vars that still used by core & sessions
Comment #25
dawehnerRIght, we should basically try to identify every place where we have leaking state in our system. It would be great to collect them all. #2760167: Add \Drupal\Core\Messenger\Messenger solves one of those cases ...
Comment #30
andypostPager no longer using globals, added related "polishing" issue
Comment #31
miksha commentedThis would be great. What do you think about using Swoole that is based on C and supposedly is very fast. There is a discussion here:
React PHP vs Swoole PHP
Comment #32
andypost@miksha nowadays reactphp/swoole are mostly the same - php itself manages promises/generators
Comparisons are mostly synthetic and real cases to compare are php-fpm, nginx-unit, roadrunner - personally (today) I prefer reactphp as it foes not need any extensions installed (there's new extension pecl parallel but it needs php compiled with zts)
Comment #33
miksha commented@andypost Thank you. ReactPHP doesn't support coroutines by default but it can be combined with RecoilPHP.
Comment #34
andypostHere goes swoole and WP https://github.com/swoole/library/pull/17
So core could redo its quickstart command
Comment #37
andypostMeantime Laravel started swoole / roadrunner 2 custom web-server https://github.com/laravel/octane
Comment #38
sinasalek commentedThis will have the biggest impact on the future of Drupal as a platform and we already have a solid feature-rich, production-ready, high performance async and multi-core library for it: Swoole
Comment #40
user654 commented.
Comment #41
darvanenMeh. Node is great, but I'd like to see anyone build something as feature-rich as you could in Drupal in less than ten times the time it would take in Drupal.
Use the tool that is right for the job. You want a microservice or a small web application that is *lightning fast*, please use Node, I would and I do. Want a backend application that can handle thousands of user sessions, present a world-class content-editing experience, manage the most granular permissions you can imagine with a few lines of code, automatically build your database, plug in to hundreds of third-party applications with ongoing security support, etc. etc. etc?... I wouldn't want to build that by myself.
Comment #42
user654 commented.
Comment #43
kentr commented@pinkonomy
This ticket is already in the
Drupal coreproject. What else is required to propose it as a drupal core idea?Comment #44
user654 commented.
Comment #45
berdirI'm not sure if there's any benefit to having this in the ideas issue queue.
That's about actual _features_ on a product/end user level. This is a technical task on a very different level.
https://github.com/php-pm/php-pm-drupal seems to be the only project mentioned in the issue summary to be even remotely up to datele and that wasn't updated in 5 years.
I don't think core itself necessarily needs to support this out of the box, this is IMHO just a meta issue to track improvements that are necessary for something like php-pm-drupal to work. So if you want this to proceed, then have a look at the referenced issues and help push them forward.
Comment #46
kentr commented@berdir
At least w/ PHP-PM, it would not work without changes to core. The issues I encountered w/ PHP-PM required patches to core.
IMO, they are not unreasonable changes, and they clean up the architecture.
Comment #47
longwaveAgree with @Berdir there is nothing directly actionable here, but there are probably lots of technical subtasks that can be parented under this issue to help improve this, so repurposing this as a meta issue.
@kentr if those patches to core exist as issues already, feel free to relate them or set them as children of this issue so they can be collected together and anyone who wants to work on this can find them more easily. Alternatively if there are specific tasks that need to be done that don't exist yet, create them as children of this issue.
Comment #48
mpp commentedComment #49
andypostComment #50
aaronmchale#3108687: Compatibility with/take advantage of code preloading in PHP 7.4 could be a good first step towards something like this, I suspect the improvements required for that issue will be quite similar to those required for this issue.
Comment #51
kingdutchThis was brought up in Slack. Big fan of this idea. Thought I'd chime in with some recent experiences.
At Open Social we're currently running ReactPHP to handle Websockets: https://platform.sh/blog/2021/how-to-build-a-real-time-saas-business-wit...
Most comments in this thread seem to be focused on the processing of the HTTP requests. Which is probably relatively easy to tackle since it's a boundary concern.
When looking into bootstrapping Drupal within ReactPHP for our websocket server, the biggest hurdle that I encountered is that Drupal's database layer. Drupal's database calls are synchronous and loaded entities are all statically stored in memory.
The synchronous nature of the database calls prevents Drupal from actually running in an asynchronous context because it means that querying the data blocks the entire process. This is not an easy thing to solve because it means that the entity layer will need to move from returning entities directly to returning promises. This would have to happen also when running outside of an event loop: the code would still use promises but be executed synchronously.
The shared state is great for performance improvements but for a long running process it will probably cause all of a site's data to be held in memory which will likely exceed memory limits for the application and may cause the server process to be terminated.
Those issues are why eventually we decided on an approach where we use GraphQL (and some RPC-like endpoints) to fetch data from Drupal, rather than bootstrapping Drupal within our websocket server. This allows the websocket server to process other tasks while waiting for Drupal to process our HTTP request.
Even though those are quite fundamental challenges, I still think it would be very cool to tackle. In most of my hobby NodeJS projects I end up rebuilding Drupal in some form or another because its module and data system are just so powerful. Being able to put that into long running real-time processes would be awesome.
In terms of choosing what async event loop/promise library to pick, my vote would go to Revolt PHP which is where AmPHP and ReactPHP (the two largest event loop implementations and ecosystems) are bundling their efforts in anticipation of PHP Fiber support.
Comment #52
daffie commentedThere is a good chance that PHP 8.1 will be the minimum required version for Drupal 10 and PHP 8.1 will have the Fiber support. See: #3223435: Track PHP 8.1 support in hosting and distributions.
Comment #53
sinasalek commented@Kingdutch How Swoole? it's the most performance and feature rich async solution for PHP. it even out performs nginx! for static content. it's a solution that's already here in production use
Comment #54
kingdutch@sinasalek I have not tried Swoole. It was disqualified by us for requiring a non-standard PHP extension to be installed. I suspect it's not an option for Drupal for the same reason.
ReactPHP can use a PHP-based implementation of the event loop, so it can work without extensions. Alternatively it can use the "event" extension for native support to speed things up.
From ReactPHP.org:
Comment #55
kentr commentedIIRC, the biggest hurdle I encountered with PHP-PM was also regarding global state. AFAIK, it was not possible to keep session state separate between requests. IOW, different requests commingled session state which should not be commingled.
That made the bootstrap-once-and-share-it strategy ineffective, b/c the wrongly-commingled state was in the persistent bootstrap.
I would guess that solving these issues is necessary regardless of which persistent app server framework is preferred.
I believe marcjschmidt brought some of the issues over from GitHub to here.
This isn't a priority for me anymore, but for anyone who's interested there may be other issues in the GitHub queue that are still relevant.
Comment #56
louis-cuny commentedThis should be a guideline for drupal core developments. For now, I think Drupal is kilometers behind being compatible with long these technologies.
Recently I had a Drupal-WTF issue with drush: https://www.drupal.org/project/drupal/issues/3215035
It would reappear between requests. But I'm pretty sure Drupal is lot of these bad implementations (like previously said by other comments).
More optimism:
- Laravel Octane will boost the interest in those technologies, swoole and roadrunner
- Roadrunner as already symfony implementations: https://roadrunner.dev/docs/integration-symfony
Final thoughts:
Drupal bootstrap is an obviously huge weight in performance optimization. If drupal survives, it should modernize and get ready for it.
For the roadmap, maybe we should first add tests where requests are reused.
Comment #57
sinasalek commentedYes this is sad that Drupal is this far behind when it comes to performance. And it bugs me why Drupal lead Developers never discuss this seriously so far. I believe Drupal has a much better chance in becoming compatible with these libraries comparing to for example WordPress. The performance boost is game changing specially for headless Drupal. I wonder when we will see an Initiative for this. Laravel Octane is a great example of how it can be done. I don't think the amount of effort needed for this compatibility is more than the other successful Drupal initiatives. So may be we should just propose a new initiative so anyone can gather and focus on the problem. I'm pretty much sure that many companies who have Drupal based product would be interested given how much money they can save down the road.
Any suggestion for this initiative's name? we have to start somewhere :) we can put together the details and a roadmap as a starting point and start the practical discussion on how to move forward from there.
Comment #58
andypostMeantime Nginx Unit 1.26.0 fixed opcache (finally shared) so it can have the same perf as reactphp
Comment #60
user654 commented.
Comment #61
user654 commented.
Comment #62
daffie commentedI have created the Swoole module for Drupal. It is based on Laravels Octane. The Swoole module for Drupal supercharges your website’s performance by serving it via the Swoole or the OpenSwoole PHP server. Both are PHP extensions.
The (Open)Swoole PHP server boots Drupal once, keeps it in memory and then feeds it requests at supersonic speeds.
For instance on a new and empty site a page request with NginX takes on average 0.060 seconds. The same request on the Swoole server takes on average 0.025 seconds. The request time for the Swoole server should go down even more with the use of Swoole memory tables.
Drupal core needs to be patched to make it all work. Apply the patch located in the Swoole module: patch/drupal-core.patch. There are 2 Drupal issues to have Drupal core updated, so that the patch is no longer needed:
- #3279191: Add the container parameter asynchronous
- #3279192: Change the method Drupal\Core\DrupalKernel::handle() to make it work for the Swoole module
The module is not yet feature complete. It is only for other developers/devops persons to play/test it.
The module is NOT ready for production!
Developement is done: https://gitlab.com/daffie/swoole
Documentation can be found: https://daffie.gitlab.io/swoole/
Comment #63
attisan@daffie this sounds intriguing. did you tackle session handling as well or is that if no concern using swoole?
Comment #64
daffie commented@attisan: The module does do the session handling, only it could use a review from a security expert.
Comment #66
bradjones1So I came to this issue by doing some sleuthing around on session handling for #3283058: Incompatibility with SameSite=Lax or stricter session cookie and I think I've stumbled upon an elegant solution to improve Drupal's session handling writ large, and also avoid (most?) of the core service overrides in the Swoole module.
It all boils down to what I describe in #3283288: Implement Symfony SessionListener - basically, if we stick closer to the Symfony trunk, they are solving this upstream for us. These changes are more or less what is included in the referenced Swoole module, plus some other goodness that would fix issues like #3228658: Session cookie is re-set on all Big Pipe'd responses.
I think Drupal could implement Symfony's
SessionListenerand reduce our own boilerplate, and reduce the Drupal-specific compatibility layers for things like Swoole. Thoughts?Comment #67
attisanA list of currently active "persistent app servers"
PHP Framework on top of Symfony and ReactPHP components
RoadRunner is a high-performance PHP application server, load-balancer, and process manager written in Golang
appserver.io is a multithreaded application server for PHP, written in PHP
Amp is an event-driven concurrency framework for PHP
Event-driven, non-blocking I/O with PHP
PHP-PM is a process manager, supercharger and load balancer for PHP applications
Powering the next-generation microservices and application
High Performance Programmatic Server for PHP with Async IO, Coroutines and Fibers
The order is random (chose ol over ul due to formatting). Some of them depend or build on top of others but all seem to tackling with the very same topic. I think we should try to find an agnostic solution to provide support - one that would enable the use of any of these (probably) incompletely listed app servers.
As for compatibility (after fiddling around with a custom react/http setup and swoole (thx @daffie)) I see the session handling as the common denominator of trouble - specifically the fact that session handling is crippled by checks against PHP_SAPI being 'cli'.
Perhaps we could introduce (as @daffie already proposed in #3279191: Add the container parameter asynchronous) an additional global drupal parameter like
persistentthat - whoever implements a persistent drupal app-server with whichever available variant - can be set and is checked whereverPHP_SAPIis checked.Comment #68
andypostThe asynchronous parameter is only a workaround to allow app-server control container
The real solution is #2371629: [meta] Finalize Session and User Authentication API which moving slowly but more then half of way passed atm
IIRC the main blocker nowadays is #2484991: Add the session to the request in KernelTestBase, BrowserTestBase, and drush
Comment #69
louis-cuny commentedWill depend on this issue:
https://www.drupal.org/project/drupal/issues/3228629
Comment #70
ressaThanks for sharing @andypost, Drupal's
quick-startoften freeze when I use it, #3271178: Quick start command installation stops responding.See also Drupal Quick Start Command > Troubleshooting added by @louis-cuny.
Comment #71
pebosi commented@sinasalek
Can you give more details about how you're using swool with drupal?
Comment #72
bradjones1Could also be interesting to move to/implement symfony/runtime, which advertises:
Comment #73
andypostUsed to give a test run of
- swoole - it needs version<5.0, works with some hacks - env is not passed when executed via cli, localhost:8080 fauled to build some links
- roadrunner, works only first request, needs workaround for sessions, failed to deliver static assets ... except front-page
- unit - works with default config, out of box same speed as php-fpm useful for docker as running as one process
Comment #75
user654 commented.
Comment #76
andypostI'm excited to use nginx-unit with PHP - it just a bit slower then php-fpm but it highly customisable and allows to replace nginx+fpm with single binary (near 1MB in size)
Comment #77
back-2-95About FrankenPHP, there is a repo for Drupal but worker mode does not work with sessions as per this issue here.
https://github.com/dunglas/frankenphp-drupal/issues/1
Comment #78
mustanggb commentedCommenting mostly more for my own benefit next time I read this issue; nginx-unit looks like it will be nice, but isn't at feature parity with nginx, yet.
Comment #79
aaronmchaleI’m also very interested in Nginx-unit, planning to experiment with it soon. Once I’ve had a chance to properly use it, I’ll share my experience.
Comment #80
bradjones1Per #24 and #51, these concerns regarding static caching (I guess not to be confused with concerns over static assets) came to mind today when I was implementing some static result caching inside of a service.
I'm not sure how many examples there are in Core; a quick search turned up at least FileCache, and of course there are static collections of loaded entities. And probably most important on the security side,
EntityAccessControlHandler::$accessCache.This seems to me to be a major blocker and even trickier because it's not something that you can control for at runtime.
Am I missing something key here? Cache invalidation on data stored with Cache API would work just fine, I think, but what about all these pesky static caching properties? Seems to me that they must be sandboxed to the currently-handled request? And what's to stop sites from using this pattern and having nasty side-effects when they start using one of these servers? Sorry if I'm repeating others here.
Are services like current_user also an issue, or is that handled in a way via moving this kind of data to the request object? Regardless, there's tons of code (e.g., context system) that rely on the current user in the container.
Comment #81
geek-merlinI think we end up with a handful of patterns, and maybe a few dozen services to touch.
Some static caches can be moved to MemoryCache backends, some others and some services need to be moved to the request object.
This can be done with thin wrapper services or methods.
As of now, it looks it a bit of work, but no big complexity.
(If no new dragons appear...)
Comment #82
andypostI bet it mostly about priority of related issues
Comment #83
bradjones1I opened #3324241: Provide DIC-friendly, concurrency-safe alternative(s) to `drupal_static()` to address the broader static caching question. TIL that
drupal_static()is still the official way to do this, but it's not broadly applied in D10 times.Comment #85
user654 commented.
Comment #86
effulgentsia commentedFrankenPHP has a known issue about crashes when certain PHP constructs and functions are used within Fibers. I think it would be great to open a separate Drupal core issue that tries to find out if Drupal makes any of those calls within fibers. That could happen independently of this issue, which affects all persistent app servers, not just FrankenPHP. However, I don't have any ideas at the moment on what the best way would be to determine if Drupal triggers any of those FrankenPHP crashes without first solving this issue.
Comment #87
andypostThe only child issue and possible way forward is #3313404: Use symfony/runtime for less bespoke bootstrap/compatibility with varied runtime environments
Comment #88
renrhafFrankenPHP official support in Drupal would be awesome, I'll give it a try if I find the time !
Comment #89
andypostNice write-up and tool to catch shared data https://dev.to/sergiid/getting-symfony-app-ready-for-swoole-roadrunner-a...
Comment #90
bradjones1Re: #87, that is the issue we need to untangle at #3324241: Provide DIC-friendly, concurrency-safe alternative(s) to `drupal_static()`. Should we change the parent of that issue to this one? Runtime is one of a few items that need to be addressed. The reference to the
ResetInterfacein Symfony 7 is excellent and provides us a model to build on instead of rolling our own.Comment #91
nod_For searchability
Comment #92
daffie commentedLet's add Swoole then also for searchability.
Comment #93
nod_Added an issue to add a Caddyfile to core, used by frankenphp (which is based on caddy), with an rough implementation of the early hints feature that's available thanks to frankenphp (and symfony). We can start by using that in the non-worker mode and once all the issues from this meta are dealt with we can turn on the worker mode of frankenphp to make everything faster without changing much on the infra side.
Comment #94
sinasalek commentedI don't think enough people are aware of the massive performance boost effect this feature can have on Drupal!! otherwise it would have be done long a time ago
Comment #95
andypostThere's fresh approach to add the Symfony Runtime's frontend in #3453474: CLI entry point in Drupal Core (Dex)
Re @sinasalek there's long way to clean all static variables before Drupal sites can benefit of pre-bootstrapped kernel
Comment #96
sinasalek commentedThanks for the update @standpoint
There has been many attempts do this over the years but non had enough strength to pull through.
I'm thinking about creating a new initiative, raise awareness and gather enough support to tackle this complicated issue.
Symfony supports runtime, which might be a good start. It's suppose to support different runtimes for running symfony
https://symfony.com/doc/current/components/runtime.html
As for static variables. it is possible to workaround it. There are multiple ways to address it. it appears that Swoole can handle it using co-routines
https://www.perplexity.ai/search/I-want-to-EZuTp_oHSmiElEHFpfToow
Comment #97
samuel.mortensonWhen I wrote Tome (a static site generator) I wanted the performance to be better than `wget --recursive`, so I added in the ability to handle multiple HTTP requests in one bootstrap. There are still many odd bugs, but here are some overrides I did to reset "state" between each request:
https://git.drupalcode.org/project/tome/-/blob/8.x-1.x/modules/tome_stat...
Might be helpful to future core changes!
Comment #98
bradjones1That linked code snippet is Exhibit A on why there needs to be an API-level fix for this issue. So many caches/states to reset. And I'm sure they were all hard-fought to discover.
Comment #99
kingdutchFor me #3324241: Provide DIC-friendly, concurrency-safe alternative(s) to `drupal_static()` could be part of that.
I think focusing on “reset” is the wrong part of the equation. The focus should be on creating a context for static caches to be attached, to that allows for switching or clearing. A request may have such a context and it may be shared (e.g. between sub requests). However it should also be able to exist without a request (e.g. in a long running process).
A long running process might have a memory cache that has changes from another application passed to it through a message bus to make sure it doesn’t use outdated data.
The API that Drupal provides should make it possible for services to easily use the right cache at the right time, that’s likely the hardest part.
Comment #100
chi commentedRe #99. That makes sense. Static cache is the fastest cache ever. It would be not wise to throw it away. I think the potential performance gain from static cache might be comparable with the one from skipping bootstrap phase. The application needs to have a control on what needs to be reset.
Comment #101
catchI think #3324241: Provide DIC-friendly, concurrency-safe alternative(s) to `drupal_static()` is a duplicate of #3047289: Standardize how we implement in-memory caches.
Re #99 we could probably add RequestAwareMemoryCache or something like that, it would only be necessary for some caches, not all.
For caches that are unbounded but also don't need request context, we need #1199866: Add an in-memory LRU cache.
Comment #102
chi commentedI think this issue has wider scope than #3047289: Standardize how we implement in-memory caches. Application state is not only about static caches. There are some other resources that may need to be reset between requests. DB connections, temporary files, open streams, etc. In Spiral framework that process is called finalizing. Finalizers are responsible for cleaning up resources. For instance, logger finalizer will call reset method on Monolog loggers.
Besides resource management there is another challenge. Request aware services. In core.services.yml I counted 47 services that has direct dependency on
request_stackand there are many services that has indirect dependency through services likecurrent_route_match,current_user,datetime.time, etc. In Spiral that implemented with "scoped containers". For each request it creates a scoped container derived from root container with some request specific overrides.One more issue to address is stateful Drupal kernel. It has a few of boolean flags (
booted,prepared, etc) that needs to be reset after each request.Comment #103
catchSorry wrong issue reference above, edited my comment to correct.
Comment #104
nod_FrankenPhp is going to the PHP GitHub org:
https://externals.io/message/127347 with some of the doc moving to PHP.net
official announcement: https://les-tilleuls.coop/en/blog/frankenphp-is-now-officially-supported...
Comment #105
kim.pepper@kingdutch wrote a great blog post on how using Symfony Runtime could help solve some of these issues https://www.alexandervarwijk.com/blog/2025-09-08-proposal-restructuring-...
Comment #107
nod_saving it here for future reference: https://github.com/igor-php/igor-php