ulimitコマンドでリソース制限を確認・設定する方法|open filesの上限変更や永続化も


この記事の監修:宮崎智広(Linux教育歴15年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips > ulimitコマンドでリソース制限を確認・設定する方法|open filesの上限変更や永続化も
「サーバーで突然『Too many open files』が出て、Apacheが落ちた」
「ulimit -n 65535 を設定したのに、再ログインしたら元に戻る」
こういう相談は、Linuxサーバーを運用していると避けて通れないトラブルです。

この記事では、Linuxのリソース制限を司る ulimit コマンドの実践的な使い方を解説します。現在値の確認から、open files(ファイルディスクリプタ)の上限変更、systemd時代の正しい永続化手順、そしてよくあるトラブルの切り分け方まで、現場で必要な知識を一通りカバーします。動作確認はRHEL 9.4 / AlmaLinux 9.4 / Ubuntu 24.04 LTSで行っています。

この記事のポイント

・ulimit -a で現在のリソース制限を一覧表示できる
・open filesは「ulimit -n」で変更、恒久化は limits.conf か systemd 側で設定
・ソフトリミット/ハードリミットの違いを理解すると制限設計が楽になる
・Too many open files の原因調査は lsof とセットで行うのが鉄則


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

なぜulimitが必要なのか?リソース制限の仕組み

Linuxではプロセスごとに「同時に開けるファイル数」「使える仮想メモリ量」「生成できるプロセス数」などに上限があります。これらの上限を「リソース制限(resource limit)」と呼び、1人のユーザーや1つのプロセスが暴走してサーバー全体を巻き込むことを防ぐ安全装置として機能しています。

ulimit は、このリソース制限をシェルから確認・変更するためのビルトインコマンドです。/bin/ulimit という外部コマンドは存在せず、bash や zsh が内部で実装しています。

制限は2種類あります。

ソフトリミット(soft limit):現在適用されている上限。ユーザー自身がハードリミットの範囲内で自由に上げ下げできる
ハードリミット(hard limit):ソフトリミットの上限値。一般ユーザーは下げることはできても上げられない(root だけが変更可能)

よくある「ulimit -n 65535 としたのにエラーになる」は、ほぼ全てハードリミットに阻まれているケースです。

ulimitコマンドの基本的な使い方

1. 現在のリソース制限を一覧表示する

まずは現状把握です。-a オプションで、全てのリソース制限をまとめて表示できます。

# ソフトリミットの一覧 $ ulimit -a real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15085 max locked memory (kbytes, -l) 8192 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 15085 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited

よく使うのは -n(open files)と -u(max user processes)の2つです。「open files 1024」は初期状態ではかなりタイトで、本番のWeb/DBサーバーではまず足りません。

2. ソフトリミットとハードリミットを見分ける

-S でソフト、-H でハードの現在値をそれぞれ確認できます。

# ソフトリミット(現在適用されている値) $ ulimit -Sn 1024 # ハードリミット(ユーザーが上げられる上限) $ ulimit -Hn 524288

この例だと「今は1024だが、524288までなら一般ユーザー権限でも上げられる」という意味です。ハードリミット自体を上げたい場合はroot作業か、後述の limits.conf / systemd の設定が必要です。

3. open filesの上限を一時的に変更する

現在のシェルだけで上限を変更する場合は、数値を直接指定します。

# ソフトリミットのみ65535に変更(ハードリミットは据え置き) $ ulimit -Sn 65535 # ソフト・ハード両方を65535に変更(root権限が必要な場合あり) $ ulimit -n 65535 # 確認 $ ulimit -n 65535

注意点として、この変更は 現在のシェルとその子プロセスにしか引き継がれません。別のターミナルを開いたり、systemd経由で起動したサービスには影響しません。恒久化したい場合は次のセクションへ進んでください。

ulimit設定を永続化する3つの方法

「ulimit -n 65535 としたのに再起動で戻る」を解決するには、どのレイヤーで制限をかけるかを正しく選ぶ必要があります。

1. /etc/security/limits.conf(ログインセッション向け)

SSHログインやsu実行時に適用される制限を設定します。対話ログインや su - から起動するアプリで有効です。

# /etc/security/limits.conf に追記 # <domain> <type> <item> <value> * soft nofile 65535 * hard nofile 65535 apache soft nofile 131072 apache hard nofile 131072 # 設定を有効にするには一度ログアウト→再ログイン

domainには「*(全ユーザー)」「ユーザー名」「@グループ名」を指定できます。type は soft / hard / - (両方)、item は nofile(open files)、nproc(プロセス数)などです。

この設定はPAMの pam_limits.so が読み込んでいるため、/etc/pam.d/login や /etc/pam.d/sshd で session required pam_limits.so が有効になっている必要があります(ほとんどのディストリビューションではデフォルトで有効です)。

2. /etc/security/limits.d/ に個別ファイルを置く

本番運用ではこちらを推奨します。limits.conf 本体を触らず、アプリごとに独立したファイルを置いた方が管理が楽で、パッケージアップデート時の競合も防げます。

# /etc/security/limits.d/90-nginx.conf を新規作成 nginx soft nofile 131072 nginx hard nofile 131072 # ファイル名は「番号-用途.conf」の形で付けると読み込み順が明確

3. systemd unit ファイル(サービス向け・最重要)

ここが現代Linuxで最も重要なポイントです。systemdから起動するサービス(httpd / nginx / mysqld など)には limits.conf の設定は適用されません。systemd はログインセッションを経由しないため、PAM の pam_limits.so が走らないからです。

サービスごとに unit ファイルで制限を指定します。

# override ファイルを作成(パッケージ本体は触らない) # systemctl edit nginx.service [Service] LimitNOFILE=131072 LimitNPROC=65535 # 保存後に設定を反映 # systemctl daemon-reload # systemctl restart nginx # 適用値の確認 # systemctl show nginx -p LimitNOFILE LimitNOFILE=131072

サービスが実際にいくつでファイルを開けているかは /proc/PID/limits で確認できます。

# nginx のマスタープロセスの制限を確認 # pgrep -f 'nginx: master' | head -1 | xargs -I{} cat /proc/{}/limits | grep 'open files' Max open files 131072 131072 files

limits.conf と systemd の両方を設定してもロスはありませんが、実際に効いているのは「サービスを起動した親プロセスの制限」です。迷ったら /proc/PID/limits を直接見るのが確実です。

実務でよく使うulimitのTips

coreファイルの出力を一時的に許可する

プロセスがクラッシュしたときの解析用に、coreファイルを吐かせたいケースです。デフォルトは core file size = 0 で出力されません。

# coreファイルの上限を無制限に $ ulimit -c unlimited # 出力先を指定(systemd環境では systemd-coredump に任せるのも可) # echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern # 確認 $ ulimit -c unlimited

本番サーバーで常時 unlimited にすると、クラッシュ時にディスクを食い潰す危険があります。障害解析のときだけ有効化し、終わったら戻す運用が安全です。

シェルスクリプト内でリソース制限をかける

大量のファイルを開くバッチ処理や、暴走を防ぎたい処理の前に、スクリプト先頭でソフトリミットを絞る使い方があります。

#!/bin/bash # このスクリプト内だけで仮想メモリを2GBに制限 ulimit -v 2097152 # ここから先のコマンドは全て2GB制限下で動く ./heavy_batch.sh

ulimitは現在のシェルプロセスに対して効くため、サブシェル(括弧)や子プロセスには継承されても、親シェルには戻りません。

ログインシェル起動時に自動適用する

特定ユーザーが対話ログインしたときだけ制限を変えたい場合は、~/.bashrc や ~/.bash_profile に書いておく方法もあります。ただしこれはユーザー自身が書き換えられてしまうため、強制したい場合は limits.conf 側で設定してください。

「Too many open files」が出た時の対処法

現場で最もよく遭遇するのがこのエラーです。切り分け手順を整理しておきます。

1. どのプロセスが開きすぎているかを特定する

まずは犯人探しから。lsof でプロセス別の open files 数を集計します。

# プロセスごとのオープンファイル数ランキング(TOP10) # lsof -n | awk '{print $2}' | sort | uniq -c | sort -rn | head -10 12453 3421 8721 3388 1024 2891 ... # PID 3421 の詳細 # ps -p 3421 -o pid,user,comm,args PID USER COMMAND COMMAND 3421 nginx nginx nginx: worker process

lsof を使った詳しいオープンファイル・ポート調査の手順は Linux ポート確認の全コマンド にまとめています。TCP/UDPの一覧まで合わせて確認したい場合はそちらが便利です。

2. プロセスごとの現在値と上限値を確認する

/proc/PID/limits が一次情報です。systemctl show の値と /proc/PID/limits が食い違っている場合は、sysctl や fs.file-max 側でもブロックされている可能性があります。

# 対象プロセスの open files 制限 # cat /proc/3421/limits | grep 'open files' Max open files 1024 4096 files # システム全体の上限(これを超えると誰も開けない) $ cat /proc/sys/fs/file-max 9223372036854775807 $ sysctl fs.file-nr fs.file-nr = 12320 0 9223372036854775807 # 左から「現在の使用数」「未使用だが確保中」「システム上限」

3. 上限を引き上げて反映する

原因がサービスのunitファイル側にあるなら systemctl edit で LimitNOFILE を上げて systemctl restart。ログインセッション経由なら limits.d で調整します。

サーバーが高トラフィックを捌く場合、Apacheのタイムアウトやキープアライブ設定と組み合わせてチューニングすると効果が出やすくなります。Apache側の値を見直したい方は Apache タイムアウト設定の詳細 を参考にしてください。

「ulimit: open files: cannot modify limit: Operation not permitted」が出る

一般ユーザーでハードリミットより上の値を指定した時に出ます。対処は以下の順に確認します。

ハードリミット自体を上げる:/etc/security/limits.conf か limits.d にhard nofileを追記してログインし直す
rootで上げる:sudo で実行するか、systemd側で LimitNOFILE を設定する
kernel.pid_max や fs.nr_open を確認:kernel側の上限(/proc/sys/fs/nr_open)を超える値は指定できない

本記事のまとめ

ulimit は「シェルから見えるリソース制限」ですが、実体はカーネル・PAM・systemd の3層で管理されています。トラブル時はこの3層のどこで止まっているかを切り分けるのが解決への最短ルートです。
やりたいこと コマンド
全リソース制限を一覧表示 ulimit -a
open filesの現在値を確認 ulimit -n
ハードリミットを確認 ulimit -Hn
open filesを一時的に65535に変更 ulimit -n 65535
coreファイル出力を許可 ulimit -c unlimited
特定プロセスの制限を確認 cat /proc/PID/limits
systemd管理サービスの制限を上書き systemctl edit サービス名
システム全体のfile-maxを確認 sysctl fs.file-nr
ulimit は単体のコマンドというより、Linuxのリソース管理体系の入り口です。limits.conf、systemd、/proc 配下の値を合わせて見る癖をつけておくと、障害対応のスピードが一段階上がります。他の現場必須コマンドも押さえておきたい方は Linux 基本コマンドの解説 から関連テーマをたどってみてください。20年以上サーバー運用をしてきた経験から言うと、ulimit の扱いに慣れているかどうかは、中堅エンジニアと新人の差が出やすいポイントの1つです。

「Too many open files」で毎回ヒヤッとしていませんか?

ulimitやsystemdのLimitNOFILE設定は、正しい「型」を知っていれば数分で対応できますが、知らないと障害のたびに手探りで消耗します。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。


無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として15年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。