KAHIBARO
Discord Login Register

26.1 Understanding Backend Performance

Why Backend Performance Matters

Backend performance is about how fast and efficiently your server can handle work. It affects:

Two backends that behave the same from a feature point of view can be very different in cost and user experience because of performance.

Key questions about performance:

You will see these concepts in later chapters such as caching, scaling, and load balancing. Here we focus on understanding performance at a basic, practical level.

Important: Performance is not only about speed, it is about capacity under constraints such as CPU, memory, network, and database limits.

Core Performance Metrics

Backend performance is usually described with a few standard metrics.

Latency

Latency is how long a single operation takes.

Examples:

If a request starts at time $t\_0$ and finishes at time $t\_1$, the latency is:

$$\text{latency} = t\_1 - t\_0$$

Often measured in milliseconds (ms).

Common latency statistics:

Tail latencies are very important. A service with:

feels slow to users, even though the median looks good.

Throughput

Throughput is how many operations you can process per unit time, for example:

Informally:

$$\text{throughput} \approx \frac{\text{number of completed operations}}{\text{duration}}$$

Throughput is limited by your slowest bottleneck, often the database, network, or CPU.

Latency and throughput are related but not the same. You can:

Resource Utilization

Resource utilization tells you how much of a resource is in use:

When a resource is close to 100%, it becomes a bottleneck, and performance often degrades sharply.

A simple view:

ResourceSymptom of saturation
CPUHigh CPU % on all cores, slow code
MemorySwapping, out-of-memory errors
DiskHigh I/O wait time
NetworkHigh latency, timeouts, packet loss

Concurrency and Parallelism

These two terms are often confused but describe different ideas.

In backend servers:

You can have concurrency without parallelism. For example, an async server on a single CPU core can juggle many I/O-bound requests concurrently.

The Lifecycle of a Request

To understand performance, break a request into stages. A typical web request:

  1. Client sends a request.
  2. Network transfer from client to server.
  3. Reverse proxy or load balancer receives it and forwards to your app.
  4. Application server parses HTTP and routes to the correct handler.
  5. Handler executes:
    • Reads data from cache or database.
    • Applies business logic.
    • Possibly calls other services.
  6. Response is created and sent back through the stack to the client.

A simplified time breakdown for one request:

StageTime (example)
Network (client to server)40 ms
Reverse proxy + routing5 ms
App logic (no DB)5 ms
Database query80 ms
Response serialization5 ms
Network (server to client)40 ms
Total latency175 ms

Knowing these stages helps you ask: Where is the time really going?

If you only optimize application code that takes 5 ms while the DB query takes 80 ms, you will not see much improvement.

Bottlenecks and the Slowest Part Rule

A backend system behaves a bit like a pipeline. The part with the lowest capacity limits the whole system.

Imagine:

Even if your app server is very fast, your maximum safe throughput will be around what the database can do.

Rule: Your system throughput cannot exceed the throughput of its slowest critical component.

Common backend bottlenecks:

Example: Identifying a Bottleneck

Suppose these measurements for handling one request:

ComponentLatency per request
Application code5 ms
Redis cache2 ms
Database70 ms
External API230 ms

Total is about 5 + 2 + 70 + 230 = 307 ms.

The external API dominates. Even if you reduce DB time from 70 ms to 7 ms, the total only drops to about 244 ms. Real gains will come from:

This idea is closely related to Amdahl’s Law, which says that speeding up a small part of a system gives a limited overall improvement.

Performance, Capacity, and Scalability

Performance is not only about speed for a single request. It is also about what happens under load.

Response Time under Load

As load increases, response time usually looks like this in practice:

You might see:

Requests per secondAverage latencyError rate
5040 ms0%
10060 ms0%
200120 ms0%
400500 ms2%
8002000 ms20%

Understanding where this “knee” occurs helps with capacity planning.

Vertical and Horizontal Scaling

Scaling is how you increase capacity when traffic grows.

Each approach has tradeoffs, which you will explore later in the course. Here the main idea is:

Performance Tradeoffs

You rarely improve everything at the same time. You trade:

Common tradeoffs:

Caching vs Freshness

Caching can make responses very fast by reusing previous results, but:

Precomputation vs Flexibility

Precomputing statistics or denormalizing data can make reads fast, but:

Simplicity vs Performance

Highly optimized code or architecture can be harder to read and maintain. For most beginner projects:

Guideline: Start with clear and correct code. Measure. Then optimize actual bottlenecks instead of guessing.

Measuring and Observing Performance

To improve performance, you must measure it. Guessing is almost always wrong.

Key Things to Measure

At minimum, for each endpoint or operation:

Later chapters cover detailed logging and monitoring tools such as Prometheus and Grafana. For now, focus on the idea that these measurements drive your decisions.

Simple Timing Example in Python

For a beginner-friendly illustration:

python
import time
def handle_request():
    start = time.perf_counter()
    # Simulate application work
    time.sleep(0.05)  # 50 ms
    end = time.perf_counter()
    latency_ms = (end - start) * 1000
    print(f"Request took {latency_ms:.2f} ms")
handle_request()

This is not production-grade monitoring, but it shows how you can measure time to understand your code’s behavior.

Common Performance Patterns in Backends

Several patterns appear again and again when you examine backend performance.

Small, Fast Operations vs Large, Slow Ones

It is usually better to do:

You will see database optimization in later chapters, but the performance mindset is:

Synchrony vs Asynchrony

Synchronous (blocking) code:

Asynchronous (non-blocking) code:

Async is especially helpful for I/O-bound workloads such as:

This is covered in more detail in the asynchronous programming chapters. For performance understanding, the main point is:

Queues and Background Jobs

If some work is slow but not needed immediately in the response, you can:

Example:

This improves perceived performance for the user, even if total server work is the same.

Performance Mindset for Beginners

As you build backend projects, keep these habits:

  1. Break down requests
    Ask: which parts touch the database, external APIs, filesystem, CPU?
  2. Expect bottlenecks
    Assume something is limiting you: DB, CPU, or network. Try to identify it.
  3. Measure first
    Do simple measurements before rewriting code.
  4. Optimize the right thing
    Spend effort on operations that are frequently called or very slow.
  5. Watch real behavior under load
    A function that looks fast for one call might behave badly with 1,000 concurrent users.

These ideas will connect directly to later chapters on asynchronous programming, database optimization, caching, scalability, load balancing, and performance testing.

Views: 7

Comments

Please login to add a comment.

Don't have an account? Register now!