As your business grows and the number of users for your site increases, your web infrastructure might become a bottleneck. If this happens, then you need to scale your web infrastructure, including any web or database servers and online file storage services.
Scaling the AWS infrastructure that hosts your PHP application is a powerful way to achieve robustness, fast load times, and high availability, even in the face of sudden spikes in traffic. In this article, we talk about some of the most important concepts when scaling PHP applications on AWS, including some of the most common PHP frameworks, how feasible they are to scale on AWS, and what techniques can be used to scale them.
Before you begin scaling
Before you begin scaling, it is important to follow PHP best practices with respect to performance and development practice. Optimizing performance is important because a performance bottleneck at the level of your application code will hold you back when making improvements to your AWS infrastructure. Good development practices are important to ensure that you have the right balance of development speed, code legibility, and flexibility in your application.
In addition to ensuring that you have optimal code and good development practices, it is beneficial to understand some of the benefits and drawbacks of your choice of PHP framework as you prepare to scale. Frameworks save you having to make major architectural decisions for your project, but they may come at a cost. The major benefits of most frameworks include more robust code, more out-of-the-box functionality, and faster development speed. However, one cost to using frameworks is that they often have fixed architectural patterns, and this inflexibility could lead to difficulties when you later want to integrate your app with AWS.
Given these tradeoffs, it is important to choose which framework you will use — if any at all — and how it will impact your scaling decisions later on. The most popular PHP frameworks are CodeIgniter, Symfony, and Laravel. CodeIgniter is a lightweight model-view-controller (MVC) framework, meaning it has very few packages and is relatively malleable. This means that you can easily replace core parts of the framework to make the system work the way you need.
Symfony is a set of decoupled and reusable components, and while the core part of it is not a framework per se, there is an MVC framework implemented on top of these components. However, using this framework is optional. Laravel, by contrast, is a full MVC framework, but it is also highly customizable. It is currently the most popular PHP framework. Much of its popularity likely has to do with the Laravel community’s commitment to high-quality explanations and tutorials in order to reduce Laravel’s learning curve.
Shifting your infrastructure to AWS
If you switch to hosting your entire infrastructure on AWS, you can take advantage of the many options it provides to support scaling. It’s a good idea to separate the hosting of different parts of your PHP application into different services in AWS before you begin scaling it. This will allow each component to be scaled on an as-needed basis without needlessly spending money on scaling resources that aren’t causing a bottleneck.
Distributed AWS architecture
AWS encourages a distributed architecture, meaning that various components of your web infrastructure — like applications, databases, and caches — are split into different services. These services are usually hosted on separate servers. One key advantage to this architecture is the ability to scale different components independently, which can save money and prevent idle resources. Some of these key AWS services are:
- Elastic Compute Cloud (EC2): Web servers (known as EC2 instances) that host and run application code.
- Relational Database Service (RDS): Your database server instances that handle database queries from your application. If you’re using a standard relational database, you should make use of this service.
- ElastiCache (with Redis or Memcached): Your object cache, which allows you to reduce load on your RDS instances and improve speed by caching the results of database queries.
- Simple Storage Service (Amazon S3): Your file store, which can serve static files to your application.
- Simple Email Service (SES): This handles any emailing required in your application, since EC2 instances aren’t allowed to handle emailing.
- Elastic Kubernetes Service (EKS): This allows you to run an AWS-hosted version of Kubernetes so you don’t have to install and configure it yourself. Kubernetes is a system used to deploy and manage containerized applications. This is an excellent way to reliably and repeatedly deploy large applications that are constructed from many services or microservices.
Integrating frameworks with a distributed architecture
Each of the options for your application architecture and framework will have different tradeoffs when integrating with the distributed AWS architecture.
CodeIgniter’s MVC architecture is only loosely enforced — and, most importantly, the “model” part is optional. Your application’s model might contain things like user sessions and caching, so it could cause a headache if these were tightly bound to your application, as this would mean they are also tied to your single EC2 instance. This makes things difficult when you later want to scale to multiple EC2 instances.
Symfony is a set of decoupled components and an optional MVC framework implemented on top of these components, which means you can choose whether or not to adopt the MVC framework. This is particularly beneficial when integrating with AWS, since you can still maintain flexibility in the architecture while still taking advantage of Symfony’s components, which are designed to make development tasks easier.
Laravel uses a full MVC architecture, which means that more steps may be required to split out the various parts of your application into different AWS services. However, Laravel is highly customizable, so there are still many options to scale on AWS with Laravel. In our article, Optimizing and Horizontally Scaling Laravel on AWS, we go into depth on how to accomplish this.
Another option is to use no framework at all. This allows you maximum flexibility, as you have full control over your architecture and can develop a distributed architecture more compatible with AWS from the beginning. The downside is that you would have to take decisions and responsibilities usually delegated to frameworks. However, the no-framework approach doesn’t mean reinventing the wheel as it is still possible and advisable to rely on existing libraries.
Scaling web servers
After your PHP application is built using your framework of choice, the standard AWS scaling solutions come into play, particularly vertical and horizontal scaling. Vertical scaling is increasing the performance (CPU, RAM, network bandwidth, etc.) of a single EC2 instance (these are your virtual servers hosted on AWS). Horizontal scaling is adding additional EC2 instances as needed, with a load balancer spreading traffic across your different instances. After the specifications on your single instance have reached their maximums, the only reliable way to scale further is through horizontal scaling.
AWS has some excellent features that make horizontal scaling easy to implement, even for applications with constantly changing loads. AWS allows users to define Auto Scaling groups, which are groups of EC2 instances that can be scaled up or down automatically according to certain rules. For example, if web traffic increases above a certain threshold, the group adds more EC2 instances, and if traffic decreases, it removes some instances. This allows your site resources to scale up or down with demand, eliminating performance bottlenecks and expenses for idle hardware.
Although Auto Scaling groups simplify the horizontal scaling of an application, it is essential to start with a single node when optimizing your PHP-FPM (FastCGI Process Manager) parameters. PHP-FPM is already a well-optimized protocol for your web server to interact with your PHP application. However, fine-tuning the configuration parameters of this can lead to even greater performance benefits. When using Auto Scaling groups, you can be a little more aggressive in optimizing your PHP-FPM parameters for a single EC2 instance within your group. Because tuning these parameters is complex and time-consuming, Logicata has created a tool called PhpBoost, which analyzes the system for a specified time period and saves the recommended PHP-FPM settings to an output file. To use the PhpBoost tool with an Auto Scaling group, ensure you add an
-a parameter when running the tool, to indicate that your instance is part of an Auto Scaling group.
Scaling database servers
After you’ve successfully scaled your EC2 instances horizontally, a single database instance (a server on AWS just for hosting a database) can become the new bottleneck in your system, as your many EC2 instances struggle to read from a single database instance at the same time. You can alleviate this by horizontally scaling your database instances, which — similar to horizontally scaling an EC2 instance — means adding extra database servers as needed.
When developing a PHP application, you will likely be using a popular database such as MySQL, PostgreSQL, SQL Server, SQLite, or, if you’re using a NoSQL database, MongoDB. These databases are generally well supported by the major PHP frameworks, as listed in the documentation for Laravel, Symfony, or CodeIgniter. Laravel and CodeIgniter only support relational databases based on SQL, while Symfony — through PHP’s Doctrine ORM — supports these as well as NoSQL databases like MongoDB.
AWS supports many SQL database options through Amazon Relational Database Service (RDS). You can manually scale your RDS instance to have up to five read replicas. There is also an option to upgrade to Amazon Aurora, which allows you to scale up to fifteen read replicas and also offers auto-scaling capabilities. AWS also supports the scaling of NoSQL databases through DynamoDB.
Putting it all together
Before scaling, it’s best to ensure that your PHP application is well optimized, in order to scale successfully and cost-effectively. Once you’ve moved your PHP application to AWS, you are ready to split your application across the many distributed services that AWS provides, such as EC2, RDS, S3, SES, etc. Adopting this distributed architecture will make scaling your application much more feasible. Vertical scaling is easiest to implement and best to start with, but if your site is successful, you will eventually have a need for horizontal scaling. Logicata is happy to brainstorm ideas for how to best scale your specific PHP application on AWS, so be sure to reach out.
Here’s more from our blog on PHP best practices
AWS Best Practices on PHP
Scale and Optimise Laravel on AWS