---
title: "Locustとは？Pythonで書く負荷試験の使い方・ramp-up・分散実行【2.47対応】"
url: "https://www.issoh.co.jp/tech/details/10870/"
published: 2026-02-05
updated: 2026-11-02
categories: ["テスト"]
publisher: "株式会社一創"
---

# Locustとは？Pythonで書く負荷試験の使い方・ramp-up・分散実行【2.47対応】

Locust（ローカスト）は、負荷試験のシナリオをPythonのコードで書くオープンソースのツールです。この記事では2026年11月時点の最新版 Locust 2.47.0 を手元で動かし、ログイン付きAPIへの負荷試験を例に、シナリオの書き方からヘッドレス実行、設定ファイル、段階的な負荷のかけ方、CIでの合否判定、分散実行までを実行結果つきで解説します。

## まとめ：Locustで負荷試験を始める要点

- Locustは負荷試験用のPythonライブラリ兼コマンドです。最新版は2.47.0（2026年10月21日公開）で、Python 3.11以上が必要です。ライセンスはMITです。
- 導入は `pip install locust`、実行は `locust -f locustfile.py` です。Web UIは既定で8089番ポートに立ち上がります。
- CIでは `--headless -u -r -t` で条件を固定し、繰り返す条件は `locust.conf` に書きます。失敗リクエストが1件でもあると終了コードは1になります。
- 秒間リクエスト数（RPS）は直接指定せず、ユーザー数と1サイクルの時間（待ち時間＋応答時間）から決まります。目標の回数に合わせたいときは `constant_throughput` を使います。
- `--csv` の `_stats.csv` は最後の約1秒分が抜けることがあります。報告に使う最終値は `--json-file` かHTMLレポートから取ります。
- 2.47.0でWeb UIの `/stop` と `/stats/reset` がPOST専用になりました。GETで叩いているスクリプトは405で止まります。

## Locustの特徴とJMeter・k6との違い

### Pythonのコードでシナリオを書く設計

Locustでは、仮想ユーザーの振る舞いを `User` クラスとして書き、その中のメソッドを `@task` でタスクに登録します。GUIでテスト計画を組み立てるJMeterと違い、ログイン、トークンの付け替え、テストデータの読み込みといった処理を普通のPythonで書けます。シナリオがただのコードなので、Gitでの差分レビューもしやすくなります。

公式リポジトリは `locustio/locust` で、ライセンスはMITです。Python製のため、1プロセスは1コアしか使えません（GILによる制約）。高い負荷をかけるにはプロセスを増やす前提で設計されています。

### JMeter・k6・Gatlingとの選び分け

| ツール           | シナリオの書き方                                | 本体の言語  | ライセンス      |
| ------------- | --------------------------------------- | ------ | ---------- |
| Locust        | Pythonコード                               | Python | MIT        |
| Apache JMeter | GUIで作るテスト計画                             | Java   | Apache-2.0 |
| Grafana k6    | JavaScript・TypeScript                   | Go     | AGPL-3.0   |
| Gatling       | Java・Kotlin・Scala・JavaScript・TypeScript | Scala  | Apache-2.0 |

チームの主な言語がPythonで、認証や前処理を含む込み入ったシナリオを書くならLocustが合います。逆に、テスト担当者がコードを書かない体制なら、Locustを第一候補にすべきではありません。JavaScriptでシナリオを書き、閾値で合否を判定する使い方は [k6の使い方とインストール手順の記事](/tech/details/7581/) で、HTTP/2の性能試験は [JMeterのBlazeMeter HTTPプラグインの解説](/tech/details/10012/) で扱っています。ツールを問わない試験の組み立て方（シナリオ設計、合否指標、環境の揃え方）は [負荷試験のシナリオ設計と合否指標の解説](/tech/details/18987/) にまとめました。

## Locustのインストールと動作確認

pipで入れるのが基本です。WindowsでもmacOS・Linuxと同じ手順で入ります。システムのPythonを汚さないよう、仮想環境に入れます。

```
python3 -m venv .venv
source .venv/bin/activate      # Windowsは .venv\Scripts\activate
pip install locust==2.47.0    # 最新版を入れるなら版指定を外す
locust --version
# locust 2.47.0 from .../site-packages/locust (Python 3.13.14)
```

