Preventing Application Hangs with uWSGI Master Mode and Harakiri
Prevent unresponsive Python workers by implementing uWSGI master mode and harakiri timers to automatically detect and restart stalled processes.
06 Sept 2025, 22:42 UTC

The most common cause of Python web application instability is the 'zombie' worker—a process that remains alive but becomes unresponsive to new requests. Without a supervisor mechanism, these workers consume memory and connection slots until the entire application stops accepting traffic. To ensure high availability, you must enable uWSGI master mode and configure a harakiri timer to automatically reap and replace stalled processes.
When master = true is enabled, uWSGI spawns a supervisor process. This process does not handle web requests itself; instead, it monitors the worker pool. If a worker crashes or is manually killed, the master detects the exit code and immediately forks a new replacement to maintain the desired process count.
Configuring Stable Workers
To implement a resilient environment, use the following .ini configuration as a baseline. This setup focuses on memory management, leak prevention through recycling, and protection against hung requests. These settings assume a Linux environment running uWSGI v2.0+.
[uwsgi] # Enable the supervisor process for worker management master = true # Define the number of worker processes (typically match CPU cores) processes = 4 # Restart workers after 5000 requests to mitigate memory leaks max-requests = 5000 # Force kill a worker if a request exceeds 60 seconds harakiri = 60 # Log detailed information when harakiri triggers harakiri-verbose = true # Run as a non-privileged user for security uid = www-data gid = www-data
The Harakiri Mechanism
The harakiri setting acts as a watchdog timer. When a worker starts processing a request, a timer begins. If the request does not complete within the specified seconds, the master process sends a signal to the worker to terminate it. This prevents a single blocked database query or an infinite loop from permanently occupying a worker slot.
This is critical for synchronous frameworks like Django or Flask. Without harakiri, a few slow endpoints can eventually consume all available workers, leading to a total service outage where the server returns 504 Gateway Timeouts because no workers are available to accept the socket.
Verifying Worker Recovery
To verify that your master process is correctly managing workers, you can simulate a failure. Run these commands on your application server with sudo or root permissions:
- Identify the process ID (PID) of one of your workers:
ps aux | grep uwsgi - Manually kill that worker process:
kill -9 <worker_pid> - Monitor the uWSGI logs. You should see a message indicating the worker died, followed immediately by the master spawning a new worker with a new PID.
To test the harakiri timer, create a temporary route in your application that sleeps longer than your configured limit:
# Example in Flask for testing
@app.route('/test-hang')
def hang():
import time
time.sleep(90) # Exceeds the 60s harakiri limit
return "This should not be reached"
Access this route and check your logs after 60 seconds. You should see a "harakiri timeout" message and the worker process will be restarted by the master.
Limitations and Common Pitfalls
- Aggressive Timers: If your application handles legitimate long-running tasks, such as large file uploads or complex PDF generation, a 60-second limit will kill these valid requests. Set the limit significantly higher than your longest expected valid request.
- Memory Exhaustion: While
max-requestshelps with leaks, settingprocessestoo high relative to your server's RAM can trigger the OS OOM (Out of Memory) killer, which may kill the master process itself. - Master Mode Dependency: Never disable
master = truein production. If a worker hits a segmentation fault without a master process, that worker slot is lost permanently until the entire service is manually restarted.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.