Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ecomevo's avatar

Ultimate PHP server performance combo

I'm trying to bring together the best PHP compatible technologies to create the highest performance server combo possible to-date without switching to something like NodeJS while still having the ease of development found in Laravel/Lumen.

Here's what I had in mind, but I'd like the community's feedback on how feasible it would be to tie these together, if at all:

  • EC2
  • PHP7
  • pthreads
  • HHVM
  • Appserver.io
  • MongoDB
  • Lumen

Thoughts?

0 likes
15 replies
willvincent's avatar

Why PHP and HHVM? Pick one or the other. :)

Also, you should probably include some kind of reverse proxy, squid, varnish, etc. Also good backend caching, memcache, etc.

1 like
ecomevo's avatar

Leaning towards PHP7 over HHVM, actually. Really should have wrote the list as "PHP7 or HHVM" instead of separate line items.

Not sure Squid or Varnish etc would make sense in my use case because I'm mainly setting this up to handle many API requests and most of the processes will be background workers.

Planning to use Redis for caching.

I might also go the MariaDB RDS route instead of a NoSQL option.

fideloper's avatar

Making PHP faster itself, while fun, is also a waste of time when it comes to using your code to build something of value to your end users.

The largest performance bottlenecks will always be network calls, especially to databases (TCP calls, compared to things going on in the CPU, take orders of magnitude longer to run). You'll almost always be limited by speed of database queries or IO-bound operations (read/writing to disk, even SSDs) rather than something CPU-bound.

Note that the scaling php book ( a really! excellent resource ) is all about scaling using a multi-server environment, not an environment that sucks the most possible speed out of a server

Lastly, PHP, like Ruby/Python/Node, is an interpreted language (although NodeJS does have the async thing going for it). If code execution speed matters in some way to what you're building, you may want to consider a compiled language (C or variants, Java or variants).

Your question really sounds like you're looking to have fun making things go as fast as possible. That's totally cool, and you'll learn a bunch playing with all that stuff!

However, the way you phrased your question reminds me of a trap I've been in before. You're mistaking the technologies you listed as being about performance, when that's not necessarily true. Everything there has specific times when they're a good idea. "Making my app fast" is rarely one of those reasons.

The first bullet point "EC2" underlines this point. There's nothing fast about EC2. On the smaller tiers, in fact, they're pretty slow. AWS's value proposition is the ability to cut out an ops engineer, while providing you with the ability to spin up multiple servers and orchestrate complex, high availability infrastructures. Performance is not a focus - it's paid for by using higher tiers of EC2 servers.

