encode / uvicorn

An ASGI web server, for Python. 🦄
https://www.uvicorn.org/
BSD 3-Clause "New" or "Revised" License
8.41k stars 730 forks source link

Issue: Increased CPU and Memory Overhead with Uvicorn Multi-Processing #2466

Open jahnavisana2812 opened 1 week ago

jahnavisana2812 commented 1 week ago

Initial Checks

Discussion Link

https://github.com/encode/uvicorn/discussions/2463

Description

We were previously using Gunicorn with Uvicorn workers for our application. Recently, we decided to shift to using Uvicorn directly, due to improvements in Uvicorn.

However, while Gunicorn used to spawn 5 sub-processes for handling requests, Uvicorn now creates 5 multiprocessing spawn processes using Python's multiprocessing library. This results in noticeable CPU and memory overhead, which we didn't experience with Gunicorn workers.

When running Uvicorn with a single worker, the overhead is not present, but increasing the worker count leads to the issue. I have attached screenshots of our monitoring data, which clearly show the difference in resource usage between configurations.

Is this behavior expected with Uvicorn, or is there a possible fix for reducing the overhead in future updates? Any guidance or suggestions would be appreciated.

With default worker=1

Screenshot 2024-09-20 at 4 20 18 PM

with workers=5

Screenshot 2024-09-20 at 4 20 39 PM

Example Code

uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 5

Python, Uvicorn & OS Version

Running uvicorn 0.30.6 with CPython 3.11.9 on Ubuntu
abersheeran commented 2 days ago

The difference is that gunicorn uses prefork mode to spawn multiple processes, while uvicorn's multi-process mode uses a more general mode for compatibility with Windows systems.

If you are running on a server with limited performance, using gunicorn's prefork mode would be a better choice.

Kludex commented 2 days ago

But shouldn't it be constant at some point anyway?

abersheeran commented 2 days ago

I'm not sure if the growth in the graph he gave is due to requests, but if you run five processes and don't request it, it shouldn't cause a continuous increase in CPU.

jahnavisana2812 commented 23 hours ago

It seems like fluctuating requests are leading to increased request rates, which, in turn, are spiking CPU usage. Here's a comparison between two of my test environments: one with a single worker and another with five workers. The environment with five workers shows many ups and downs in CPU usage, whereas the one with a single worker is more stable. However, I can't limit my workers to just one. Could you suggest a solution for better handling this situation?

Workers=1

Screenshot 2024-10-01 at 11 09 15 AM

Workers=5

Screenshot 2024-10-01 at 11 08 48 AM