Moving From Nginx+FPM to Swoole Has Increased Our PHP API Performance by 91%
Appwrite 0.7 was just released last month with a lot of new features. One of the biggest features we released was our internal switch from a stack using Nginx + PHP FPM to using Swoole as our underline HTTP server.
In Appwrite, we build an open-source, free alternative to Google’s Firebase, which you can host on your own on any infrastructure. Our stack is composed of a set of Docker containers using a micro-services architecture, allowing us to scale and debug individual components composing our backend API quickly. Using our backend API, developers get a much better starting point for new web, mobile, or Flutter projects. Our project basically offers a ready-to-use Auth, Storage, Database, Cloud Functions, and other standard APIs any app requires to handle users, permissions, and data.
How We Use Swoole 👩💻👨💻
Swoole is a high-performance, scalable, concurrent TCP, UDP, Unix Socket, HTTP, WebSocket services with PHP and easy-to-use Coroutine fiber API. Using Swoole, we have a single multithreaded process running our HTTP server, which allows our HTTP request to share memory across multiple users. Using that approach, we can hold persistent DB connections and avoid reinitializing our app for every user from scratch, which helps us utilize memory and CPU much better.
On top of that, Swoole also allows us to use Coroutines. Swoole Coroutine is similar to Coroutine in other languages or frameworks. Swoole creates one Coroutine for each request and schedules mainly based on the IO status of each request. Swoole also comes with built-in Redis, MySQL, AND Postgres async clients allowing us to push performance even farther.
Using Swoole as our web server is also a much healthier approach when designing a system to work in a microservices architecture like ours. Instead of having one container with Supervisord to manage all Nginx, FPM, and PHP process running altogether in the background, each of our Docker containers has one single process as an entry point which is much easier to scale, debug and monitor. You can use Nginx and PHP on separate containers, but don’t feel native to Docker and has extra overhead.
Benchmarks 🧪⚙️
To illustrate the improvements, we have benchmarked various scenarios against version 0.6.2 and version 0.7.0. We performed requests to multiple endpoints of Appwrite to read and write data. All requests were made to endpoints that require authentication and conduct abuse control, functions that also benefit from these improvements.
Both tests have been performed on the same single node hardware and are not designed to show Swoole max performance capabilities but focus on the difference from our older version. The following results are for 5 minutes of load and stress testing with 500 concurrent clients using K6.
Version 0.6.2
As can be seen, only 98% of all requests were successful. The rest resulted in a timeout due to overload.
Version 0.7
With version 0.7, things look quite different. Not only were all requests successful, but there were almost twice as many requests with, on average, around half the response time.
Conclusions 🤔
Considering all factors together, this signifies a total increase in performance of ~91%. With Swoole, our stack is now way faster and easier to maintain. Actually, online benchmarks demonstrate that Swoole+PHP is beating popular Node.js and Python alternatives with ease and is not far behind compiled languages like GO.
This performance boost is part of a series of steps we are taking to ensure developers can take full advantage of their Appwrite servers. We plan to share more data and insights from both the development process and Appwrite benchmarks with upcoming new versions.
This is also a good opportunity to thank the entire Swoole team for their support and help in our migration process, which was surprisingly simple and fast. It literally took us a couple of days to get to a first working version of our entire API.
What’s Next? 🚀
If you are interested in [Appwrite](https://appwrite.io), you can check some of our getting started guides for Web, Flutter, or Server, and visit our Discord community where we chat about Appwrite non-stop with over 1,300 fellow Appwriters.
If you’re excited about these improvements, you should probably also track what is coming up next by visiting our Github projects. You can also ask for new features on our Github issues and go over our upcoming feature specs on the Appwrite RFCs repository.