対象は Java 版のサーバー (バニラと Paper) です。処理の順番は Minecraft Wiki と Paper のソースコード、設定の名前と既定の値は 2026 年 10 月時点の PaperMC のドキュメントによります。
1 秒に 20 回のティック
Minecraft のサーバーは、ワールドの中の出来事を、1 秒に 20 回、まとめて計算しています。この 1 回の計算を「ティック」と呼びます。作物が育つのも、モブが動くのも、レッドストーン回路が動くのも、すべてティックごとに進みます。
1 秒に 20 回を保つには、1 回のティックを 50 ミリ秒以内に終える必要があります。計算が早く終わったときは、次のティックの時刻まで待ちます。
0 秒1 秒
1 回の
上の 20 個のマスは、実際の速さ (50 ミリ秒ごと) で順に点灯します。下の図は、1 回のティックを引き伸ばして、処理が進む順に表示しています (画面に入ったときに 1 回)。割合は説明のための例です。実際の割合は、ワールドとプレイヤーの数、レッドストーン回路やモブの数によって大きく変わります。
サーバーの状態は、次の 2 つの数字で表します。
| 指標 | 意味 | 目安 |
|---|---|---|
| TPS | 1 秒あたりのティックの回数 (Ticks Per Second) | 20 が上限。下回るとワールド全体の動きが遅れる |
| MSPT | 1 回のティックにかかった時間 (Milliseconds Per Tick) | 50 ミリ秒以下を保つ。平均だけでなく、最大と上位の値も見る |
TPS が 20 のままでも、MSPT が 45 ミリ秒であれば、余裕はほとんどありません。人数が少し増えたり、大きなレッドストーン回路が動いたりしただけで、TPS が下がります。サーバーの余裕は、TPS ではなく MSPT で見ます。
1 回のティックで計算すること
Minecraft Wiki がまとめている処理の順番を、要点に絞って示します。ディメンション (オーバーワールド、ネザー、ジ・エンド) は、1 つずつ順番に計算します。
- 遅れの確認と、tick・load の関数の実行 (データパックの処理)
- ディメンションごとの計算 (オーバーワールド、ネザー、ジ・エンド、追加のディメンションの順)
- ワールドボーダー、天候、時間、睡眠
- 予約されたブロックの更新 (レッドストーン回路など) と、液体の流れ
- 襲撃
- チャンクごとの処理 (モブのスポーン、雪と氷、作物の成長などのランダムティック)
- ブロックイベント (ピストン、音符ブロックなど)、エンダードラゴンの戦い
- エンティティ (モブ、アイテム、トロッコなど)
- ブロックエンティティ (ホッパー、かまど、チェストなど)
- プレイヤーとの通信の処理 (届いた操作の反映、変化の送信)
- 6,000 ティック (5 分) ごとの自動保存
このうち、プレイヤーの数に比例して増えやすいのは、読み込まれるチャンクと、その中のモブ、エンティティ、ブロックエンティティです。プレイヤーが散らばるほど読み込むチャンクは増え、1 か所に集まるほど、その場所のモブやエンティティの計算が重くなります。
チャンクと読み込まれる範囲
Minecraft のワールドは、「チャンク」という区画に分けて保存し、計算しています。1 つのチャンクは、横が 16×16 ブロックで、縦はワールドの底から高さの上限までです。オーバーワールドでは Y -64 から 319 までの 384 ブロック、ネザーとジ・エンドでは Y 0 から 255 までの 256 ブロックです。
サーバーは、ワールド全体を計算しているのではありません。計算するのは、読み込まれているチャンクだけです。読み込まれたチャンクにも段階があり、モブまで動かすチャンク、ブロックだけを動かすチャンク、読み込んでおくだけのチャンクに分かれます。
1 マスが 1 チャンク (16×16 ブロック) です。中央の白い点が、プレイヤーのいるチャンクです。読み込む範囲は円に近い形、計算する範囲は正方形です。既定の値は、どちらも 10 です。つまみを動かすと、範囲とチャンクの数が変わります。この図では、simulation-distance を view-distance 以下の範囲で動かせます。
プレイヤーのまわりの 2 つの距離
| 設定 (server.properties) | 意味 | 既定 |
|---|---|---|
view-distance | プレイヤーに送るチャンクの範囲 (半径、チャンクの数)。この範囲を読み込む | 10 (3〜32) |
simulation-distance | モブやエンティティを動かす範囲。その外側の 1 チャンクの幅では、レッドストーン回路や液体など、ブロックの処理だけが進む | 10 (3〜32) |
view-distance を広げると、遠くまで見えるようになりますが、読み込むチャンクと、プレイヤーに送る通信が増えます。simulation-distance を狭くすると、見えていても動かない範囲が増えるかわりに、計算は減ります。Paper では、ワールドごとの値を spigot.yml の world-settings で変えられます。
モブが自然にスポーンするのは、プレイヤーから 8 チャンク (128 ブロック) 以内のチャンクだけです。
プレイヤーがいなくても読み込まれるチャンク
| きっかけ | 読み込まれる |
|---|---|
/forceload | 指定したチャンク。サーバーを再起動しても残る。1 回のコマンドで指定できるのは 256 チャンクまで |
| ポータル | ネザーポータル、エンドポータル、エンドゲートウェイを、プレイヤー、モブ、アイテムが通ると、移動先のまわりを 15 秒間 |
| 投げたエンダーパール | 飛んでいる間、まわりの 3×3 チャンク (1.21.2 から) |
| エンダードラゴンとの戦い | 戦いの間、ジ・エンドの中央のまわり |
スポーン地点のまわりを常に読み込む仕組み (スポーンチャンク) は、1.21.9 で廃止されました。それまでスポーンチャンクで動かし続けていた装置は、プレイヤーが近くにいるか、/forceload で読み込まない限り、止まります。
1.21.5 からは、/forceload やエンダーパールで読み込んだチャンクでも、作物の成長などのランダムティックが進みます。ポータルにアイテムを通し続ける装置 (チャンクローダー) を使うと、プレイヤーがいない場所を読み込み続けられます。サーバーの負荷になるため、公開のサーバーでは、こうした装置の扱いをルールで決めておきます。
読み込みの解除と、新しいチャンクの生成
チャンクを読み込んでおく理由 (プレイヤー、/forceload、ポータルなど) がなくなると、チャンクは保存されて、読み込みが解除されます。Paper は、プレイヤーが離れたチャンクの解除を 10 秒遅らせます (paper-world-defaults.yml の chunks.delay-chunk-unloads-by)。すぐに戻ったときに、読み込み直さずに済みます。
読み込まれるチャンクの数は、プレイヤーが 1 か所に集まっていれば重なって少なく、散らばるほど増えます。view-distance が 10 なら、1 人のまわりだけで、直径 21 チャンクほどの円の範囲 (300 チャンクを超える) を読み込みます。
まだ誰も行っていない場所のチャンクは、保存したデータを読み込むのではなく、地形から生成します。プレイヤーが散らばって新しい場所を探索すると、生成の負荷が大きくなります。大人数のサーバーでは、公開の前にワールドボーダーで範囲を決め、Chunky などのプラグインで、その範囲のチャンクをあらかじめ生成しておきます。Folia のドキュメントも、事前の生成を勧めています。
| Paper の | 意味 | 既定 |
|---|---|---|
chunk-loading-basic.player-max-chunk-send-rate | 1 人に送るチャンクの数の上限 (1 秒あたり) | 75 |
chunk-loading-basic.player-max-chunk-load-rate | 1 人のために読み込むチャンクの数の上限 (1 秒あたり) | 100 |
chunk-loading-basic.player-max-chunk-generate-rate | 1 人のために生成するチャンクの数の上限 (1 秒あたり) | -1 (制限なし) |
メインのスレッドが 1 つであること
上の処理は、ほぼすべて「Server thread」という 1 つのスレッドで、順番に行われます。オーバーワールドとネザーとジ・エンドも、別々のコアで同時に計算されるのではなく、同じスレッドで 1 つずつ計算されます。Paper も、この基本の仕組みは同じです。
スレッドの名前は Paper のソースコードによります。使用率は説明のための例です。実際には、OS が各スレッドを空いているコアに割り振ります。
ワールドの中の出来事は、互いに影響し合います。ピストンがブロックを押せば、その先のレッドストーン回路が変わり、モブの動きも変わります。こうした処理を複数のスレッドで同時に計算すると、順番が入れ替わって結果が変わったり、同じデータを奪い合ったりします。順番どおりに 1 つのスレッドで計算するのは、ゲームの動きを保つための作りです。
そのため、CPU のコアの数を増やしても、ワールドの計算そのものは速くなりません。速くするには、1 コアあたりの性能が高い CPU を選ぶか、計算の量を減らすか、サーバーを分けるかのどれかです。
ほかのスレッドで動く処理
メインのスレッドの負担を減らすため、ワールドの状態を直接変えない処理は、別のスレッドで動きます。
| スレッドの | 処理 | 設定 |
|---|---|---|
| Netty Epoll Server IO | プレイヤーとの通信の送受信 | spigot.yml の netty-threads(既定 4) |
| Paper Common Worker | チャンクの生成など | paper-global.yml の chunk-system.worker-threads(既定は自動。物理コアの半分まで) |
| Paper I/O Worker | チャンクの読み込みと保存 | chunk-system.io-threads(既定は自動で 1) |
| Async Chat Thread | チャットの処理 | chat-executor-core-size など |
| Craft Scheduler Thread | プラグインが非同期で行う処理 | プラグインの作りによる |
| Paper Watchdog Thread | メインのスレッドの停止の監視 | spigot.yml の timeout-time |
Paper の起動のときのログには、「Paper is using X worker threads, Y I/O threads」と、チャンクの処理に使うスレッドの数が表示されます。
50 ミリ秒を超えたとき
1 回のティックが 50 ミリ秒を超えると、次のティックは待たずにすぐ始まります。重いティックが続くと、1 秒に 20 回を保てなくなり、TPS が下がります。プレイヤーからは、モブやブロックの動きが遅れ、壊したブロックが戻るように見えます。
通常
重い
縦の
遅れが大きくなったときの動きは、バニラと Paper で異なります。
- バニラ: 遅れが約 2 秒を超えると、ログに「Can't keep up! Is the server overloaded?」と表示し (15 秒に 1 回まで)、遅れた分のティックを取り戻さずに飛ばします
- Paper: この処理を置き換え、遅れを取り戻すために続けて行うティックの数を、
misc.catchup-ticks(既定 5) までに限ります。一時的な重さのあとに、ワールドが急に早送りされるのを防ぎます
ティックが止まったまま進まない場合は、Watchdog がサーバーを止めます。spigot.yml の timeout-time(既定 60 秒) のあいだティックが終わらないと、応答がないと判断して停止し、設定があれば再起動します。Paper は、その前の 10 秒後から、メインのスレッドが何をしているかをログに出力します。
メインのスレッドを止めてしまう処理
メインのスレッドの上で、時間のかかる処理を待つと、その間ワールド全体が止まります。よくある原因は、プラグインがメインのスレッドでデータベースや外部の Web のサービスに問い合わせることです。応答に 200 ミリ秒かかれば、その間に 4 回分のティックが失われます。
Paper のドキュメントは、Web のリクエスト、ファイルの読み書き、データベースなど時間のかかる処理は、非同期のタスクで行うよう案内しています。一方で、Bukkit の API の多くは非同期のタスクから安全に使えないため、ワールドを変える処理だけをメインのスレッドに戻す作りが必要です。
Paper の Watchdog のメッセージも、メインのスレッドの状態に HTTP や MySQL の処理が含まれていれば、そのプラグインの作者に報告するよう案内しています。データベースとの連動の作り方は、MySQL との連動で説明しています。
計測にもとづいて判断する
性能の改善は、計測から始めます。サーバーが重いと感じると、原因の見当を付けて設定を変えたくなります。しかし、見当が外れていれば、効果のない変更を重ねるだけでなく、別の不具合を生み、元の原因を見えにくくします。重さの原因は、プレイヤーの行動、ワールドの状態、プラグインの組み合わせで変わるため、経験や一般論だけでは特定できません。
KEY SELECT は、Minecraft に限らず、Web のシステム、データベース、ネットワーク、クラウドのどの技術でも、憶測ではなく計測にもとづいて判断します。進め方は次のとおりです。
- 基準を測る: 変更の前に、TPS、MSPT、CPU、メモリなどを、同じ条件で記録する
- 原因を特定する: プロファイラーで、どの処理に時間がかかっているかを数字で確かめる
- 1 つずつ変える: 変更は 1 度に 1 つにし、何が効いたかを分かるようにする
- 同じ条件で測り直す: 変更の前後を同じ人数と内容で比べ、効果を数字で確かめる
- 記録する: 測った値、変えた内容、結果を残し、次の判断と、障害のときの調査に使う
/tick query
Java 版 1.20.3 で追加された /tick コマンドでは、/tick query で、目標のティックの頻度、1 回のティックの平均の時間と、P50・P95・P99 (遅いほうから 50%・5%・1% の境目) を確認できます。平均が低くても P99 が高い場合は、時々起きる重さがあります。
spark
Paper には、1.21 から計測のプラグイン spark が組み込まれています (以前の Timings は非推奨になり、既定で無効)。
# TPS と MSPT を確認する
/spark tps
# 300 秒間、メインのスレッドの処理を記録する
/spark profiler start --timeout 300
# 100 ミリ秒を超えたティックだけを記録して、時々起きる重さの原因を探す
/spark profiler start --only-ticks-over 100 --timeout 300
# すべてのスレッドを記録する
/spark profiler start --thread * --timeout 300
結果は Web の画面で、処理の呼び出しの流れ、プラグインごとの時間、フレームグラフで確認できます。結果は既定で spark の外部のサーバーにアップロードされ、URL を知っている人なら見られるため、共有する相手に注意します (アップロード先は設定で変えられます)。
Folia: ワールドを分けて並列に計算する
PaperMC の Folia は、メインのスレッドが 1 つという前提そのものを変えたサーバーです。近くの読み込まれたチャンクを「リージョン」にまとめ、リージョンごとに 20 TPS のティックを、複数のスレッドで並列に計算します。Folia のドキュメントは「メインのスレッドはもうない」と説明しています。
Paper読み込まれた
Server thread 1 つ
Folia近くの
リージョンごとの
色の
1 つのリージョンが重くなっても、ほかのリージョンは遅れません。プレイヤーが広く散らばるサバイバルのサーバーなどに向いています。一方で、次の制約があります。
- ハードウェア: Folia のドキュメントは、物理コアが 16 以上あることを理想としています
- プラグイン: plugin.yml に
folia-supported: trueがあるプラグインだけを読み込みます。Folia のドキュメントは、互換性には「期待しないでほしい」と書いています - 作りの違い: Bukkit のスケジューラーはメインのスレッドが 1 つという前提のため、リージョン用の専用のスケジューラー (RegionScheduler、EntityScheduler など) に書き換える必要があります
- 向かない場面: 全員が 1 か所に集まる企画では、1 つのリージョンにまとまるため、並列にならない
Folia の設定の考え方
Folia の README は、ワールドを事前に生成したうえで、スレッドを次のように割り振る目安を示しています。約 330 人が参加したテストのサーバーをもとにした目安で、実際の使われ方を見て調整する必要があるとしています。
- 通信 (Netty): 200〜300 人あたり約 4 スレッド
- チャンクの読み書き: 200〜300 人あたり約 3 スレッド
- チャンクの処理 (事前生成した場合): 200〜300 人あたり約 2 スレッド
- 残りを、80% を上限にリージョンの計算 (
threaded-regions.threads) に割り当てる。プラグインやサーバーが、設定できないスレッドを使うため
導入の前に、最新の情報を確認する
Folia は開発が続いていて、入手の方法や推奨の設定も変わってきました。導入するときは、次の点を、その時点の公式の情報で確認します (2026 年 10 月時点の内容)。
- 入手の方法: PaperMC の公式サイトで、完成したファイルが配布されている (1.19.4 から 26.3 まで)。以前はソースコードから組み立てる必要があったが、今は公式の配布を使える
- 向いている規模: プレイヤーが散らばるサーバー (サバイバルや skyblock) で、人数がある程度多い場合に向く。物理コア 16 以上が理想
- 起動の設定: Java の起動のオプションは、PaperMC の Script Generator で作る。スレッドの割り当ては、上の目安をもとに別に調整する
- プラグイン: 使うプラグインが Folia に対応しているかを、Modrinth や Hangar の対応の一覧で確かめる。ViaVersion、BlueMap、Chunky、LuckPerms などは対応が示されている (2026 年 10 月 25 日に確認)。Geyser は Folia ではなく Velocity に入れる
- 効果: Paper との性能の差は、構成とプレイの内容で大きく変わる。自分の企画と同じ条件で計測してから決める
Folia を含めて、サーバーをどう分けるかは、サーバーを分ける構成で説明しています。
参考にした資料
- Tick (Minecraft Wiki)
- Commands/tick (Minecraft Wiki)
- Chunk (Minecraft Wiki)
- Server.properties (Minecraft Wiki)
- Commands/forceload (Minecraft Wiki)
- Minecraft: Java Edition 1.21.2 (Minecraft.net)
- Minecraft: Java Edition 1.21.5 (Minecraft.net)
- Minecraft: Java Edition 1.21.9 (Minecraft.net)
- World configuration (PaperMC)
- Folia FAQ (PaperMC)
- Chunky (Hangar)
- Paper (GitHub)
- Global configuration (PaperMC)
- Spigot configuration (PaperMC)
- Using the scheduler (PaperMC)
- Profiling (PaperMC)
- Command Usage (spark)
- Folia (GitHub)
- Folia overview (PaperMC)
- Folia のダウンロード (PaperMC)
サーバーの重さの原因の調査は、KEY SELECT に
spark での計測と結果の読み解き、メインのスレッドを止めているプラグインや設定の特定、改善の提案まで、KEY SELECT がお引き受けできます。
- 記事や技術資料の内容についてのご質問とサポートは、保守・サポートのご契約、またはスポットでのご契約をいただいたうえでお受けしています。無償でのサポートは行っておりません。
- 記事や技術資料の内容は、公開の時点の情報にもとづいて作成しています。内容の正確性、完全性、最新性を保証するものではなく、内容にもとづいて行った作業の結果について、弊社は責任を負いかねます。設定や変更は、ご自身の責任で、検証用の環境で確かめてから行ってください。
- 記事や技術資料の内容について、ご指摘や誤りにお気づきの点がありましたら、その他のお問い合わせからお知らせください。
- 技術資料の内容は、引用元として資料の名前と URL を明記していただければ、ご自身の動画や資料としてご利用いただけます。全文の Web サイトでの引用はご遠慮ください。