VPS版Nextcloudの本当の制限と苦手なこと
VPS上のNextcloudが苦手な条件を解説します。大量の小ファイル、巨大ツリーの同期クライアント、未設定のcron、Office利用に必要なメモリの下限を確認できます。
Nextcloud が苦手とする点(遭遇する順)
VPS 上の Nextcloud で問題になりやすい制限の多くは、ディスク容量ではなくファイル数とリクエスト数に起因します。200 GB の動画ファイルを収めたライブラリは、小規模なサーバーでも問題なく動作します。同じ 200 GB でも、400,000 個の小さなファイルに分散していると、フォルダー一覧の表示が遅くなり、データベースがサーバー上で最も負荷の高いプロセスになります。以下では、セルフホスト環境でこれらの制限に遭遇する順に説明します。最初に PHP のリクエストモデル、次に同期クライアント、続いてデータベースのデフォルト設定、バックグラウンドジョブ、最後にメモリを扱います。
「Nextcloud は遅い」と言われる原因の一部は、誰も変更していないデフォルト設定です。残りは設計上の特性であり、チューニングで解消することはできません。各セクションで、どちらに該当するかを説明します。
PHP が同時実行数の上限を決める仕組み
Nextcloud は PHP で記述されており、PHP アプリケーションは長時間稼働するサーバーではありません。各リクエストは、PHP-FPM(FastCGI process manager)プール内の 1 つのワーカープロセスが処理し、そのワーカーが開始から完了までリクエストを担当します。そのため、サーバーが同時に処理できるリクエスト数は pm.max_children です。各ワーカーは、それぞれ独自のメモリも確保します。
ここから 2 つの点が分かります。処理の遅いリクエストは処理が完了するまでワーカーを占有するため、1 人のユーザーが 4 GB のアップロードを組み立てている間、他のユーザーはそのスロットを利用できません。すべてのワーカーが処理中になると、新しいリクエストは socket backlog で待機します。プールのログには次のように記録されます。
WARNING: [pool www] server reached pm.max_children setting (5), consider raising it通常、最初に現れる症状は、手前にある Web サーバーから返される 504 です。
upstream timed out (110: Connection timed out) while reading response header from upstreamディストリビューションの標準プールでは、通常 pm.max_children = 5 が設定されています。共有サーバーでは妥当な推測ですが、同期クライアントが 12 台接続された Nextcloud には少なすぎます。実際に使用できるメモリを基準に設定してください。負荷がかかったワーカーの resident size を測定し、データベースとキャッシュのための余裕を残してから割り算します。
pm = dynamic
pm.max_children = 12
pm.max_requests = 500
php_value[memory_limit] = 512Mmemory_limit はリクエストごとの上限であり、割り当て量ではありません。ほとんどのリクエストは、その一部しか使用しません。残りのメモリを必要とするのは、プレビュー生成や大容量アップロードの組み立てです。そのため、この上限と子プロセス数は一緒に決める必要があります。
また、リクエスト間で共有されるアプリケーションメモリはありません。各リクエストで、設定、enabled apps、ルート、イベントリスナーなどのフレームワークが再度起動します。OPcache はコンパイル済みの bytecode を保持するため、これは解析ではなく実行です。APCu(alternative PHP cache)は、shared memory 内に小規模なローカル key-value store を保持します。そのため、管理画面の概要に表示される「No memory cache has been configured」という行が重要になります。これがない場合、メモリから取得できるはずの値も、すべてのリクエストでデータベースに問い合わせることになります。この部分は 設定 の問題です。その下にある、リクエストごとに 1 プロセスを使用するモデルは アーキテクチャ の問題です。
多数の小さなファイルは、ディスクに影響が出るよりはるか前に負荷になる理由
Nextcloud は、すべてのファイルとフォルダーのメタデータを 1 つのデータベーステーブル oc_filecache に保持します。そこには、パス、パスのハッシュ、サイズ、更新時刻、etag、storage id が含まれます。フォルダー一覧は、ディスク上の readdir ではなく、このテーブルに対するクエリです。書き込みが発生すると、ファイルの行を更新した後、親フォルダーを 1 つずつたどってルートまで新しいサイズと etag を反映します。1 回のアップロードで、1 回の HTTP リクエスト、複数の SQL ステートメント、さらに階層の深さごとに 1 回の更新が発生します。
転送もファイル単位です。同期プロトコルは WebDAV(web distributed authoring and versioning)であり、WebDAV は 1 回のリクエストで 1 ファイルを転送します。400,000 ファイルでは、400,000 回のリクエストが必要です。各リクエストで、認証、フレームワークの初期化、権限チェック、データベースへの書き込みが発生します。サーバー側の処理時間が 1 回あたり 25 ms なら、ペイロードを 1 バイトも数えない段階で、オーバーヘッドだけでほぼ 3 時間になります。これはベンチマークではなく、算術的な見積もりとして扱ってください。重要なのは、コストがファイルサイズではなくファイル数に応じて増えるという点です。
高速なストレージは、この問題の一部を改善します。小さなデータのランダム読み取りと書き込みでは、NVMe と SATA SSD の VPS ストレージの差が最も大きく現れるため、大規模なインスタンスでは NVMe を使用する価値があります。ただし、1 リクエストあたりのコストは変わりません。このコストはディスクではなく、PHP と SQL によって発生するためです。
1 つの結果は、誰もが一度は問題になります。Nextcloud の外部でサーバーにコピーしたファイルは、Nextcloud から見ると存在しません。行を書き込む処理が一度も実行されないためです。occ files:scan がツリーを走査して不足している行を書き込んだ後にだけ表示されます。大規模なツリーでは、この走査に長時間かかります。コンテナー環境でファイルがどこに配置されているか分からない場合は、Docker 上の Nextcloud のデータディレクトリ構成で別途確認できます。ここで重要なのはアーキテクチャです。ファイル一覧はデータベースにあります。
大きなツリーでデスクトップクライアントが遅くなる理由
同期クライアントは、評判ほど単純ではありません。書き込みが発生すると新しい etag がルートフォルダーまで伝播するため、クライアントは低コストの問い合わせを 1 回行うだけで、何か変更があったかどうかを確認できます。その後、etag が異なるフォルダーだけを下位へたどります。そのため、アイドル時のポーリング自体に大きなコストはかかりません。
それでも発生するコストはあります。初回同期ではすべてのフォルダーを走査し、フォルダーごとに 1 回の PROPFIND リクエストを送り、すべてのファイルをダウンロードします。ツリーの上位で名前を変更すると、その配下にあるすべての項目の etag が変わるため、クライアントはそのサブツリー全体を再確認します。また、クライアントは独自のローカルデータベースを保持し、ローカルファイルの stat も実行します。そのため、低速なノート PC のディスクや過剰に動作するウイルス対策ソフトによって、サーバーとは無関係の遅延が発生することがあります。
Client Push app がない場合、notify_push、接続中のすべてのクライアントがタイマーに従ってポーリングします。30 クライアントが、Web インターフェースと同じワーカープールに対して、一定のバックグラウンドリクエストを発生させます。notify_push はクライアントごとに 1 本の websocket を保持し、変更があったときに通知する小規模な独立サービスです。これにより、アイドル時のトラフィックの大部分を削減できます。負荷の高いインスタンスでは、導入効果が特に大きい追加機能の 1 つです。
マージはありません。2 人がオフライン中に同じファイルを編集すると、budget (conflicted copy 2026-08-22 141530).ods のような名前の競合コピーが作成され、人手で解決する必要があります。office service 経由で編集すれば、サーバー上で常に 1 つのコピーだけが正となるため、この問題を回避できます。ファイルを開くまでプレースホルダーとして表示する仮想ファイルは、Windows と macOS では安定しています。一方、Linux では安定するまでに時間がかかっているため、この機能を前提にワークフローを設計する前にクライアントのバージョンを確認してください。ポーリングは設定の問題です。ファイルごとに 1 回リクエストする方式はアーキテクチャ上の問題です。
デフォルトインストールで未設定の項目
新規にインストールした Nextcloud は動作します。ただし、一般的な手動インストールでは、まだ4つの項目が不足しています。これらはすべて、Settings の Administration、Overview で確認できます。
- メモリキャッシュがありません。Overview には「メモリキャッシュが設定されていません」と表示されます。APCu はほとんどコストをかけずに導入でき、同じデータベース参照の繰り返しを大幅に減らせます。
- データベースでファイルロックを管理しています。Nextcloud はファイルの書き込み中にそのファイルをロックします。Redis がない場合、このロックはデータベーステーブルに保存されます。そのため書き込み負荷が増え、リクエストが異常終了した後に古いロックが残ります。ユーザーにはファイルがロックされているというエラーが表示され、手動でクリーンアップしないと解消できません。
- データベースインデックスが不足しています。Overview には「データベースに不足しているインデックスがあります」と表示され、
occ db:add-missing-indicesが示されます。数百万行の filecache では、これらのインデックスの有無が高速な一覧表示と低速な一覧表示を分けます。 - SQLite が使用されています。手動インストールでは SQLite が選択される場合がありますが、ドキュメントではテスト用途と最小構成のインスタンスに限って推奨されています。書き込みが直列化されるため、アクティブなユーザーが2人いるだけでも過負荷になります。
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => [
'host' => 'localhost',
'port' => 6379,
],これらは特殊な設定ではなく、すべて 構成 に関する項目です。これらの判断が済んだ状態から始めたい場合は、TLS とバックアップを備えた Docker インストールを使用すると、スタックの一部としてキャッシュと cron コンテナも起動できます。
cron が設定されていないとバックグラウンドジョブが停止する理由
Nextcloud は、プレビューの生成、古いファイルバージョンの期限切れ、スケジュールに従ったごみ箱の消去、通知メールの送信、共有のクリーンアップなどの実処理をバックグラウンドジョブに移します。実行方法は 3 つサポートされていますが、デフォルト設定は最も信頼性が低い方法です。
AJAX モードでは、ブラウザーがページを読み込んだときに 1 件のジョブを実行します。1 週間誰もアクセスしない個人用インスタンスでは、1 週間何も実行されません。バージョンとごみ箱の内容は期限切れにならないため、ユーザーが削除したと思っているデータでディスクが埋まり続けます。プレビューも事前生成されないため、最初に写真フォルダーを開いたユーザーは、自分のリクエストでプレビューが生成される間、待たされます。最終的に概要画面には、最後のバックグラウンドジョブが数時間前に実行されたことと、「何か問題があるようです」と表示されます。得られる警告はこれだけです。
Webcron と system cron を使えば、どちらもこの問題を解消できます。system cron は Web サーバーのユーザーとして cron.php を 5 分ごとに実行し、コンテナー環境では専用の cron コンテナーから同じ処理を実行します。ドキュメントで指定されている間隔は 5 分で、ジョブの実行間隔もこれを基準に調整されています。
残るコストは、ジョブが直列化されることです。時間のかかるジョブ、プレビューの一括生成、ファイルスキャンが実行されると、後続のキュー内の処理がすべて遅延します。single-core VPS では、その実行処理が通常のリクエストと CPU を奪い合います。負荷の高いホストでは、近隣ユーザーの影響による CPU steal time により、実行時間が自分の測定値から予測した時間を超えることがあります。Configuration は、多くの放置されたインスタンスで最も効果の高い単一の対策です。
Office、Talk、プレビューを追加した場合のメモリ下限
通常の Nextcloud は控えめです。PHP pool、データベース、Redis、Web サーバーで構成されます。小規模なインスタンスなら 2 GB で余裕があります。実際に必要となる各機能は、それぞれ独自の下限を持つ別サービスです。
プレビュー。 デフォルトでは、プレビューは最初に要求された時点で生成されます。そのため、ユーザーはプレビューを必要とするリクエストの処理中に待たされます。Preview Generator アプリを使うと、この処理を cron に移せます。その代わり、cron 実行時に CPU を消費します。どちらの場合も、元画像ごとに異なるサイズのプレビューファイルが複数生成されます。そのため、写真ライブラリではファイル数が増え、前述の小ファイル問題にも直結します。大きな元画像では、Allowed memory size of 536870912 bytes exhausted として PHP のエラーログに記録されるメモリ制限にも達しやすくなります。preview_max_x と preview_max_y ではこれを防げません。これらは保存する最大プレビューサイズだけを指定する設定であり、元画像は縮小される前にフルサイズでデコードされるためです。元画像のサイズを制限する設定は preview_max_memory で、デフォルトは 256 MB です。Nextcloud はファイルヘッダーから画像の幅と高さを読み取り、1 ピクセルあたり 4 bytes として計算します。制限を超えるメモリが必要な画像は処理せず、プレビューの代わりにデフォルトのファイルアイコンを表示します。この計算では、プレビューサイズをどれだけ小さくしても、20,000 × 20,000 pixel の画像には約 1.6 GB が必要です。preview_max_filesize_image はファイルサイズに対する対応する上限で、デフォルトは 50 MB です。preview_max_memory は PHP の制限値より十分低く保ち、両方を際限なく引き上げないでください。
Office。 Collabora Online と OnlyOffice Docs は、それぞれ独自のサービスとして、通常は別のコンテナで動作します。それぞれに独自のランタイムとメモリが必要です。ドキュメントのセッションでは、PHP ではなくこれらのサービス側で CPU と RAM を消費します。応答性を確保するには、まず 1〜2 GB を見込んでください。サーバーのサイズを決める前に、2026 年 8 月時点のベンダーの最新要件も確認してください。両者の違いはリソース使用量だけではありません。セルフホスティングにおける違いについては、セルフホスティングでの OnlyOffice と Collabora の比較で説明しています。
Talk。 デフォルトでは、通話は WebRTC を使用してピアツーピアで接続され、サーバーはシグナリングメッセージだけを中継します。Talk の管理設定には、High Performance Backend(別のシグナリングサーバー)なしで 2 人を超える参加者が通話すると、参加者のデバイスで接続問題と高負荷が発生する可能性が高いと記載されています。多くのネットワークでは、coturn などの TURN(NAT 越しにリレーを使用して通信を通過させる仕組み)サーバーも必要です。メディアをリレーする場合、その通信は VPS を経由するため、帯域幅も実際のコスト項目になります。
全文検索。 Elasticsearch のインスタンスは、何もインデックス化していない段階でも、単体で 1 GB 以上のヒープを必要とします。
Nextcloud に必要な VPS の容量
ユーザー数だけでサイジングすると、実態を見誤ります。負荷は利用方法に大きく左右されるためです。300,000 ファイルのソースツリーを同期する開発者 5 人のほうが、ブラウザーでドキュメントを開くだけの 30 人より高い負荷を発生させます。以下は、実際のファイル数を使って検証するための開始点として利用してください。確定値ではありません。
- 1 vCPU と 1 to 2 GB: 1 人または 2 人で、ファイルとカレンダーだけを使用する場合。プレビューの生成量は厳密に制限し、office サービスは使用しません。このサーバーで発生する処理のうち、アップグレードと完全なファイルスキャンが最も時間のかかる処理になります。
- 2 vCPU と 4 GB: APCu、Redis locking、system cron を使用し、cron でプレビューを生成する、通常利用のユーザーがおおむね 5 to 15 人の場合。
- 4 vCPU と 8 GB: 同じユーザー数で office サービスも使用する場合、または office サービスなしで軽量なユーザーが 15 to 40 人いる場合。ここでメモリを最も消費するのは office セッションです。
- 4 vCPU 以上と 16 GB: High Performance Backend を使用する Talk、全文検索、または写真ライブラリ全体に対する一括プレビュー生成を行う場合。
ディスク容量は別に計算します。プレビュー、ファイルバージョン、ゴミ箱のデータは実データに追加されます。バックグラウンドジョブが実際に実行される場合にだけ、これらのデータは減少します。全体の費用がサブスクリプションより安くなるかどうかは、これらの数値によって決まります。セルフホストストレージと Dropbox の料金比較では、その計算方法を説明しています。
Nextcloud の制限のうち、設定で解決できるものとアーキテクチャ上のもの
次の項目は、午後の作業で改善できます。メモリーキャッシュと Redis によるロック、未作成のデータベースインデックス、バックグラウンドジョブのモード、FPM プールサイズと PHP のメモリー制限、OPcache のサイズ、notify_push、プレビューの上限です。これらをすべて設定したインスタンスは、同じハードウェア上でも、デフォルトインストールとは別のソフトウェアと言えるほど変わります。
次の制約は、どれだけ調整しても解消できません。
- 1 つのリクエストを 1 つのプロセスで処理します。同時実行数は RAM に制限され、遅いリクエストが 1 つのワーカーを処理終了まで占有します。
- ファイルごとに 1 行のデータベースレコードを持ち、サイズと etag をすべての親へ伝播します。コストはファイル数に応じて増加します。
- ネットワーク上ではファイルごとに 1 つのリクエストを送信します。多数の小さなファイルの同期では、帯域幅ではなくリクエストのオーバーヘッドが制約になります。
- ファイル機能を内包したグループウェアプラットフォームです。純粋な同期ツールでは読み込まない処理機構も、基本構成に含まれます。
- アップグレードは順番に適用します。メジャーバージョンはメンテナンスモードで 1 つずつ適用し、各段階でアプリの互換性問題を解消する必要があります。
これらはバグではありません。共有リンク、外部コラボレーター、モバイルクライアント、そしてそれらすべてで共通利用する 1 つのアカウントシステムを提供するための代償です。エンタープライズ版を購入するとサポートと一部の追加アプリを利用できますが、上記のリクエストモデルは変わりません。この点については、無料の Nextcloud 版に実際に含まれるもので説明しています。
VPS で Nextcloud を実行すべきでないケース
- 数台のマシン間で大規模なツリーを高速に同期することだけが目的の場合。P2P ツールは Web アプリケーションのデータベースにファイルごとの行を保持しないため、小さなファイルが多数ある場合のコストは大きく異なります。単純な同期における Syncthing と Nextcloud の比較
- 共有機能と Web インターフェースが必要ですが、データが数百万個の小さなファイルで構成されている場合。Seafile はファイルごとに 1 つのファイルを作るのではなく、ブロックストアにコンテンツを保存するため、必要なリソースの計算が変わります。その代わり、データはディスク上の通常のファイルではなくなります。Seafile と Nextcloud の比較
- サーバー上にすでにあるファイルをブラウザーで表示するだけで、同期クライアントやファイルごとのデータベース行が不要な場合。これは 軽量なセルフホスト型ファイルマネージャー の用途です。
- 実際の要件が 4 人で使う共有ドライブの場合。まずは軽量な構成から始め、後で機能を追加してください。Nextcloud のセルフホスト型代替製品
- 1 vCPU と 1 GB の環境で、ブラウザーからのオフィス編集を行いたい場合。この組み合わせでは要件を満たせません。どれだけチューニングしても解決しません。
組織外のユーザーとの共有、すべてのスマートフォンでのカレンダーと連絡先、ブラウザーでの編集、それらすべてへの単一のログインといったグループウェア機能が必要なら、Nextcloud を実行してください。問題は突然発生するのではなく、徐々に悪化します。ファイル数が増え、インストール環境にはキャッシュも cron もないままになり、ある日フォルダーを開くのに 8 秒かかるようになります。これらはすべて測定可能であり、多くの場合、問題が発生する前に対処できます。
FAQ
1 台の Nextcloud VPS で何人のユーザーを処理できますか?
ユーザー数よりも利用状況の影響が大きくなります。調整済みの 2 vCPU、4 GB のサーバーであれば、ファイル、カレンダー、連絡先を利用する通常ユーザー 5 から 15 人程度なら余裕があります。オフィスサービスを追加する場合は、通常 8 GB が必要です。最初に制限となるのは、一般に利用可能な RAM に対する PHP worker 数か、oc_filecache が大きくなった場合のデータベースです。そのため、プランのサイズを決める前に、実際のファイル数でテストしてください。
多数の小さなファイルがあると Nextcloud が遅くなるのはなぜですか?
すべてのファイルがデータベースの 1 行となり、個別の WebDAV リクエストも必要になるためです。フォルダー一覧の取得では SQL クエリが実行されます。書き込みではファイルの行が更新され、その後、すべての親フォルダーのサイズと etag も更新されます。転送では、認証とフレームワークの初期化を伴う HTTP リクエストごとに 1 ファイルが処理されます。そのため、負荷は合計サイズよりもファイル数に左右されます。高速なストレージを使うとディスク処理の時間は短縮できますが、リクエストごとに発生する処理は残ります。
Nextcloud に Redis は必要ですか?
単一ユーザーであれば必要ありません。複数ユーザーで利用する場合は必要です。Redis がない場合、トランザクション型のファイルロックはデータベーステーブルを介して実行されます。そのため書き込み負荷が増え、リクエストが異常終了した後に古いロックが残ります。ユーザーには、ファイルがロックされていることを示すエラーが表示されます。通常は、ローカルキャッシュに APCu、ロックに Redis を使用し、どちらも config.php で設定します。
Nextcloud のバックグラウンドジョブを設定しないとどうなりますか?
デフォルトの AJAX モードでは、ページを読み込むたびに 1 つのジョブが実行されます。そのため、ログイン中のユーザーがいなければ何も実行されません。プレビューは事前生成されず、ファイルのバージョンとゴミ箱の内容も期限切れにならないため、ディスク使用量が増え続けます。通知メールの送信も停止します。最終的に管理画面の概要には、最後のバックグラウンドジョブが数時間前に実行され、何らかの問題があるようだと表示されます。5 分ごとに system cron を実行するよう切り替えることが解決策です。コンテナでインストールしている場合は、専用の cron コンテナから実行します。