Sep 29, 2025Web Applications

Python application slowing down? What to check before scaling

When a Python application slows down under load, start by measuring a specific user task. Find out whether the time is spent retrieving data, running calculations, waiting for another system or displaying the result. You can then compare the cost of improving the application with the cost of adding server resources.

If delays are already preventing orders from being accepted or stopping your team from working, the provider should stabilise the service first. A temporary increase in resources may be part of that response. Agree how its effect will be checked and when a longer-term decision will be made, so that an emergency measure does not become an ongoing expense without a clear reason.

What exactly is slow for the user?

Turn “the system is slow” into a description of a task: opening the order list, saving a form, finding a product or preparing a report. Record when the problem occurs, who it affects and whether it appeared after an application change, an increase in traffic or growth in the amount of data. This helps reproduce the situation, although two events happening at the same time do not establish a cause.

Ask the provider to trace that task from the initial click to the result on screen. Some of the delay may come from the browser or network connection. If the server itself is taking time, the investigation needs to distinguish between the application, the database and external services. Otherwise, you could pay to expand a part of the system that is not causing the problem.

The report should cover response times, traffic, errors and resource utilisation. These are four core areas described in the Google SRE monitoring guide. The result must also be correct: a fast error response does not mean an employee has completed their task.

How many requests per second does the application need to handle?

A request is a single call to the server, such as fetching data for a table. One user action may require several calls. Requests per second, or RPS, therefore measures neither the number of users nor the number of completed orders.

Capacity planning needs a picture of actual usage: how many people work at the same time, what they do and how the load changes at peak times. A test that returns a simple “server is running” message does not tell you how many orders can be saved while also checking permissions, stock levels and connections to other systems.

When a provider presents a test result, ask what was measured. It should be clear whether the result covers one application process, one server or several servers combined; which data and functions were tested; how many operations succeeded; and how long responses took. You also need the cost of the environment used for the test. Without that context, an RPS figure offers little help with budget decisions.

What should you improve before adding servers?

Measurements should point to specific work. The Django performance guide recommends defining the goal and measuring the application first. A change of tools or software version needs to be tested in the system concerned.

Retrieving and processing data

For a slow order list, check how much data the application retrieves and how often it queries the database. It may load the entire history when the user sees only a small part, or issue a separate query for every row. Django’s database optimisation guidance covers measuring queries, avoiding unnecessary reads and choosing indexes: structures that help the database find data.

Before accepting the fix, ask the provider to identify the data retrieval or calculations they changed and demonstrate the effect on the same user task.

Reusing results

A cache stores data or calculated results so they can be reused. It can help when many people read similar data that is expensive to retrieve or calculate each time. You need to agree how long a result may remain out of date and when it will be refreshed. Microsoft’s cache-aside pattern guide explains these limitations.

A historical report may tolerate a different update delay from a product availability check before a sale. Decisions about caching therefore need to account for the consequences of showing an old value. Costs also include maintaining the additional service and handling cases where a result has to be generated again.

Moving tasks that can wait into the background

A large data export can run in the background: the user requests it and receives the file when it is ready. This makes sense if they do not need the result immediately. They need to be able to see its status, learn about errors and retry safely.

Accepting a task into a queue quickly does not mean completing it quickly. If tasks keep arriving faster than they can be processed, the queue will grow, increasing the wait. When checking this change, measure the time from the request to the finished result as well. Tasks that need immediate confirmation, such as confirming that a reservation has been saved, require a separate agreement on how they will work.

When does adding server capacity make sense?

Adding resources makes sense when measurements show that a lack of capacity is limiting the operations you need. Options include a more powerful server or additional copies of the application with traffic distributed between them. Check whether the rest of the system can handle the increased load.

If every copy uses the same overloaded database, adding more copies does not remove that constraint. Similarly, more processing power on the application server will not, by itself, shorten the wait for a slow external service. Test the complete process you need to confirm the potential benefit.

Before approving a quote, compare the options against the same goal: how quickly the application should perform the agreed tasks, with how many errors, under the expected traffic. Alongside implementation costs, include monthly running costs, the work required to operate additional services and a way to reduce spending when traffic falls. Automatically adding resources also requires an agreed spending limit and a response when that limit is reached.

Do you need to replace Django or Flask with FastAPI?

The fact that an application uses Django or Flask is not, on its own, a reason to rewrite it. These are tools for building web applications. Moving to another tool, such as FastAPI, should address a measured limitation and account for the cost of rebuilding features, testing and ongoing maintenance.

Asynchronous processing is often suggested: the program can handle other tasks while it waits for data. This makes use of waiting time, but does not in itself speed up intensive calculations. Running those calculations simultaneously across several processor cores is a different mechanism and requires the work to be divided appropriately. The FastAPI documentation explains the distinction.

Django also supports asynchronous code, although the benefits depend on how the application is deployed and which libraries it uses. Start by checking what the existing system can do. If rebuilding part of it proves worthwhile, the scope should follow from the measurements rather than a technology popularity ranking.

How do you check the result and sign off the work?

Before any changes, agree on a test scenario: user tasks, data volume, concurrent traffic and the conditions under which connections to other systems operate. Repeat it after the changes in a comparable environment. The k6 load testing guide recommends reproducing normal user activity and observing the system long enough to see how it behaves under load. Your business may also need a separate scenario for a sales peak.

Do not sign off the work based solely on the average response time. One useful measure is p95 for successfully completed operations: 95% of them finish within the reported time. The rest may take longer, so assess errors and the longest delays alongside it. Time targets should reflect the task: saving a form and preparing a large report may have different requirements.

The report used to sign off the work should show results before and after the change, the conditions of both tests, remaining constraints and ongoing costs. For caching, also check how the system works when no results have been stored. For background tasks, check how long users wait for completion. Agree who will respond if performance deteriorates after deployment and how to return to the previous version.

For an initial discussion, bring a description of the affected tasks, examples of when the problem occurred and information about expected traffic growth. If you are commissioning development and maintenance of an existing application, start by agreeing on an investigation, a proposed scope of work and a way to verify the result. This gives you a basis for deciding which change is worth paying for.

How could this work in your business?

Have a question about the article? Tell us about your situation and what you want to change. We’ll discuss how the ideas could apply to your needs and constraints.

After reading your message, we will follow up with questions and suggest a conversation about scope and pricing.

You can also call us directly.

Loading form…

You can also email us directly: office@softwarelogic.co