 try to set this up. Hello? Hello? Okay, perfect. So, okay, this is a look. Do you hear me well? Yeah, perfect. Okay, so this is a look at the modern WordPress server stack. As Chris introduced me, I'm Carl Alexander. I've been organizing work camps in Montreal for almost half a decade now, and I also organize the meetups. I've been doing WordPress since 2009, and I've been developing or coding since I'm in basically second grade, so a long time. You can find me on twigpress on Twitter. I also write on Carl Alexander.ca. I love writing. I love technical writing, and usually this is the result, and I've tried very hard to get better at getting everybody to understand what I'm trying to teach. And one of the things that I do when I'm speaking is I always write a companion article for the talk, so there's a 5,000-word companion article that's going to go up tomorrow around this, and there's also going to be question breaks throughout the talk. That way, if you feel that you're falling behind, you can ask me a question. So, story time. Do you guys remember when a fast WordPress server was the good old lamp stack? So, Linux, Apache, MySQL, PHP. Those were kind of the good old days. You didn't have to think too much. You could install MAMP, and you knew that your server was going to have basically lamp, which is just replaced a Mac with Linux, and things were simpler. And nowadays, you need everything to load fast. You know, Google's going to dock you. If your site takes too long to load, they'll dock you. You can lose some page ranks. These consequences have their dire. Like, as a business, if you're selling anything, if your site takes too long to load, those are bounces. There are people that you're losing. There are sales that you're losing. There are conversions that you're losing. It's super, super important to have a website that's fast, and because of that, the WordPress stack had to kind of evolve. So, what does it look like? This is kind of a conceptual overview of what the modern WordPress stack looks like, and we're going to be going through that throughout the talk. So, the first kind of component, or let's say, section that we're going to talk about is what I call the Request Response Cycle. It covers this section of the diagram, and really what it comes down to is the back and forth between what you call an HTTP request. So, it's a browser asking for something out of the web server, and the web server is saying, okay, I might have that. Here's a response, and here's what I'm sending back. And the way it works is whenever you're asking for, let's say, the WordPress homepage, the first document, as they call it, that you're going to get back to a response, barring that you get an error redirect and all those things is always going to be the HTML. So, good old HTML that you do view source. This is what you're always going to get first, because inside that HTML, the browser also gets follow-up HTTP requests for additional content, such as JavaScript, CSS, movies, what have you, and those are always secondary. So, the first is always HTML, and then after that, it's always the extra files. And your browser is going to continue to cycle through this process of asking for documents for either CSS file, JavaScript, and getting those back. And it'll continue doing that until I can render the page for you. So, the real trick is you want that to happen. The faster this happens, the faster your web page will appear to load, because that's when really the loading process is when your browser says, okay, I have enough information, I can show you the web page now. So, the faster this happens, the better it is. So, that's the first kind of optimization that we need to do. And the reason that we need to optimize that is because we can't just make a web server faster. A web server is really a dispatcher, so it receives the request, but really behind the scene, it's doing a whole bunch of other things. And one of them is for your requests to other services, like PHP, which runs WordPress. And really, the trick to speeding up this, okay, perfect. Oh, this sounds actually a lot better. So, really, the trick at this point is really we want to receive as few requests from the browser as possible. And we really want to forward as few of them as possible also to PHP, because PHP is really the slow, slow, slow part of this whole stack. So, what's involved in the first half of this stack? Well, we have the web server, which is right here. So, we have our browser. Our browser sends a request to the web server. And nowadays, there's three really big players in the web server space, and they own like 90% of the market share. So, you have Apache, which is the old guard, still used widely, very well documented. You also have IAS, which is the Microsoft web server, which I don't know who here has... You can also ignore that one, but who here has ever installed WordPress on IAS? Yeah. That's not... You don't give that gift to any friends that you like. It's really... It's not that fun. And then you have Nginx, which I'll call the new kid, but new kid's kind of relative because it's still over a decade old. But it's used by Automatic since 2008. It's used by all the top hosting companies, WP Engine, GoDaddy. You name it. They all use it. And it's also used by a lot of the IAN agencies. So, you'll hear 10-up talk about it. You'll hear Web Dev Studios talk about it. It's built to handle a lot of traffic. So, it was built by a Russian guy that I forget his name, but he worked for a really big site called Rambler, I believe, in Russia. And he needed a web server that could handle a lot of traffic. So, that's why it's really, really popular. But if there's one thing that you should remember from this talk, it's what we call HTTP cache or HTTP caching. So, we're at this point now. So, a request has gone to the web server and now it's talking to what we'll call the HTTP cache and it'll ask it, okay, have I had this request before? Yes, no. And do I have something, a response cached already? So, do I need to proceed any further with this? If the answer is, yes, I have something cached and we can just return that to the web server who then sends it back to the browser, which is excellent. And like I said, this is the most important element of the stack because by default, a web server is kind of dumb. It will always forward your request to PHP and PHP is often going to just generate the same response, which is absolutely terrible because like I said before, the PHPs are bottleneck and the HTTP cache solves this problem. It caches responses from PHP and it really causes drastic reductions in the cycle time. So, it's really going to take your requests and throw out responses right away and that'll save a lot of time. It'll make your site load a lot faster. And the good news, it's also the one, the solution, the component with the largest set of options for you to use. So, the easiest one is to install what everybody knows as a page caching plugin. Here are all the five biggest ones that are available right now. So, you have backcache, hypercache, WPQ rocket, WP supercache, and WP3 total cache. In general, all four of them, the one that's not highlighted is the paid one, so WP rocket. Personally, it's the one that I like best as well. I find that for less technical people, it's the easiest one to use. But if you're looking for a free option, those other four are also super good. Then you have the middle option, which is you can have a web server can actually do HTTP caching as well. This is a common tutorial for Nginx. I see that tutorial come over very often. Nginx has something called fastcgi caching. It's basically instead of sending things to PHP, it'll check if it already rendered the page and it'll return that instead. So, that's a lot faster than plugins because you're not hitting PHP. So, before the plugin would still hit PHP, so there's still an overhead to connecting for the web server to go to the PHP, but by having the web server do it, you're skipping this entire step and you're going to get a lot, a lot more power out of it. Just with this simple middle option, you can easily survive being slash dotted or being on the front page of Reddit because with Nginx or even Apache supports it, it's meant to handle a lot, a lot of traffic. Then the hardest option is Varnish. Varnish is a specialized server appliance that its only purpose is to handle HTTP caching. So, a lot of the top hosting companies use it, so WP Engine, well, that one's the most known one because they have their Mercury local environment which they use it with, but a lot of the top hosting agencies use that because they can extract that away from the web server and have a dedicated option for handling caching. I don't know if there's any questions so far. Yes. That is an excellent question and it was cut out of this, but you'll find in the article, I've actually discussed the architecture of all three options where they fit in the entire stack because you are correct. They don't fit in the same spot if you will because like I said, the plugin handles on the PHP side. Meanwhile, the web server is by itself handling it internally and Varnish is a separate appliance that the web server has to connect to. So, they look different, but just for length purposes, I had to cut that out. CDN. It depends on the CDN. The goal of a CDN per se is global distribution. So, let's say that you have an image in, you have a user in India who's trying to access an image. If it was hosted in New York, it would take them a lot of time to load that image. So, the idea is they distribute the image throughout the world so it's easier for them to get access to it. But if I take for example S3, you have to manage what we call the caching headers yourself when you're uploading the images. And really that's what's going to do a lot of the work for you is the caching headers. Any other questions? Yep. Sorry, I can't hear you. So, the question is how does the hardware fit in all this? It doesn't really change that much at this point. I mean if you want to hone bare metal server appliances, you can, but I find that digital ocean and really offer like pretty much the same thing at this point and it's really hard to see the difference. Another question? All right. Well, I'll continue. The next step is what we'll call optimizing PHP. So, at this point we've gone through the web server. We've gone through the HTTP cache. It said no, I don't have anything to return back. So, now we have to go back and talk to WordPress. So, it's time for WordPress to do its thing and turn our request into a response. But at this point we've hit what we are main bottleneck, which is PHP. So, how can you optimize PHP to run faster to get your response out faster? The easiest one is obviously use the latest PHP version. So, right now the WordPress minimum requirement is 5.2, which is almost 10 years old, 10 years old. It has no more support since 2011, but the PHP team hasn't been quite idle during that time. There's been a lot of improvement in the PHP 5 line of versions. The biggest improvement was between 5.3 and 5.4, which you saw I believe 10 to 15% improvement in processing time. The other thing that you can use is what we call opcode caching. So, the way PHP works is whenever you load WordPress you're actually running a script like a bash script. And PHP is just processing this script every time. And when it processes it, it's actually compiling it into what they call opcode, which is basically in between machine code and just your PHP code. And it needs to do that every time, and it's very time consuming. So, the opcode caching caches this compile code so that it doesn't need to compile it every time. Now, this is in bundled with PHP in 5.2, 5.3 or 5.4, but since 5.5 it's come built in, so that's another improvement gain that you can get just by moving ahead in the PHP versions. And then the last one that I'm going to talk about is what I'm labeling next generation PHP, which is just two new PHP compilers. So, you have HHVM, which has been talked about quite a bit in the community, and then you PHP 7. So, both these compilers have been rewritten from the ground up. So, they're not the PHP compiler that you would use before with PHP 5. They're completely different. They use two different architecture, compiling architectures. So, HHVM uses just in time compiling and PHP 7 uses ahead of time compiling. Both these compilers offer drastic, incredible, almost magical performance gain. And the good news is that WordPress supports those two compilers at 100%. There's no problem with those. The bad news is that not all the plugins or teams do. And really that's kind of the problem with a lot of these modern software server stacks is that they always need to fall back to PHP 5 in case there's an error. But having used them quite a bit, it's really, it's getting pretty much stable at this point. So, this is the next question period. I don't know if there's any other questions on this section. Yeah. I can tell you about the issues with HHVM. So, in terms of code, the only issue that I've come across is with a plugin, the fail to ban plugin, which sends logs to the syslog. And basically, for some reason, there's a bug there. I couldn't trace it. I couldn't find any ticket on the GitHub about it. And really, you can kind of hack the plugin a bit and make it behave properly. But that's really the only bug that I've really found with it. But the big thing I think with HHVM that if you're not a sys admin or not somebody that's paying attention is that HHVM kind of fails catastrophically when it dies. Like, it just kind of, the service just stops. And it's really, really important to have that fall back that I mentioned before. Because, again, you don't want your website to fail when that happens. And that's why a lot of the stacks that you see posted on the internet, like WP Engine's Mercury, is that they always have a fall back to PHP 5, just in case that happens. But if I'm going to get a bit in the nitty gritty, but if you're a sys admin, you can install Monit, that'll restart the HHVM. But really, once it's configured, well, it's fine. It's just the memory, it's really memory that kind of screws up with HHVM. So if you use, if you're trying to run a web server on HHVM on not a lot of RAM, you have to be very careful. Because if it runs out of memory, it'll just die and leave you hanging. So that's, yeah. I couldn't get, I've been playing around, actually, to build a local dev environment with such a stack. And I had a lot of trouble with XDbug with HHVM. It's supposed to work, but I think it might just be getting it to work within a VM that's kind of problematic. So for those aspects of local dev environment construction, I'm not as familiar because I'm still kind of experimenting and researching around it. But my first kind of foray into it was that, yeah, it didn't work very well. But I think XDbug and PHP7, though, works fine. I just haven't had the chance to test it heavily because it's only going to be available officially in the Linux distribution with Xenial that comes out next week or just came out. But it's coming out soon. So it's not officially, PHP7 is so new that it's not officially supported by most Linux distributions yet, but it's going to be. Any other questions? Yeah. Sorry, HHVMN. Like which one? Oh, CentOS. I haven't tried it. Honestly, recently I just migrated somebody away from CentOS because, I mean, that's another debate entirely that I'm not going to, that doesn't make quite sense here, but there's reasons for it that you can come talk to me after and we can discuss it. Any other questions? All right. So the last kind of third aspect of the stack is what I call the query results. So this is really the relationship between WordPress and the database. So what's going on between the two? Because by default, PHP files don't contain any data. WordPress stores it all in MySQL databases. So really what it comes down to is WordPress or really PHP running the WordPress script is going to hit points where it's like, oh, I need to query my data source. I need to know what's in my database server and get the result back so that I can continue on my way and continue loading my home page. And this is going to happen a few dozen times to a few hundred times, but really if you're in the few hundred times category, you should probably talk to your developer or somebody else because that's a lot of requests. And it's very time consuming. So optimizing this aspect of the cycle comes down to the fact that database queries take time. I don't know who here uses query monitor. Yeah. Like usually if you can, with query monitor, you can see how long your queries take and sometimes a query can take as long as a couple of seconds. So that's a couple of seconds that your browser is actually waiting on the other end to get a response back. And the worst part is that this is happening when, like I mentioned that initially, the first response that we'll always get back is your HTML content. And what's going to generate the HTML content that need is PHP, which needs the database queries. So everything's going to be blocked. So the longer your queries take, it slows down PHP's execution time, which slows down how long it takes for the response to get back to your browser before it can even request everything else. So it has to wait for that to get the JavaScript files to get your images, to get your CSS. And one of the problems that you have as somebody managing a server is you don't always have control on how many queries are going to be sent. So really, even if we need to make PHP wait as little, so really the goal here is to make PHP wait as little as possible. So even if we don't have access to the number of queries or reducing the number of queries that we're doing, like the goal should always be we need to make this be as fast as possible. So what's involved in this stack in this cycle? We have the database server. So we're going to skip all the way to the end. And back in the day, MySQL database meant MySQL server. Unfortunately, the Oracle decided to take over MySQL server. And a lot of people weren't happy with that. And the result is now we have multiple forked versions of MySQL. But really, there's no performance differences between the two. So really, if you're using MySQL, you're fine. If you're using MariaDB, you're fine. If you're using Percona, that's fine. Really, what it comes down to is what we call storage engines. So who here has ever heard of MySQL and EnoDB? So those are storage engines. So they control how the database is going to store data. And that has a much larger impact on the speed of your database. By default, WordPress installs MySQL, which is really, if you're running like me, you're running a small site, that's, there's really not a lot of problems with MySQL. The performance is really good, but as you scale, the better choice is to use EnoDB, because it performs better, especially on the, it doesn't do what we call a table lock whenever you're writing. So if you're, let's say, a common example is, let's say you're managing a site with a lot of publications, every time that somebody's auto-saving a post, it would lock the database. So that's kind of, that would, that can cause slowdowns, but in general, that's not super important because what's important is what we call object cache. So who here is familiar with object cache? Okay, not too many people. The object cache is really a system that WordPress designed for storing fetched, but also generated data. It's really like, let's say you're, you're doing something that's heavy processing wise. Let's say you want to cache an external RSS feed that you've processed. You can use it as well. And WordPress uses this a lot, because what it does is that it, let's say you, you, you get an option from the database, let's say you want to know what's my home URL. And maybe five, five plugins are going to ask what, what the home URL is. You don't want, WordPress doesn't want to query the, its database each time to know what the home URL is. So instead, it caches this inside the object cache. And this causes less database queries. So instead of having five requests for a home URL, you just have one. And then it just keeps getting that information from the object cache. But the problem with the object cache is by default, it's not persistent. So by this, I mean that let's say I'm requesting the homepage of my blog. And I'm asking for a home URL five times. It'll, it'll go in the object cache, get requested once. But then let's say somebody else comes, hits my homepage. Well, it still needs to do that one query again, except my home URL never changed. Because that type of data can stay valid for a super long time. Like your home URLs technically will never change. Unless you're really, the only time I can think of is if you're migrating, for example, HTTP HTTPS or something like that. So that's really when using a persistent object cache is really useful. Because what it does is it connects the object cache to what we call a persistent data store, which is an appliance also kind of like a database that will store that data for future use. So each subsequent page load, instead of requesting the database for our home URL is going to ask that data store, hey, do you have the home URL? Well, yes, I already have it. So and then that will save also time by not querying the database, which is the really, really heavy. And there are two popular data store options. One is memcache. So memcache is what I call the old favorite. It's still used quite a bit. All of WordPress.com uses memcache, a combination of memcache and backcache. It's still very, very performant. If you've invested time in memcache, it's not wasted because it still performs super, super well. But really the new hotness is Redis, which is also a data store, but it does a lot more than just that. And it's super easy to set up. It doesn't need, you can actually use it without installing additional drivers for PHP and it'll connect right away. But with those two data stores, what you need, you also need a plugin. Because like I mentioned initially, the object cache itself is WordPress code. So what you need, you also need a plugin to go and act as the intermediary between this persistent data cache and the object cache itself. So there's a memcache plugin that's still very active and there's a Redis plugin as well that's very active. The last thing I want to talk about is how can you do this yourself? So I've done some research to find three kind of do-it-yourself options. There's DevOps for WordPress, which is the project that I'm working on that I started last year. It's my way of trying to shore up the sysadmin for the community by providing a easy-to-deploy stack that's similar to WP Engine and GoDaddy managed and all those big hosting providers. It currently comes with HHVM, MariaDB, EngineX, Redis, and Varnish. And it all comes pre-configured. So usually you just run two command lines and your site's going to be good to go. The other extremely popular option is Easy Engine. I don't know anybody here that knows Easy Engine. Okay, a few people. Easy Engine, they run a site, super good site. If you're looking for sysadmin kind of tutorials, they have excellent tutorials and they run, they have a project called Easy Engine that is a command line to install to configure a WordPress server. They're super flexible, so that's why most of my points are various. They always come with MariaDB, they always come with EngineX, but you have various object cache options. They support memcache, they support Redis. They also support various HTTP cache options, so they support just having a plugin do it. They support having EngineX do it. They support having EngineX do it with Redis. And they also have various PHP options as well. So if you want to try HHVM, they support HHVM. They also support PHP 7, and I believe that their normal PHP is 5.6, but I can't remember often. And the last one is Trellis. Trellis is made by the Roots team. It comes with MariaDB, memcache, EngineX. You can also have EngineX do the HTTP cache if you want, and PHP 7. The only caveat with Trellis is who here knows about Bedrock? Yeah, so it's coupled with the Bedrock project. So Bedrock is the Roots team kind of project framework for building WordPress applications. We're using the 12-factor app philosophy, but their project is tied to having a Bedrock project, so you can't use Trellis without your project being using Bedrock. At least that's what I, if somebody from the Roots team is here and wants to correct me, then perfect, but I couldn't find anything on their discourse board. So that's it. I don't know if there was any other questions on that section or on the presentation overall. Yes? Sorry, caching validation, and I'm not familiar with the WP Engine caching validation as for the, for caching validation with varnish, what you want to use with varnish is a blue host has this plugin called varnish purge. So what it'll do is it'll communicate with varnish whenever you update a post and it'll send purge requests. So without getting too into it, but varnish responds to a specific type of HTTP request that says I don't want this to be cached anymore, and what the plugin will do is whenever you update a post, it'll, it will send that request for every archive page, every RSS feed, and the home page that this connects to. The only thing, having worked with it, the only thing I have to mention is let's say you're doing this yourself with varnish. The purge all, there's a purge all for purging the entire site at the top of the, of the page, and that's really custom. So you have to go look at their varnish configuration and see how they do it because instead of a purge, it's what varnish calls a ban, which is like a more global kind of, let all these objects are now invalid. Yes? Yes. Not super recently, but when I was working on DevOps, I was, I, the whole point of my, my project was that it needs to run on the smallest digital ocean droplets, so 512 megs of RAM, and using that, it could, if you're hitting varnish, you can easily send it hundreds of requests a second on that small of a server, and it'll handle it well. Obviously, if you start hitting PHP itself, even with HHVM, your mileage is going to vary because if your cache is cold, like the op cache, if it's cold or not, will have a certain effect on it, but in general, it handles stress tests very, very well. Even out of the box, you can handle a lot, a lot of connections. Any other questions? Cool, sweet. So just a reminder, I'll post the article tomorrow. There's some extra information in there that I cut just for, for length purposes, like HTTP2 and FastCGI, and like I was asked earlier, like what, what the different architectures look for, let's say you're using a plug-in, a caching plug-in, or versus varnish versus your web server. So thank you.