Practice: Capacity planning and performance

Generated by Claude through GigAI (karthik446/gigai-learning-center 4c0cb514) on 2026-10-13.

Main tool: Locust · Locust lets you write the demand model as ordinary Python user classes and then push the same file from a laptop smoke run to a distributed, headless, pass-or-fail run, which is the full capacity planning loop of this lesson. · Alternatives: k6 scripts tests in JavaScript and runs them from a single Go binary with built-in thresholds, JMeter drives XML test plans from a GUI on a thread-per-user model, Gatling writes simulations in a Scala, Java or Kotlin DSL with rich static reports, and Vegeta or wrk fire a fixed request rate at one endpoint with no user-behaviour model, whereas Locust describes users in plain Python and scales out through a master and workers.

Every step links into the tool's own documentation; links were checked on 2026-10-13 · version 1

Setup (one time)

  • 1. Install Locust into a fresh Python virtual environment and check that the locust command reports its version.

    Every later step runs through the locust command, and a dedicated environment keeps the version you measure with fixed.

    Explained in: Installation — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: Running the locust command with the version flag prints a version number.

  • 2. Raise the maximum number of open files for your shell before generating any load.

    Each simulated user holds connections, and a low limit makes the load generator fail first, which looks like a capacity limit in the target but is not one.

    Explained in: Installation — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: Your shell reports an open files limit well above the number of users you plan to simulate.

  • 3. Start a small HTTP service you own on your laptop, with a fixed CPU and memory allowance, and note its address as the host Locust will target.

    Capacity numbers only mean something for a target of known size, and you must only load test systems you control.

    Explained in: Writing a locustfile — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: The service answers a request in a browser and you have written down the base address to use as the host.

Steps

  • 1. Write a minimal locustfile with one user and one request, start Locust, and run a small test from the web interface.

    This is the shortest path to seeing requests per second, response times and failures for your own service. It gives you a baseline before you model anything.

    Explained in: Your first test — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: The web interface shows live request rate and response time charts for your endpoint with zero failures.

  • 2. Write your demand forecast into the locustfile by choosing a wait time that makes each user produce the per-user request pace you expect, including a constant throughput variant.

    A resource plan starts from a demand model, and the wait time is where peak users and requests per user become a concrete arrival rate. Without it the user count on the screen means nothing.

    Explained in: Writing a locustfile — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: With a fixed number of users, the total request rate in the statistics matches the rate you calculated on paper within a few percent.

  • 3. Write several tasks with weights that match the real traffic mix, for example many reads, fewer writes and a rare expensive call.

    Capacity depends on the mix as much as the volume, because one heavy endpoint can consume most of the resources. Weighted tasks make the test load look like production load.

    Explained in: Writing a locustfile — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: The per-endpoint request counts in the statistics table follow the ratios you set in the weights.

  • 4. Write response checks that mark a request as failed when the status, the body or the response time breaks your service level target.

    A server under stress often returns fast errors or slow successes, and both would otherwise count as healthy throughput. The sustainable limit is the load at which the checks still pass.

    Explained in: Writing a locustfile — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: A deliberately broken or slow endpoint shows up in the failures tab with the message you wrote.

  • 5. Run the same test without the web interface for a fixed duration and save the statistics as CSV files, once per instance size.

    Saved results are what let you compare one run with another instead of trusting memory. They are the evidence behind the per-instance number in your plan.

    Explained in: Configuration — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: Two sets of CSV files exist on disk and you can state the difference in throughput and high-percentile latency between them.

  • 6. Write a custom load shape that raises the user count in steps and holds each step, then run it against one instance to find where latency bends upward.

    The knee of the curve is what one instance can sustain, and dividing forecast peak demand by it, plus headroom, gives the instance count. A stepped shape makes the knee visible and repeatable.

    Explained in: Configuration — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: You can name the step at which response time or failures rise sharply and write down the instances needed for peak plus headroom.

  • 7. Compare the stepped run against the checks in the request rate guide to decide whether the limit is in the load generator or in the system under test.

    Finding the bottleneck starts with ruling out your own tooling, since a saturated Locust process flattens throughput exactly as a saturated server does. Only then is it worth looking at the target's CPU, memory, connections or database.

    Explained in: Increasing the request rate — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: You have one written sentence naming the limiting resource, backed by the Locust process CPU staying below its limit while the target's resource is saturated.

  • 8. Create a configuration file that pins the host, user count, spawn rate, run time and CSV prefix, and commit it next to the locustfile.

    A test whose parameters live in shell history cannot be repeated by a colleague or by a pipeline. A committed configuration file turns the run into a versioned artifact.

    Explained in: Configuration — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: Running the locust command with no extra options reproduces the earlier headless run and writes the same set of CSV files.

  • 9. Run Locust as one master and several workers with Docker Compose on your laptop, and repeat the stepped test.

    One Python process uses one core, so real load needs several workers. Containers also pin the Locust version so the result is reproducible on any machine.

    Explained in: Running in Docker — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: The workers tab lists every worker as connected and the peak request rate the generator can produce is higher than with a single process.

  • 10. Configure the headless run to exit with a failing code when the failure ratio or a response time percentile breaks your budget, and run it as a pipeline job.

    Capacity regresses silently as code changes, so the check must run on every change and fail by itself. An exit code is the contract a CI system understands.

    Explained in: Running without the web UI — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: The job passes against the healthy service and fails with a non-zero exit code when you lower the service's CPU allowance.

  • 11. Deploy the Locust operator on a local cluster such as kind or minikube, run the test as a cluster resource, and send a sudden spike shape at a target scaled by a HorizontalPodAutoscaler.

    Autoscaling reacts only after metrics are scraped and new pods become ready, so a spike faster than that delay is served by the old replica count. Watching the spike tells you how much standing headroom autoscaling cannot replace. No paid cloud is needed.

    Explained in: Kubernetes Operator — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: You can state the seconds between the start of the spike and the new replicas taking traffic, and the failures or latency seen in that window.

  • 12. Write event hooks that record the worker count and the final statistics and set the process exit code, then run the full distributed, headless, stepped and spike test on the local cluster as one production-like capacity check.

    A production-like run must prove that the load was really generated and must judge itself without a person watching charts. Event hooks are where Locust lets you add those guarantees in code.

    Explained in: API — Locust 2.46.8.dev0 documentation (docs.locust.io), checked 2026-10-13

    Done when: One command runs the whole test on the cluster, logs the worker count and the verdict from your hooks, and ends with a pass or fail exit code you can trace to a stated budget.