Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What does a modern high performance php serving stack look like?


We handle 50-60 million monthly page views (comments embed requests) in our commenting system using PHP/Laravel, NGINX (2 load balanced servers), Redis (for queues and caching), and MYSQL.

All performance issues we have ever encountered were always related to the database - never had an issue with PHP or Laravel.

However, we use Node.js for websockets. Though there are some improvements in PHP for event-driven development (like ReactPHP [1]), it was quite hard to find proper documentation and help to build a production-ready WebSocket server. So, we ended up using Node.js for that.

The new features added to PHP in the latest versions are great. Type hinting and return types are really helpful in writing better code. I hope there will be an addition to type hint advanced data structures (ex: Arrays of Objects) in a future version.

[1] https://reactphp.org/


If you want better types, have you taken a look at Hack?

https://hacklang.org


We handle a couple million daily users, educational online reading product used by K12 schools worldwide.

Internal framework PHP monolith, nginx, Aurora MySQL, redis, Memcache, internally developed message queue, handful of small Go microservices.

While we're largely hosted on AWS, some countries require us not to be, namely China, where are product lives on servers run by the government. We've kept are infrastructure non-AWS compatible.

For our US installation, monolith scales up to 50+ servers during the day and down to a minimum of 2 at night.


At $WORK we serve billions of requests a month on with nginx, php-fpm, and Percona.

In total I think it’s something on the order of ~1000 application servers (nginx/PHP) that are specced to handle 28 concurrents, and 200 Percona instances of varying sizes. A big HAProxy cluster sits in front of the whole thing and cloud flare in front of that.

A whole bunch of memcached servers spread around too. By far the biggest bottleneck is the MySQL servers at the moment, so we rely heavily on memcached to keep requests away from the DBs.


Just curious, have you calculated what it would cost to have the equivalent of those 50 servers as dedicated bare metal servers?


I haven't. That's all Ops, and I'm a developer. We're a pretty small team of about 15, and managing physical servers would require a big investment in staff alone.


There is little difference in managing a bare metal server vs an AWS VM. Both can come preinstalled with your OS of choice. And you are responsible for maintaining the system either way. I'm not talking about colocating your own hardware in a data center. Just renting bare metal.


Not OP but I have seen web apps with 1 million MAU (Monthly Active Users) using:

- Laravel

- Redis

- PostgreSQL

- Nginx+ php_fpm


I am deploying considerably smaller applications but I've had good results lately with Caddy and PHP-FPM [0]. I tend to use MySQL 8 but I've made use of both Redis and Memcached where appropriate.

I don't even use any of the JIT stuff, but I will soon.

[0] Once I figured out how to configure Caddy, that is. (Laravel vs Caddy documentation ease of use is night-and-day territory.)


