For Safe and Secure online transactions SSL is mandatory. Now if we are planning to…
Well we all know that nobody likes a slow website, and this becomes even more crucial for eCommerce site owners. Every second delay can cost you a drop in your conversions.
Talking about eCommerce and you can’t ignore Magento. It is also our preferred eCommerce platform for eCommerce Development.
Magento comes loaded with features and flexibility for developers but this makes it a very large and complex system. Often, we receive requests from eCommerce Merchants to speed up their Magento stores.
Magento is resource hungry and deploying such a huge code base requires a highly optimised environment with supporting hardware configuration.
This guide will provide best practices and configurations for a lighting fast Magento 2 store.
Summary
- Operating System on AWS
- Apache with HTTP2
- PHP-FPM
- Apache MPM
- PHP Opcache
- Magento 2 Optimization
- Varnish with SSL using HAProxy
- PHP-FPM Tuning
- Conclusion
1. Operating System on AWS
So, before we move ahead, we need a server with operating system. In this guide we are using AWS with Ubuntu as our operating system. It is an open-source operating system but you are free to use other Linux distributions like RedHat Enterprise Linux, CentOS, Debian and similar. Please note that Magento doesn’t support Windows & Mac OS.
Memory Requirement: Magento requires at least 2GB of RAM, but we would recommend to have at least 4GB of RAM as you would be requiring third-party extensions or custom code for your store requirements.
If you would like to know how to setup a Ubuntu instance on AWS EC2 then you can check it here
Please keep in mind that you have to open port 80 for the http request. You can do this under security group in AWS console panel, Click here to see how. We would also recommend opening 443 because browsers are now forcing you to have SSL certificates for your website and you would also like to keep your store secure.
2. Apache with HTTP2
Once our Server is ready with required ports open, we can then proceed with web server installation. Magento supports Apache 2.2 or 2.4 and Nginx 1.x. In this guide we are using Apache 2.4 because it is still the most popular web server in the market and very powerful.
Step 1 – Install Apache using Ubuntu Repository
Before we install Apache i would recommend to update and upgrade the packages. Use the following command to do that
sudo apt update
sudo apt upgrade
Apache Installation
sudo apt install apache2
You can now access your default Apache landing page to confirm the installation.
http://your-server-ip
Make sure port 80 is open or else it will not load.
Step 2 – Enable HTTP2
Check Apache Version
apache2 -v
Most likely you will notice that Apache 2.4.29 is the current version that has been installed on our server. If in case the version is less than 2.4.24 then we will be using Ondrej PPA for latest release
To add the PPA , type:
sudo add-apt-repository ppa:ondrej/apache2
Once the PPA is added, update and upgrade Apache:
sudo apt update
sudo apt upgrade
This will update and upgrade apache2 to Apache 2.4.27+.
You will now need to add the following line into your Virtual Host config files between <VirtualHost>..</VirtualHost> tags. You can also add this line to /etc/apache2/apache2.conf file if you want all of your sites to run on HTTP2
Protocols h2 h2c http/1.1
Enable mod_http2
Let’s enable the Apache’s mod_http2 module by using the following command
sudo a2enmod http2
Restart Apache
sudo service apache2 restart
Test HTTP2
You can test your webpage to see if HTTP2 is working on your server by checking the headers or you can also check it here
3. PHP-FPM
We have our Apache installed on the server and now we should proceed with PHP installation. In this guide we are going with PHP-FPM, though the most common approach of running PHP with Apache is mod_PHP because it comes default with Apache.
But since our target is to get optimal performance for our Magento store so we will be proceeding with PHP-FPM.
FastCGI Module
Let us first start with installation of FastCGI module that is required to integrate PHP-FPM with Apache
sudo apt install libapache2-mod-fastcgi
This command will most likely throw the following error
So lets proceed to install it manually using the following command
cd /tmp && wget http://mirrors.kernel.org/ubuntu/pool/multiverse/liba/libapache-mod-fastcgi/libapache2-mod-fastcgi_2.4.7~0910052141-1.2_amd64.deb
sudo dpkg -i libapache2-mod-fastcgi_2.4.7~0910052141-1.2_amd64.deb; sudo apt install -f
PHP Installation
We will be using Ondrej PPA for installation of PHP
sudo add-apt-repository ppa:ondrej/php
Once the PPA is added, Update and Install PHP and PHP-FPM packages
sudo apt update
sudo apt install php7.2 php7.2-fpm php7.2-common
Once installed, php7.2-fpm service will start automatically. You can confirm it by running the following command
sudo systemctl status php7.2-fpm
Apache Configuration
Lets enable required modules for apache configuration
sudo a2enmod actions fastcgi alias proxy_fcgi
So far so good, Let us now configure our sites on Apache to run with FPM/FastCGI.
Since we currently didn’t setup any Virtual Hosts so we will be making this change to the 000-default.conf which you will find in /etc/apache2/sites-available/
Add the following within your <VirtualHost> … </VirtualHost> tags
<FilesMatch \.php$>
# 2.4.10+ can proxy to unix socket
SetHandler "proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://localhost/"
# Else we can just use a tcp socket:
#SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
Save the file and restart Apache using following command
sudo service apache2 restart
Test PHP-FPM
Create a info.php file containing <?php phpinfo(); ?> in /var/www/html/
Open http://your-server-ip/info.php in your browser and you will see FPM/FastCGI in Server API column.
Awesome, now we have our PHP installed but we would be requiring some PHP extensions that are required by Magento. You can install them by using the following command
PHP Extensions for Magento
sudo apt-get install php7.2-bcmath php7.2-ctype php7.2-curl php7.2-dom php7.2-gd php7.2-iconv php7.2-intl php7.2-mbstring php7.2-mysql php7.2-simplexml php7.2-soap php7.2-xsl php7.2-zip
Restart PHP-FPM by using the following command
sudo systemctl reload php7.2-fpm.service
4. Apache MPM
Apache uses Multi-Processing Modules (MPM) to handle and process incoming requests. There are three types of MPM in apache which are Prefork, Worker & Event MPM.
By default, Apache comes with Prefork MPM. We will not go in detail about the pros and cons of each module, but in this guide, we will be using Event MPM which was introduced in Apache 2.4 and best for managing high loads.
Let’s switch the MPM from Prefork to Event mode
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
Restart Apache
sudo service apache2 restart
Let us now confirm if the Event Mode is enabled
sudo apachectl -V
You will see Server MPM: event in the output
5. PHP Opcache
Opcache is a caching extension in PHP that stores precompiled scripts in shared memory. So, it eliminates the process of compilation on each request as it is reading the precompiled script bytecode from Memory
Let us first start by enabling Opcache. Open php.ini available at the following location:
/etc/php/7.2/fpm/php.ini
Remove Semicolon in front of opcache.enable=1
Following are some recommended PHP Opcache settings for Magento 2:
opcache.memory_consumption=512
opcache.interned_strings_buffer=48
opcache.max_accelerated_files=100000
opcache.revalidate_freq=4
Save the file and restart PHP FPM
sudo systemctl reload php7.2-fpm.service
Confirm PHP Opcache by again opening the php.info in browser
http://your-server-ip/info.php
Perfect, Now we need more extension that would be very beneficial for the performance of our Magento Store
PHP APCu
As per Magento this extension caches file locations for opened files, increasing performance for Magento server calls (including pages, ajax calls, and endpoints)
sudo apt install php7.2-apcu -y
Restart PHP-FPM
sudo systemctl reload php7.2-fpm.service
Confirm it by opening our info.php file in browser
6. Magento 2 Optimization
Our Web server is ready for Magento Installation and all we need is to have a MySQL server.
You can install MySQL on the same server, but our recommendation is to use a separate server for MySQL, preferably on Amazon RDS.
We will not cover the RDS setup in this topic and will proceed with optimizations assuming we have Magento installed on our Server with demo data.
While in Developer Mode go to
Stores > Configuration > Advanced > Developer and make the following changes
Grid Settings > Asynchronous indexing : Enable
CSS Settings > Merge CSS Files : Yes
CSS Settings > Minify CSS Files : Yes
Javascript Settings > Merge JavaScript Files : Yes
Javascript Settings > Minify JavaScript Files : Yes
Javascript Settings > Enable JavaScript Bundling : Yes
Template Settings > Minify HTML : Yes
Stores -> Configuration -> Catalog -> Catalog
Storefront > Use Flat Catalog Category : Yes
Storefront > Use Flat Catalog Product : Yes
Stores -> Configuration -> Sales -> Sales Emails
General Settings > Asynchronous Sending : Enable
System -> Index Management
Set all indexers to “Update by Schedule” mode.
Production Mode
Let’s change the mode to Production now, Login to Magento server as Magento File System Owner and run the following code
bin/magento deploy:mode:set production
7. Varnish with SSL using HAProxy
Varnish is an HTTP reverse proxy that caches content in memory in front of a Web Server. It basically reduces the load on Apache and PHP as all the cacheable pages are managed by Varnish.
Magento 2 comes with built-in support for Varnish caching, though we can continue using Full-Page cache by Magento, but it is recommended to use Varnish because of its performance.
We have created a separate article for Magento and Varnish with SSL Support using HAProxy, Kindly check that for the step by step method.
8. PHP-FPM Tuning
We have successfully installed PHP-FPM, Let’s tune it for an optimal Magento performance.
PHP-FPM has three process managers that manages all the processing. These processes are Static, OnDemand & Dynamic.
We recommend Dynamic process manager for Magento 2
You can locate the PHP-FPM configuration file in /etc/php/7.2/fpm/pool.d/www.conf
Open the file and make the following changes
pm = dynamic
pm.max_children = 70
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 16
pm.max_requests = 2000
Please note that these are recommended changes and may require different configurations depending upon the Site Traffic, Available RAM, Virtual Machine Configuration etc.
You can use the following method to figure out the correct values
Check Avg. Memory Consumption by Single PHP-FPM Process
ps -ylC php-fpm7.2 --sort:rss
This will output the following
The column RSS contains the avg. memory usage per process in Kilobytes
Which mean our single PHP-FPM process is consuming about 81976/1024 = 80MB.
Let’s say we have approx. 7GB of available RAM on Server, So to calculate the max_children we will use the following formulae:
(1024 * 7)/80 = 102.
Let’s go with 70 max_children
Please also note that we have just setup the server so there is no traffic on it and almost no load on PHP-FPM processes. You can use Apache Benchmark to send requests to your server and see what is the average memory usage of PHP-FPM after that. Make sure you send requests to non-cached Magento pages like Account Sign Up or else our Varnish will be handing the requests and no load will be coming on PHP-FPM.
9. Conclusion
All the above recommendations and configurations are based on our years of experience working with Magento. Though we cannot guarantee that the above configuration would be ideal for all as every store has its own resources, traffic, customisations etc but this will for sure delivers you a great performance and you can notice it after comparing it with others who are not using them.
Leave a Reply