You want to know what happens to your API when 80 users hit checkout at the same time. With Locust, that usually starts with Python: create a HttpUser, add @task methods, build a locustfile.py, configure dependencies, and debug token reuse before you even get to the load test.
Locust is a solid code-first load testing tool. But if your goal is simply to answer “does my login endpoint survive 100 concurrent users?”, writing and maintaining a Python harness can be unnecessary overhead. With Apidog, you can run a performance test from an existing API test scenario, set virtual users and duration, then watch throughput, response time, and errors in real time. No locustfile, no pip install, no Python setup.
What Locust does well
Locust is an open-source load testing tool written in Python. You define user behavior as code. A virtual user is a Python class, and each action is a method decorated as a task.
A basic locustfile.py looks like this:
from locust import HttpUser, task, between
class CheckoutUser(HttpUser):
wait_time = between(1, 3)
@task(3)
def browse_products(self):
self.client.get("/api/products")
@task(1)
def add_to_cart(self):
self.client.post("/api/cart", json={"sku": "AK-204", "qty": 1})
Run it:
locust -f locustfile.py
Then open http://localhost:8089, set the user count and spawn rate, and start the test.
The benefit is control. Because the test is code, you can implement:
- Conditional logic
- Weighted tasks
- Multi-step user journeys
- Shared state across requests
- Custom clients for protocols beyond HTTP
- Distributed load generation across workers
In the example above, @task(3) makes product browsing happen three times as often as adding to cart with @task(1).
Locust also scales horizontally. A master process can coordinate multiple workers, and its event-driven model lets each worker handle many concurrent users without one thread per user.
Use Locust when you need complex, code-modeled behavior or large distributed tests. The tradeoff is that every load test becomes a program you must write, debug, and maintain.
Where code-first load testing slows you down
The friction usually appears in three places.
1. Setup
Before measuring anything, you need to:
python -m venv .venv
source .venv/bin/activate
pip install locust
Then you still need to write and test the load script.
For a quick “can this endpoint handle 50 concurrent users?” check, that setup can be more work than the actual test.
2. Duplicate request definitions
Your API requests probably already exist somewhere:
- An API client
- A test collection
- A
.httpfile - A QA test scenario
- Existing functional tests
A locustfile.py often redefines the same request URL, headers, auth flow, body, and variables. That creates two sources of truth. When the API changes, both must be updated.
3. Access for non-Python users
The people who need load test results are not always Python developers. QA engineers, frontend developers, product teams, and release managers may only need the answer:
Does this endpoint hold up under expected traffic?
If the test is locked behind a Python script, the result is locked behind that skill set.
The Apidog approach: load-test existing API scenarios
Apidog takes the opposite approach. Instead of writing a script to describe API requests, you reuse API requests you already have.
In Apidog, the unit of a performance test is a test scenario: an ordered set of API requests with environments, variables, and assertions already configured.
If you already use Apidog to debug or test an endpoint, that request can become the source for a performance test.
How to run a performance test in Apidog
Use this workflow:
- Open the test scenario you want to load-test.
- Run it as a performance test instead of a single functional test.
- Set the number of virtual users.
- Set the test duration.
- Optionally set a ramp-up duration.
- If the scenario uses test data, choose a data matching mode.
- Start the test.
- Monitor live metrics.
Apidog supports up to 100 virtual users in one performance test. Each virtual user loops through every request in the scenario for the duration you set.
Ramp-up controls how quickly those users start. For example:
-
0 seconds: all users start immediately -
30 seconds: users start gradually over 30 seconds -
2 minutes: users ramp up more slowly
For data-driven scenarios, Apidog supports:
- Random Match: each virtual user picks a random test data row on each loop
- Sequential Match: virtual users walk through test data rows in order
During the run, Apidog shows live metrics for each API in the scenario:
- Total Requests
- Avg Throughput
- Avg Response Time
- Maximum Response Time
- Minimum Response Time
- Errors
The Error tab breaks down failed requests, and the Test Reports tab keeps historical runs so you can compare results before and after a change.
Example: test a login endpoint with 100 users
Assume you want to test:
- Endpoint:
POST /login - Load: 100 concurrent users
- Duration: 2 minutes
- Ramp-up: 30 seconds
Locust workflow
You would typically:
- Create
login_test.py. - Define a
HttpUser. - Add a task that posts credentials.
- Parse the auth token from the response.
- Store the token for later requests if needed.
- Run Locust.
- Open the Locust UI.
- Enter users, spawn rate, and duration.
- Debug Python if auth or state handling fails.
Example shape:
from locust import HttpUser, task, between
class LoginUser(HttpUser):
wait_time = between(1, 2)
@task
def login(self):
response = self.client.post("/login", json={
"email": "test@example.com",
"password": "password"
})
if response.status_code == 200:
token = response.json().get("token")
self.client.headers.update({
"Authorization": f"Bearer {token}"
})
That works, but you are maintaining a separate test harness.
Apidog workflow
In Apidog:
- Open the login test scenario.
- Switch to performance testing.
- Set virtual users to
100. - Set duration to
2 minutes. - Set ramp-up to
30 seconds. - Start the test.
- Read live throughput, latency, and error rate.
The same auth configuration that works in the functional scenario is reused in the performance test.
Locust vs Apidog: when to use which
Use Locust when you need:
- Complex branching behavior
- Weighted task graphs
- Custom protocol clients
- Distributed load generation
- Very high virtual-user counts
- Load tests maintained as code
Use Apidog when your test is closer to:
Run these existing API requests at this concurrency for this duration and show me the numbers.
Apidog is useful for everyday API checks where you want fast feedback without maintaining a separate Python load testing layer.
Limits to keep in mind
Apidog performance testing has practical boundaries.
It supports up to 100 virtual users in a single performance test, and the load is generated from the machine running the app. If you need tens of thousands of users or load generation from multiple regions, use a distributed setup such as Locust workers or a dedicated load testing cluster.
Apidog also records failed requests statistically rather than capturing the full request and response body for every failed call during load. For deep forensic debugging of a specific failure, you may need additional logging on the API side.
Locust has the opposite tradeoff. It gives you extensive control, but you pay for that control with code, environment setup, and ongoing maintenance.
A practical rule:
- If the test is “run these requests at this concurrency for this long,” use an in-app performance test.
- If the test requires custom behavior, branching, distributed workers, or large-scale traffic generation, use code.
For more context, see these comparisons:
How to read the load test results
A load test is only useful if you know how to interpret the output.
Throughput
Throughput is the number of requests or transactions served per second.
If throughput stops increasing while you add more virtual users, the system has likely reached saturation.
Response time
Response time is how long each request takes.
Watch both:
- Average response time
- Maximum response time
A good average can hide bad tail latency. If max response time spikes, some users are still having a poor experience.
Error rate
Error rate is the percentage of failed requests.
A test that passes at low concurrency but starts returning 500, 429, or timeout errors under load tells you where the system begins to break.
Concurrency
Concurrency is the number of active virtual users.
Ramp-up matters. An API may handle 100 users when they arrive gradually but fail if all 100 start in the same second.
For a deeper walkthrough, see:
How this compares with JMeter and Postman
If you have used JMeter, Apidog’s UI-driven approach may feel familiar. Both let you configure tests without writing code. JMeter is more powerful in some advanced cases, but it uses heavier XML-based test plans and has a steeper learning curve. See the JMeter load testing tutorial for details.
If you have used Postman’s collection runner for load-style testing, you have seen a lighter version of request reuse. This is covered in load testing with Postman. Apidog adds dedicated performance reporting on top of reusable API requests and scenarios, including workflows for API testing without Postman.
The main point: your load test should reuse API knowledge you already encoded instead of duplicating it in another tool or language.
Getting started
If your API requests already live in Apidog, you can run a performance test quickly:
- Open a test scenario.
- Switch it to a performance test.
- Set virtual users.
- Set duration.
- Optionally set ramp-up.
- Start the run.
- Review throughput, latency, and errors.
If you are coming from Locust and the Python layer is only duplicating existing API requests, rebuild the scenario once in Apidog and reuse it for functional and performance testing.
Download Apidog and run a performance test against an endpoint you already test. For distributed, code-modeled load at massive scale, Locust remains the better fit. For everyday API load checks, reuse the requests you already have.
FAQ
Is Apidog a drop-in replacement for Locust?
Not for every use case. For load-testing API requests at up to 100 virtual users without writing code, Apidog can replace the usual Locust workflow by running existing test scenarios directly. For distributed load at very high user counts or custom non-HTTP protocols modeled in code, Locust is still the better fit.
Do I need to write code to load-test in Apidog?
No. You configure virtual users, duration, and ramp-up time in the UI. The test runs requests from an existing test scenario. There is no locustfile and no Python environment to manage.
How many virtual users can Apidog simulate?
Apidog supports up to 100 virtual users in a single performance test. Each virtual user loops through every API in the scenario for the configured duration.
What metrics does Apidog report?
For each API in the scenario, Apidog reports:
- Total Requests
- Avg Throughput
- Avg Response Time
- Maximum Response Time
- Minimum Response Time
- Errors
The chart updates live, the Error tab breaks down failed requests, and the Test Reports tab keeps run history.
Can I load-test data-driven requests?
Yes. If your scenario uses test data, choose:
- Random Match to select a random row on each loop
- Sequential Match to walk through rows in order
Should I still use Locust?
Yes, when the test needs Locust’s strengths: code-defined user behavior, branching logic, weighted tasks, custom protocol clients, and distributed load generation beyond Apidog’s in-app performance test limits.


Top comments (0)