FWIW, a Caddy config for a Laravel app is just the following (which you can find here in the docs https://caddyserver.com/docs/caddyfile/patterns#php):

    example.com {
        root * /srv/public
        encode gzip
        php_fastcgi localhost:9000
        file_server
    }
Do you have any specific comments regarding Caddy's docs? What exactly did you find difficult? I'm a Caddy maintainer, and I'm always looking to find ways we can improve.


(Thank you for your reply! I'm using some of that pattern. It wasn't enough for my requirements, unfortunately. What I have now works fine; I use the handle directive a fair bit and that makes sense to me. This is not a problem now)

The main problem with Caddy's documentation is that it is a maze of twisty tunnels! Lots of terse fragments of documentation that bounce you on to other terse fragments of documentation. It feels fractured and impermanent. I lose my place.

Part of the problem is inherent to very flexible packages like this, and it is going to be difficult to solve.

I think you possibly overestimate how many people have time to learn about the JSON syntax or API configuration, how many people want Caddy outside of a package manager installation, etc.

It almost seems to me that you need entire documentation guides -- "Caddy for Nginx users", "Caddy for Apache users", "Caddy for people who need an API-driven server" -- that have much more narrative flow to them.

(IMO, configuration file adapters are a hiding to nothing. Just explain to me why Caddy is better and help me make the switch)

I love Caddy for what it is now doing for me -- please don't get me wrong, I think it's an impressive project -- but after 28 years of configuring web servers I really need migration documentation that I can read in detail without clicking from link to link and lots of emoji people.

Small observation: the mid-blue text on a pale blue background for your code examples and monospaced text is difficult to read if your eyes are over 40 years old and it's been a long day.


This is valuable feedback, thank you. A lot of people just say that the docs suck and we can't do anything about that. This is more helpful. I'll see what we can do to improve cohesiveness and clarity/accessibility.


FWIW, I'm very comfortable with nginx, but preferred something with Acme built in.

What I struggled with most in setting up things with caddy was the context for a config statement.

I could usually find the config parameters I needed, but I had no idea at what level of nesting it was and in what context it was used.

I would have found it incredibly useful to have a reference caddyfile for every parameter so I could see it used in context and then just strip that reference file down to what I need and go from there.

In the end, I just went back to nginx and dealt with Let's Encrypt myself since that was what I was most comfortable with and decided learning this new thing wasn't worth the benefit at that moment for the specific project. I'll probably revisit it later this year.


Did this page help? https://caddyserver.com/docs/caddyfile/concepts - it explains the structure of the Caddyfile, what directives are, and goes from there.


Thanks -- I'm glad it didn't come across too whiny, because to be honest you've saved me from so much HTTPS pain so far I really will put up with a _lot_! :-)


Thanks! I appreciate that feedback.

I do want to work on improving the "Tutorials" section to make it apply to more installation methods (i.e. running in Docker requires additional setup to use the admin API, running as a service means you may need to turn off the service before playing with the tutorial, etc)

"Caddy for X users" pages are complicated to get right IMO, and I'm not sure it's worth the effort - those are also general purpose servers, and can be used an infinite amount of different ways. Comparing them is difficult and I'd argue that it's not that useful. Take for example https://statamic.com/vs/wordpress to get a sense of what I mean.

> I think you possibly overestimate how many people have time to learn about the JSON syntax or API configuration

I definitely don't; I spend a lot of my time improving and polishing the Caddyfile adapter since it's definitely the easiest way to use Caddy. The tutorials do put too strong a focus on JSON in my opinion (Matt wrote them). But on the other hand I think it's pretty important to understand that the Caddyfile _is_ an adapter to JSON and not the native config language. It's key to knowing how to debug and inspect how Caddy actually runs.

> how many people want Caddy outside of a package manager installation

I'm not sure I understand this point though, what are you trying to say here? You can definitely just download the caddy binary and run it wherever, you don't need to use a package manager. I'm not sure what this is trying to point to.


> The tutorials do put too strong a focus on JSON in my opinion (Matt wrote them).

I don't mean to start a fight between friends! :-)

> But on the other hand I think it's pretty important to understand that the Caddyfile _is_ an adapter to JSON and not the native config language. It's key to knowing how to debug and inspect how Caddy actually runs.

Agreed.

> I'm not sure I understand this point though, what are you trying to say here? You can definitely just download the caddy binary and run it wherever, you don't need to use a package manager. I'm not sure what this is trying to point to.

Sorry, I mangled that with a run-on sentence, didn't I! What I mean is, I think more users are likely to want the package manager, systemd-configuration deal. The automatic-HTTPS thing is such a strong sell that I think a lot of people will seek to replace nginx just for that.

I could totally be wrong here but this is where I think a sort of narrative document for Nginx users at least is perhaps worth it.

Some of this is always going to be a challenge because Caddy is a fascinating, category-straddling project; you've made a product that is somewhere between a magical automatic appliance, a Golang web dev framework and a traditional configurable server, that avoids the downsides of all of those things as far as is really possible.

Documenting that is definitely a unique challenge.

I'm prattling on now but thank you again for Caddy; it really is a great contribution.


> I don't mean to start a fight between friends! :-)

Nah it's fine ^_^ we both know we have a difference of opinion there, and we balance eachother out on that.

> Sorry, I mangled that with a run-on sentence, didn't I!

Hah, maybe a bit! Thanks for clarifying, that helps. We'll definitely take those comments into consideration when we work on updates to the docs!

Thanks for the kind words <3


We use AWS elastic beanstalk mostly, so just auto scaling EC2 servers running nginx, RDS serverless, SQS worker queues etc. Front end is static hosted on S3/cloud front. Handles up to ~100k orders per day.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: