Introduction

During past couple of years we were using platforms/websites that were failing under heavy load. That got us thinking. How to create something that people can take ideas from and build upon which can handle reasonable load in reasonable expenses. For that we created a goal to handle 30,000 requests per minute in the most cost-effective way.

To handle this situation we were thinking to develop such an application with GoLang, which itself is a very efficient platform in itself. But later decided to engage with more audiences picked a challenge ourselves and set up our goal to build the application with PHP.

Challenges

We set the target to serve 30,000 requests per minute (500 requests per/sec).

Framework Selection

We choose lumen for its simplicity.

Database Selection

Most PHP applications work with MySQL database. However, we don’t need MySQL for all the cases. We chose NoSQL for this application and decided to use MongoDB.

Tweaking

Lumen is fast but not enough to serve 30K requests per minute for our application, which was supposed to be run with minimum resources. So, we added some sauce over Lumen named Swoole.

What is SWOOLE?

Compared with other async programming frameworks or software such as Nginx, Tornado, and Node.js, Open Swoole is a complete async solution that has built-in support for async programming via fibers/coroutines, a range of multi-threaded I/O modules (HTTP Server, WebSockets, TaskWorkers, Process Pools) and support for popular PHP clients like PDO for MySQL, Redis, and CURL. You can use sync or async, coroutine, fiber API to write the applications or create thousands of lightweight fibers within one Linux process. Swoole enhances the efficiency of your PHP applications and brings you out of the traditional stateless model, enabling you to focus on the development of innovative products at a high scale, brining event loops and asynchronous programming to the PHP language.

You will find more about Swoole on their official website.

Benchmark

Here is some performance benchmark for our demo application:

Machine description:

Initial load tests were done in the following configuration:

1. 2x t3.medium (2CPU/4GB Mem) instances to host API.
2. 1x t3.small (2CPU/2GB Mem)Redis cluster with 1 node.
3. MongoDB hosted in 1x t3.medium (2CPU/4GB Mem) instance.
4. Tsung hosted in GCP in 4 pods.

Load Test

Alternative

Falcon with Swoole combination could be an alternative solution. We choose Lumen for its simplicity over Falcon.

Laravel Octane is also can be a good choice.

You will find this project on Github:

API: https://github.com/vivasoft-ltd/movement-pass-api
UI: https://github.com/vivasoft-ltd/movement-pass-ui