(Similarly, MongoDB isn't about code speed, but about document storage. Even development speed added is marginal).

I think the one exception here is HHVM, actually, is about speed, since Facebook runs thousands and thousands of servers and actually saves real money on faster code.

(I've never played with appserver.io, that sounds interesting).

I hope this doesn't sound too much like an angry internet rant. Going down this road will definitely teach you some new stuff, but don't be fooled by anyone saying any of those tools are about app performance. And don't let anyone tell you app performance is really important at the level of optimizing how fast code is run through a CPU.

6 likes
ecomevo's avatar

@fideloper What would you recommend over EC2 for speedy microservices?

Sadly, it's unlikely I can use anything other than an AWS solution due to requirements from corporate product managers. Usually I love DigitalOcean.

Code execution is important, but more for the angle of needing to process a huge volume of requests per second from SQS and every other service our company while be hammering my system with. Trying to dodge the push for my team to switch from PHP to NodeJS (which none of us are proficient in) for a major scheduled code rewrite because they feel PHP won't be able to handle the request volume.

fideloper's avatar

@eComEvo AWS is great! My point is that you just end up paying more for speed. Nothing in AWS is more speedy than other providers necessarily.

Ah, that details is perfect - large volumes of SQS jobs can definitely benefit from fast execution. Depending on what the job type is (image processing?) you can determine the best instance types to run on AWS. Some are memory-optimized (Fast ram), some are CPU-optimized.

All instances can use "provisioned IOPs" which (for a fee, like EVERYTHING in aws!) can guarantee you better disk read/write speed.

NodeJS is not necessarily faster than PHP, but it does work asynchronously (so long as your code isn't accidentally blocking), allowing for the possibility that some NodeJS workers may be able to crunch a few jobs at the same time (although I'm not necessarily sure about that with nodejs).

I'm curious about what type of jobs the workers will be doing? Maybe I can help point to a solution there.

1 like
ecomevo's avatar

@fideloper The workers will be processing API requests from across our system related to MWS such as inventory handling, repricing, competition analytics, etc. The biggest challenge is handling millions of AnyOfferChanged SQS notifications coming in. The data contained in those notifications impact numerous parts of our system.

Then there are all the other MWS API requests that need to be made in response to these notifications and also the needs of our core/secondary systems. Those requests can total in the millions per hour as well and need to be coded to squeeze every bit of potential out of the MWS throttling limits.

This doesn't even cover the demands created by calls to the databases, S3 and RedShift in relation to the functions above.

I plan to make extensive use of asynchronous multithreaded support granted by pthreads in PHP7, GuzzleHttp promises (which the AWS SDK supports natively) and worker queues where appropriate.

Everything needs to be able to scale automatically regardless of load spikes and designed as efficiently as possible to keep costs as lean as reasonable.

Thoughts?

BTW, definitely going to read through Scaling PHP. Thanks for the recommend!

ecomevo's avatar

I'm also wondering if it would be possible to have Lumen running as always-on servlets so the framework doesn't have to boot up each time.

This sort of benefit is seen when Lumen is run as a daemon queue listener. Everything stays in memory after the initial boot.

Do you think it would be a good strategy to have a single instance that handles polling continuously from the SQS queue within an always-on daemon process to eliminate the need to boot the framework each time? This instance handles processing messages asynchronously using multiple threads, passing off the processed results to other dedicated daemon queues to handle more complicated specialized processing.

1 like
jimmck's avatar

Lumen is not a servlet engine. Its key difference is the amount of stuff done to initialize vs. Laravel. But in the end it starts a new at each request. This is where Java web server come in handy. But again some volume transaction systems avoid them because of the overhead. Appserver.io is interesting as looks like a threaded server, but there are no benchmarks and the 'fast CGI' reference is scary. Given your message rates you might find it hard to find a single off the shelf systems. HTTP message will be too slow IMHO. And Node or even PHP or Java processes will still need monitors to manage the flow.

ohffs's avatar

Have you thought about something like kubernetes? It sounds like you're in that kind of ball-park?

1 like
fideloper's avatar

Thanks for the details, that's super helpful context for the original question!

I think overall you have a really strong case to move away from PHP on those worker jobs, but I know it sounds like the team isn't ready to move away from PHP.

As for booting the framework - Using php artisan queue:work --daemon currently loads the framework once, Laravel already takes care of that (that's why any code changes necessitate the restarting of the queue via php artisan queue:restart).

For sending lots of api requests during a job - Guzzle's async functionality might help there.

Using thread-safe PHP may help you if you take a job and spin off multiple threads to handle more of a job. Handling threads yourself is a bit of a hassle, but might be what you'll end up doing in any language used. The benefit of a compiled language (Go, java) would be faster job processing with a lower memory footprint, allowing for more workers per server.

1 like
ecomevo's avatar

@fideloper Do you recommend switching entirely to something else such as Node? Or a hybrid solution with something like Node + PHP, where each handles it's strong points?

The thing with Node, is that it is very fast at processing events such as API calls TO the server. However, with something like SQS it is a call out FROM the server, so the script has to actively request and then process each group of messages it pulled. This would seem to be better suited to multi-threaded handling or async functionality such as found in Guzzle. Node is single threaded.

ohffs's avatar

If it's any anecdotal help, I've switched out a lot of internal API services to use Go instead of various php/python/node apps. It's fairly easy to code with - if you can read & write even a half-way complicated php app you should be able to pick up some Go (ie, type some stuff, google some stuff, type some stuff ;-). And it's great to deploy compared to node or python :-)

fideloper's avatar
Level 11

Every PHP process is a single process, it's just that PHP-FPM spins off many processes while NodeJS uses a single process to handle all requests via asynchronous action. Don't get confused by how the language is run (php with php-fpm is a process per request, nodejs is a single process handleing all incoming processes) with what the language itself can do.

PHP (if thread safe ) can spawn threads, and NodeJS can create child processes which can help handle additional load. I don't think Node is necessarily the way to go in this project, it's still a slower language overall, it's just that people call it "fast" because of the asynchronous nature.

The asynchronous nature of NodeJS allows multiple things to happen "at the same time" (it's not truly at the same time), but it does not actually do any one thing particularly fast. If I remember right, it's async setup is basically to process something else while another thing is busy doing work. For example, you can make HTTP api call. While waiting for a response to that network request, NodeJS might start processing another incoming web request. Nothings truly happening "faster", it's just able to handle multiple things at once so the overall time of multiple things happening is lower. Using NodeJS, you need to be careful of taking blocking actions (like file i/o) that might hold up everything.

NodeJS may be the answer as it would handle lots of HTTP requests (incoming and outgoing) well. If network requests is the main bottleneck in speed, NodeJS would be fine I think.

I would, however, definitely use a hybrid approach. There's no reason to re-write the main PHP app (usually!).

1 like
ecomevo's avatar

@fideloper A rewrite of the main PHP app is what we were going to have to do anyway. It's so old and patched together that it's become unmaintainable. Given the rest of the architecture has already been rewritten in NodeJS, there is a big company push to not rewrite this service in PHP if we are going to do a rewrite.

I think PHP is more than capable of handling what we need, but given the company push (and the overwhelming number of Node devs here) it looks like I will be going the Node route instead.

Thanks for all your input!

1 like

Please or to participate in this conversation.