Python 3.10以前ではLocust 2.47.0を入れられません。[PyPIのlocust](https://pypi.org/project/locust/)で要件が `>=3.11` になっているためです。Dockerを使う場合は公式イメージ `locustio/locust` に、カレントディレクトリのlocustfileをマウントして起動します。2.47.0でイメージのPythonは3.13から3.14に上がりました。

```
docker run -p 8089:8089 -v $PWD:/mnt/locust locustio/locust:2.47.0 -f /mnt/locust/locustfile.py
```

## locustfileの書き方：ログイン付きAPIのシナリオ

### HttpUserとタスクの重み

次のコードは、ログインしてトークンを受け取り、商品APIと遅いAPIを3対1の比率で呼ぶシナリオです。`on_start` は仮想ユーザーごとに1回だけ実行されるので、ログインはここに書きます。`locustfile.py` の名前で保存します。`/api/login` などのパスは、この記事の検証用に手元で立てたサーバーのものなので、自分のシステムのAPIに置き換えてください。

```
import random
from locust import HttpUser, task, between

class ApiUser(HttpUser):
    wait_time = between(1, 2)

    def on_start(self):
        res = self.client.post("/api/login", json={"user": "demo", "password": "secret"})
        self.client.headers["Authorization"] = f"Bearer {res.json()['token']}"

    @task(3)
    def get_item(self):
        item_id = random.randint(1, 100)
        with self.client.get(f"/api/items/{item_id}", name="/api/items/[id]", catch_response=True) as res:
            if res.status_code == 404:
                res.success()

    @task(1)
    def slow(self):
        self.client.get("/api/slow")
```

`@task(3)` と `@task(1)` の数字は選ばれる確率の重みです。`wait_time = between(1, 2)` は、タスクを1回終えるごとに1〜2秒待つ指定です。`self.client` は requests のセッションと同じように扱え、Cookieやヘッダーはユーザーごとに保持されます。

### URLの集約と、404を成功として数える判定

IDをURLに埋め込むと、統計がURLごとに別々の行へ分かれます。`name="/api/items/[id]"` を渡すと1行にまとまります。

存在しないIDへの404も、既定では失敗として数えられます。仕様どおりの応答なら、`catch_response=True` で応答を受け取り、`res.success()` を呼んで成功扱いにします。反対に、ステータスが200でも本文にエラーが入っている場合は `res.failure("理由")` で失敗にできます。

## ヘッドレス実行とWeb UIの使い分け

### コマンドラインの主要オプション

`locust -f locustfile.py` だけで起動すると、Web UI（`http://localhost:8089`）でユーザー数と生成レートを入力してから開始します。CIや再現性が必要な計測では、`--headless` で画面を使わずに条件を固定します。

```
locust -f locustfile.py -H http://127.0.0.1:18099 \
  --headless -u 20 -r 5 -t 20s \
  --csv out/run1 --html out/report.html --only-summary
```

| オプション            | 意味                    |
| ---------------- | --------------------- |
| `-H`             | 負荷をかける先のベースURL        |
| `-u`             | 最大同時ユーザー数             |
| `-r`             | 1秒あたりに増やすユーザー数        |
| `-t`             | 実行時間（30s、20m、1h30mなど） |
| `--headless`     | Web UIを使わずに即時開始       |
| `--autostart`    | Web UIを残したまま即時開始      |
| `--only-summary` | 途中経過を出さず最後の集計だけ出力     |

コマンドラインの `-t` は、`--headless` か `--autostart` と組み合わせたときだけ有効です。Web UIから開始する場合は、開始フォームのRun time欄で実行時間を指定します。指定しなければ、止めるまで走り続けます。2.47.0では、`--csv`・`--html`・`--json-file` の出力先ディレクトリが無ければ作られます。上の例でも `out` を作らずに実行して、ファイルが出力されました。

### 設定ファイル locust.conf による条件の固定と上書き順

毎回同じオプションを並べるなら、設定ファイルに移します。[公式ドキュメントの設定ページ](https://docs.locust.io/en/stable/configuration.html)によると、Locustは `~/.locust.conf`、`./locust.conf`、`./pyproject.toml` を既定で読み込み、ほかのファイルは `--config` で指定します。キー名はオプション名から先頭の `--` を外したものです。

```
# locust.conf
locustfile = locustfile.py
host = http://127.0.0.1:18099
headless = true
users = 10
spawn-rate = 5
run-time = 5s
only-summary = true
csv = out/conf
```

このファイルを置いたディレクトリで引数なしの `locust` を実行すると、10ユーザー・5秒で始まり、CSVが出力されました。`locust -u 4` とすると4ユーザーで始まります。値は `pyproject.toml` → `locust.conf` → `--config` のファイル → 環境変数 → コマンドラインの順に読まれ、後のもので上書きされます。ステージング用と本番相当用でファイルを分け、`locust --config staging.conf` のように切り替えると、CIの定義に条件を書かずに済みます。`pyproject.toml` に書く場合は `[tool.locust]` セクションに置きます。

### Web UIのタブとAPIとしての使い方

2.47.0のWeb UIには、Statistics、Charts、Failures、Exceptions、Current Ratio、Download Data、Logsのタブがあります。分散実行のときはWorkersタブも加わります。実行中に見るのは主に次の3つです。

- Statistics：リクエスト名ごとの件数、失敗数、中央値、95パーセンタイル、RPS
- Charts：RPS、応答時間、ユーザー数の推移。ユーザー数を増やしてもRPSが伸びず応答時間だけ上がり始めた点が、限界の目安です。負荷生成側のCPUが足りない場合も同じ形になるので、Locustのコンソールに出るCPU使用率の警告も確認します
- Failures：失敗の種類と件数。ステータスコードや例外メッセージ単位で集計されます

Web UIの裏にあるHTTPエンドポイントをスクリプトから叩いて、試験の開始や停止を自動化する使い方もあります。[2.47.0のリリースノート](https://github.com/locustio/locust/releases/tag/2.47.0)には破壊的変更として「`/stop` と `/stats/reset` をPOST専用にした」とあり、理由はCSRF対策です。手元でも `GET /stop` と `GET /stats/reset` は405になり（2.46.5の `GET /stop` は200）、`curl -X POST http://127.0.0.1:8089/stop` は `{"message": "Test stopped", "success": true}` を返しました。開始用の `/swarm` は以前からPOSTです。

## RPSの決まり方とwait\_timeの選び方

Locustで指定するのはユーザー数で、RPSは直接指定しません。1タスクで1リクエストを送るシナリオなら、RPSは「ユーザー数 ÷ 1サイクルの時間（待ち時間＋応答時間）」がおおよその目安です。先ほどのシナリオを20ユーザー（1秒に5人ずつ増加）で20秒実行すると、次の集計になりました。

```
Type     Name              # reqs   # fails |  Avg   Min   Max   Med |  req/s
GET      /api/items/[id]      166   0(0.00%) |    6     2    31     5 |   8.60
POST     /api/login            20   0(0.00%) |   11     4    29    11 |   1.04
GET      /api/slow             50   0(0.00%) |  529   339   635   520 |   2.59
         Aggregated           236   0(0.00%) |  117     2   635     5 |  12.23
```

待ち時間の平均は1.5秒なので、20ユーザーがそろった状態の目安は約13 req/sです。実測の合計12.23 req/sには、20人に達するまでの約3秒間と、ログインの20件が含まれています。加えて `/api/slow` の応答に平均0.53秒かかるぶんサイクルが長くなり、RPSが下がっています。対象システムが遅くなるとRPSも下がるわけです。「ユーザー数を固定して応答時間を見る試験」ではこれが自然ですが、「毎秒20件を処理できるか」を確かめたい試験では条件がぶれます。

待ち方は `wait_time` に渡す関数で変えます。2.47.0で使えるのは次の5つです。

| 関数                       | タスク後の待ち時間            | 向く試験        |
| ------------------------ | -------------------- | ----------- |
| `between(a, b)`          | a〜b秒の一様乱数            | 人の操作間隔を模す   |
| `constant(n)`            | 常にn秒                 | 単純な繰り返し     |
| `constant_throughput(n)` | 各ユーザーのタスク実行を1秒にn回へ調整 | 目標RPSに合わせる  |
| `constant_pacing(n)`     | 各ユーザーのタスク実行をn秒に1回へ調整 | 周期処理を模す     |
| `poisson(n)`             | 平均1/n秒の指数分布          | 到着のばらつきを入れる |

商品APIを呼ぶタスク1つだけのシナリオを10ユーザー・15秒で実行すると、`constant_throughput(2)` は20.39 req/sで、目標の20にほぼ一致しました。調整されるのはリクエスト数ではなくタスクの実行回数です。タスクの実行に0.5秒以上かかると待ち時間は0になり、目標には届きません。

`poisson()` は2.46.6（2026年9月17日）で追加された関数です。同じ条件の `poisson(2)` は17.56 req/sでした。ソースを見ると待ち時間は `random.expovariate(rate)` そのもので、タスクの所要時間を差し引きません。そのため1ユーザーあたりの実行回数は平均で「1 ÷（タスクの所要時間＋1/n）」回/秒になり、nに近づくのはタスクの所要時間が平均待ち時間（1/n秒）より十分短いときだけです。今回のタスクは約7msなので計算上は合計約19.7 req/sですが、待ち時間が乱数なので15秒程度の試験では1回ごとに数値が揺れます。「毎秒何件」を確かめる試験は `constant_throughput`、アクセスが集中する瞬間を含めて見たい試験は `poisson` と使い分けます。

## LoadTestShapeによるramp-upと段階的な負荷

`-r` は一定の割合でユーザーを増やすだけです。「5人で10秒、15人に増やして10秒、その後0人」のような段階的な負荷は、`LoadTestShape` を継承したクラスで書きます。Locustは `tick()` を約1秒ごとに呼び、戻り値の「ユーザー数と生成レート」に合わせて負荷を調整します。`None` を返すとテストが終わります。

```
from locust import HttpUser, LoadTestShape, task, constant

class WebUser(HttpUser):
    wait_time = constant(1)

    @task
    def index(self):
        self.client.get("/")

class StepShape(LoadTestShape):
    # (終了秒, ユーザー数, 生成レート)
    stages = [(10, 5, 5), (20, 15, 5), (30, 0, 5)]

    def tick(self):
        run_time = self.get_run_time()
        for end, users, rate in self.stages:
            if run_time < end:
                return (users, rate)
        return None
```

ShapeクラスがあるlocustfileではShapeが負荷を決めるので、`-u -r -t` は不要で、接続先の `-H` と `--headless` だけで実行できます。2.47.0の実行ログでは、開始直後に5人、約10秒後に15人、約21秒後に0人へ切り替わり、31秒の時点で終了コード0で終わりました。

```
Shape test updating to 5 users at 5.00 spawn rate
Shape test updating to 15 users at 5.00 spawn rate
Shape test updating to 0 users at 5.00 spawn rate
Shape test completed, shutting down
```

## 結果レポートの読み方：CSV・HTML・JSON

### 出力されるファイルと見る列

`--csv out/run1` を付けると、2.47.0では次の4ファイルが出力されました。`--help` の説明文には3ファイルと書かれていますが、実際には例外用のファイルも作られます。

| ファイル                     | 内容                 |
| ------------------------ | ------------------ |
| `run1_stats.csv`         | リクエスト名ごとの集計        |
| `run1_stats_history.csv` | 時系列の集計（グラフ用）       |
| `run1_failures.csv`      | 失敗の種類と発生回数         |
| `run1_exceptions.csv`    | locustfile内で発生した例外 |

`run1_stats.csv` には、Request Count、Failure Count、Median Response Time、Average Response Time、Requests/s などの列に加え、50%から100%までのパーセンタイルの列が入ります。応答時間の単位はミリ秒です。性能要件がパーセンタイルで決まっているなら、95%や99%の列と照らし合わせます。平均は少数の遅いリクエストに引っ張られるためです。先ほどの集計（Aggregated）では、平均117msに対して中央値は5msでした。

1ファイルで共有したいなら `--html report.html` でグラフ付きのHTMLレポートを出力します。ファイル名の `{u}` `{r}` `{t}` は、ユーザー数、生成レート、実行時間に置き換わります。別のプログラムで集計する場合は、`--json`（標準出力）か `--json-file` で最終集計をJSONとして受け取れます。`--json-file` を付けると、コンソールの最終集計表は出なくなります。

### \_stats.csvの最終集計がコンソールより少ない問題

上の20秒の試験では、コンソールとHTMLレポートのAggregatedが236件だったのに対し、`run1_stats.csv` のAggregatedは227件でした。9件、時間にして最後の約0.7秒分が抜けています。6秒の試験を6回繰り返すと、コンソールとCSVの件数は 74と73、74と60、68と68、75と75、69と61、70と68 で、一致したのは2回だけです。2.46.5でも、`--json-file` の70件に対しCSVは61件と同じ現象が出ました。

原因はCSVの書き方にあります。Locustは `_stats.csv` を1秒ごと（`CSV_STATS_INTERVAL_SEC = 1`）に上書きしており、終了時はファイルを閉じるだけで最後の書き込みをしません。[Issue #2299](https://github.com/locustio/locust/issues/2299)（2023年2月）で同じ差が報告され、メンテナーは「CSVの書き出しが早すぎるのだろう」と答えていますが、修正されないまま自動でクローズされています。手元では3回に1回、終了時に `ValueError: I/O operation on closed file` のトレースバックも出ました（終了コードは0のまま）。

報告書やCIの判定に使う最終値は、`--json-file`、HTMLレポート、または次の章の `quitting` イベントで受け取る `environment.stats` から取ってください。`_stats.csv` は件数が少し欠ける前提で扱い、`_stats_history.csv` は推移のグラフ用に使います。短い試験ほど、抜ける1秒の比率が大きくなります。

## CIでの合否判定と終了コードの制御

ヘッドレス実行では、失敗リクエストが1件でもあるとLocustは終了コード1で終わります。商品APIの404を失敗のまま数えるシナリオで試すと、失敗率11.67%で `Shutting down (exit code 1)` になりました。GitHub ActionsなどのCIでは、このステップがそのまま失敗します。

「失敗は1%まで許す」「95パーセンタイルが800msを超えたら落とす」といった条件にしたい場合は、[公式ドキュメントのヘッドレス実行のページ](https://docs.locust.io/en/stable/running-without-web-ui.html)にあるように、`quitting` イベントで `environment.process_exit_code` を設定します。

```
import logging
from locust import events

@events.quitting.add_listener
def check_result(environment, **kwargs):
    stats = environment.stats.total
    if stats.num_requests == 0:
        logging.error("リクエストが1件も記録されていません")
        environment.process_exit_code = 1
    elif environment.runner.exceptions:
        logging.error("locustfile内で例外が発生しました")
        environment.process_exit_code = 1
    elif stats.fail_ratio > 0.01:
        logging.error("失敗率が1%を超えました")
        environment.process_exit_code = 1
    elif stats.get_response_time_percentile(0.95) > 800:
        logging.error("95パーセンタイルが800msを超えました")
        environment.process_exit_code = 1
    else:
        environment.process_exit_code = 0
```

`process_exit_code` に値を入れると、Locust標準の判定（失敗が1件でもあれば1）より優先されます。1%以下の失敗を許すには合格時に0を入れる必要がありますが、そのままではlocustfile内の例外も見逃します。そのため、この例では `environment.runner.exceptions` を先に確認し、リクエストが1件も記録されない場合（ユーザー数0など）も不合格にしています。

2.47.0でこのコードを試すと、失敗率0.45%（662件中3件）では終了コード0、タスク内で例外を送出すると1、ユーザー数0でも1になりました。応答に0.3秒以上かかるAPIだけを流して閾値を300msに下げた場合も1です。失敗があっても終了コードを変えたくないときは、`--exit-code-on-error 0` を指定します（既定値は1）。性能要件を数値で決める手順は [非機能要件の数値化と閾値テストの解説](/tech/details/17610/) を参照してください。負荷試験を組み込んだ開発体制ごと外部に任せたい場合は、Pythonでの[フルスクラッチ開発](/service/system/fullscratch/)として相談を受けています。

## 分散実行：masterとworkerの構成

### masterとworkerの起動手順

分散実行では、`--master` を付けたプロセスがWeb UIと全体の制御を担当し、`--worker` を付けたプロセスが仮想ユーザーを動かして統計をmasterへ送ります。master自身はユーザーを動かしません。[公式ドキュメントの分散実行のページ](https://docs.locust.io/en/stable/running-distributed.html)のとおり、1プロセスは1コアしか使えないため、負荷生成マシンのコア数と同じ数だけworkerを立てます。

```
# 負荷生成マシンA（master）
locust -f locustfile.py --master -H https://api.example.com \
  --headless -u 1000 -r 50 -t 10m --expect-workers 4

# 負荷生成マシンB・C（workerを2つずつ）
locust -f locustfile.py --worker --master-host 192.168.1.10
```

`--expect-workers 4` は、workerが4つ接続するまで開始を待つ指定です。`-u` や `-r` はmaster側だけに付ければ、workerへ配分されます。masterとworkerは5557番ポートで通信するので、ファイアウォールで開けておきます。

1台のマシンでコア数分を使うだけなら、`--processes` で自動的にプロセスを分けられます。2.47.0で `--processes 2` を付けて失敗を含むシナリオを流すと、workerが2つ接続して負荷を分担しました。workerのログには `exit code 0` が出ますが、コマンド全体の終了コードはmasterの1です。CIで見るのはmasterの終了コードで足ります。なお、このオプションはWindowsでは使えません。

### Docker Compose・Kubernetes・マネージド実行

Docker Composeでは、公式イメージをmasterとworkerの2サービスとして定義します。公式ドキュメントの例では `-H` がmaster自身のWeb UI（`http://master:8089`）になっているので、試験対象のURLに書き換えて使います。

```
services:
  master:
    image: locustio/locust:2.47.0
    ports:
     - "8089:8089"
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --master -H https://api.example.com
  worker:
    image: locustio/locust:2.47.0
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --worker --master-host master
```

workerを増やすときは `docker compose up --scale worker=4` とします。Kubernetesでは、公式ドキュメントに載っているLocust Operatorが使えます。master/workerのJob作成、locustfileのマウント、Web UIの公開、メトリクス収集までをカスタムリソースで管理できます。

負荷生成の基盤を自分で持ちたくない場合、[公式ドキュメントのHosted load testingのページ](https://docs.locust.io/en/stable/hosted-load-testing.html)はMicrosoftのAzure Load Testingを案内しています。同じページには、MicrosoftがLocustの保守に貢献・支援していると書かれています。以前のマネージドサービスLocust Cloudは、2.43.0（2025年12月30日）で本体からの参照が削除されました。試験中のリクエストを監視基盤のトレースと突き合わせたいなら、`pip install "locust[otel]"` で入れて `--otel` を付け、送信先を `OTEL_EXPORTER_OTLP_ENDPOINT` などの環境変数で指定すると、OpenTelemetryでトレースとメトリクスを送れます。[公式ドキュメントのOpenTelemetryのページ](https://docs.locust.io/en/stable/telemetry.html)によると、HTTPリクエストが自動でスパンになるのは requests を使う `HttpUser` だけで、次の章の `FastHttpUser` は対象外です。

## FastHttpUserによる負荷生成側の高速化と互換性の制約

workerを増やす前に試したいのが `FastHttpUser` です。`HttpUser` と同じAPIのまま、内部のHTTPクライアントを python-requests から geventhttpclient に切り替えます。[公式ドキュメントの性能向上のページ](https://docs.locust.io/en/stable/increase-performance.html)では、小さなリクエストを待ち時間なしで繰り返す最良のケースで、1プロセスあたり `HttpUser` が約4,000 req/s、`FastHttpUser` が約16,000 req/sとされています（2021年のM1 MacBook Pro、Python 3.11で計測）。

1ユーザー・待ち時間0で10秒ずつ比べた結果は、`HttpUser` が262.99 req/s、`FastHttpUser` が450.48 req/sで、約1.7倍でした（Intel Core i9-9880H、検証用サーバーはPython標準の `ThreadingHTTPServer` を同じマシンで稼働）。同じマシンで2026年9月に測ったときは463.88と854.88 req/s（約1.8倍）で、絶対値は今回の2倍近くありました。この差の原因は切り分けていません。倍率も絶対値も環境ごとに測り直す必要があり、負荷生成側のCPUが先に張り付いていないかは試験中に `top` などで確認します。

切り替えは `from locust import FastHttpUser` にして継承元を変えるだけです。ただし requests 固有の機能（セッションのアダプター設定など）に依存したコードは、そのままでは動きません。

## HTTP以外のプロトコルとlocust-plugins

Locustの計測はHTTPに限りません。任意の処理の所要時間を `events.request.fire` で報告すれば、Statisticsに1行として並びます。次は、TCP接続にかかる時間を計測する例です。

```
import socket
import time
from locust import User, task, constant

class TcpUser(User):
    wait_time = constant(1)

    @task
    def connect(self):
        start = time.perf_counter()
        exc = None
        try:
            with socket.create_connection(("127.0.0.1", 8099), timeout=2):
                pass
        except OSError as e:
            exc = e
        self.environment.events.request.fire(
            request_type="TCP",
            name="connect",
            response_time=(time.perf_counter() - start) * 1000,
            response_length=0,
            exception=exc,
            context={},
        )
```

実行すると、集計に `TCP connect` の行が追加され、HTTPのリクエストと同じ形式で件数と応答時間が出ます。[公式ドキュメントのHTTP以外のシステムを試験するページ](https://docs.locust.io/en/stable/testing-other-systems.html)に載っているものは次のとおりです。

- gRPC：本体に同梱されたクラスではなく、公式ドキュメントとリポジトリの `examples/grpc` に、利用者が組み込む `GrpcUser` 基底クラスの例があります
- Socket.IO：本体同梱の `SocketIOUser`（実験的機能）
- MQTT：本体同梱の `MqttUser`（実験的機能）

Socket.IOではない素のWebSocketには、公式ドキュメントに専用クラスがありません。WebSocketクライアントのライブラリを上の例と同じ形で包み、送信から応答までの時間を `events.request.fire` で報告します。

コミュニティ製の拡張集 locust-plugins（SvenskaSpel、最新は2026年6月の5.0.3）には、Playwright・Selenium・Kafka・FTP用のユーザー、CSVやMongoDBからテストデータを読むリーダー、`--check-rps` や `--check-fail-ratio` による合否判定オプションなどがあります。

## よくある質問

### Locustの読み方と意味は？

「ローカスト」と読みます。英単語のlocustは「イナゴ」の意味で、大量の仮想ユーザーが一斉にシステムへ押し寄せる様子に由来します。

### LocustはWindowsで使えますか？

使えます。`pip install locust` で導入でき、Web UI、ヘッドレス実行、master/workerの分散実行も動きます。1台で自動的にプロセスを分ける `--processes` だけはWindowsで使えないため、複数コアを使うときはworkerを個別に起動します。

### Locustの負荷試験でramp-upを設定するには？

一定の割合で増やすだけなら、`-r`（1秒あたりに増やすユーザー数）を指定します。段階的に増減させるなら、`LoadTestShape` を継承したクラスの `tick()` で、経過時間に応じたユーザー数と生成レートを返します。

### Locustは有料ですか？

本体は無料です。MITライセンスのオープンソースで、商用の負荷試験にも使えます。マネージドサービスを使う場合は、公式ドキュメントが案内するAzure Load Testingなど、そのサービスの料金がかかります。

### Locustとk6はどちらを選ぶべきですか？

シナリオをPythonで書きたいならLocust、JavaScriptやTypeScriptで書き、閾値による合否判定を標準機能で済ませたいならk6です。Locustで高いRPSが必要な場合は、workerを複数並べる前提になります。

## 関連記事

- [負荷試験とは？シナリオ設計と合否指標、本番相当環境の揃え方をk6の実例で解説](/tech/details/18987/)
- [k6とは？Grafana k6の使い方とインストール手順・負荷テストの書き方【v2.3対応】](/tech/details/7581/)
- [非機能要件とは？6大項目の数値化とk6での閾値テストまで実装目線で解説](/tech/details/17610/)
- [JMeterでHTTP/2負荷テストを行う方法｜BlazeMeter HTTPプラグインの導入と設定【3.2対応】](/tech/details/10012/)
- [Postmanとは？APIテスト自動化とNewmanでのCI組み込みまで実装手順で解説](/tech/details/17392/)

---

出典: [Locustとは？Pythonで書く負荷試験の使い方・ramp-up・分散実行【2.47対応】](<https://www.issoh.co.jp/tech/details/10870/>)（株式会社一創）
