Python Web Application Becomes Unresponsive When Handling Concurrent Requests

Hi All,

I am working on a Python-based web application for my website and have been running into an intermittent performance issue where the application becomes unresponsive when several requests arrive within a short period of time. Under normal traffic, the website behaves as expected and individual pages load without any noticeable delay, but when multiple users access the application around the same time, some requests begin taking significantly longer to complete and eventually appear to hang. The issue is not limited to one particular browser or user session because I have been able to observe the same behavior from different sessions when the application is under increased request activity. What makes it particularly confusing is that the application does not consistently fail at a specific request count; sometimes a small burst of requests is enough to reproduce the slowdown, while at other times the website continues responding normally despite similar activity. Once the application enters this state, new requests can remain pending much longer than expected even though the server itself does not appear to be completely unavailable. I am trying to determine whether there is something in the way my Python application handles concurrent requests that could cause requests to wait for one another instead of being processed independently.

The application performs several normal backend operations before returning a response, including reading information needed to construct the requested page and processing some application logic. With a single request, these operations complete normally, but the response time becomes unpredictable when multiple requests are being handled at the same time. I initially suspected that the problem might simply be related to the amount of traffic, but the behavior seems more closely connected to concurrent request handling than to sustained high traffic. For example, a number of requests arriving close together can produce a noticeable queue even though the same number of requests spread over a longer period completes without difficulty. I am using Python for the backend and want to understand whether the application could be holding execution in a way that prevents other requests from progressing efficiently. I have been reading about Python’s concurrency model and understand that the correct solution can depend heavily on whether the application is using synchronous code, threads, asynchronous code, or the particular web server configuration used to run it. I therefore do not want to assume that simply adding more workers or threads is the correct solution without first identifying what is actually causing the requests to become blocked.

I have already tried reproducing the behavior with controlled testing rather than relying only on occasional reports from the live website. When I send requests individually, the application generally responds normally, but when I send several requests concurrently, the response times can increase considerably. I have also monitored the application while reproducing the problem and noticed that the server remains running rather than immediately crashing or exiting. This makes me think the issue may involve requests waiting on some operation rather than a straightforward application failure. I am particularly interested in understanding how I should investigate this from the Python side. For example, would it be useful to capture thread information, inspect active tasks, add timing around potentially blocking sections of the application, or use Python’s profiling and debugging tools while the application is under concurrent load? I want to avoid randomly changing concurrency settings because that could potentially hide the underlying problem without explaining why the application becomes unresponsive in the first place. A clear way to identify which part of the Python request lifecycle is holding up concurrent requests would be much more useful.

One area I am currently investigating is whether a synchronous operation inside the request-handling path could be preventing other requests from progressing efficiently. Some parts of the application perform operations that may take noticeably longer than simple Python calculations, and I am wondering whether one of these operations is occupying the execution path for longer than expected whenever several users reach the same endpoint at approximately the same time. If the application is waiting synchronously for an operation to finish before it can continue, I would like to understand how that interacts with the concurrency model of the Python web application. I have considered whether converting certain parts of the application to asynchronous code would help, but I am not sure that changing the architecture is justified until I can identify whether blocking behavior is actually responsible for the observed delays. I am also unsure whether the issue would be better addressed at the Python application level or by configuring the web server to handle requests differently. Since the website works normally under light activity, I would prefer a solution that improves the application’s handling of concurrent requests rather than simply increasing resource limits and hoping the symptoms disappear.

I am also trying to collect enough information to distinguish between a Python execution issue and a request-processing configuration issue. During normal operation, the response time is relatively stable, but during the problematic periods the number of active requests appears to increase and some requests remain pending much longer than normal. The application process itself continues running, which makes a simple crash unlikely. I would like to know what information experienced Python developers would normally collect in this situation before making architectural changes. For example, should I record the time each request enters and leaves the application, inspect the Python process while requests are stuck, look for blocked threads or tasks, or create a small reproducible example that simulates the same concurrent request pattern? I am especially interested in a debugging approach that can reveal whether requests are waiting on Python code, an external operation, or the web server’s request-handling mechanism. If there are particular Python tools or standard-library techniques that are useful for diagnosing intermittent request stalls, I would appreciate recommendations on where to start.

Has anyone dealt with a Python web application where individual requests work normally, but a burst of concurrent requests causes some requests to remain pending and eventually makes the website appear unresponsive? I am mainly looking for advice on how to identify the actual bottleneck before changing the application’s concurrency architecture. The behavior seems to depend on multiple requests being processed at roughly the same time, while the same functionality works correctly when requests are handled individually, so I suspect the way concurrent requests interact with the Python application is important. I would appreciate guidance on what measurements or diagnostics I should collect, which parts of the Python request lifecycle I should inspect first, and how to determine whether the problem is caused by blocking application code or by the way the Python web application is being served. My goal is to make the website reliably handle concurrent visitors without simply masking the problem by increasing arbitrary limits. If there is a standard Python debugging workflow for investigating intermittent request stalls like this, I would be grateful for suggestions on how to apply it to a production-style web application while keeping the investigation focused on this one concurrency issue. Very sorry for long post!