「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 とセットで行うのが鉄則
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜ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
3. open filesの上限を一時的に変更する
現在のシェルだけで上限を変更する場合は、数値を直接指定します。# ソフトリミットのみ65535に変更(ハードリミットは据え置き) $ ulimit -Sn 65535 # ソフト・ハード両方を65535に変更(root権限が必要な場合あり) $ ulimit -n 65535 # 確認 $ ulimit -n 65535
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 # 設定を有効にするには一度ログアウト→再ログイン
この設定は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
# nginx のマスタープロセスの制限を確認 # pgrep -f 'nginx: master' | head -1 | xargs -I{} cat /proc/{}/limits | grep 'open files' Max open files 131072 131072 files
実務でよく使う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
シェルスクリプト内でリソース制限をかける
大量のファイルを開くバッチ処理や、暴走を防ぎたい処理の前に、スクリプト先頭でソフトリミットを絞る使い方があります。#!/bin/bash # このスクリプト内だけで仮想メモリを2GBに制限 ulimit -v 2097152 # ここから先のコマンドは全て2GB制限下で動く ./heavy_batch.sh
ログインシェル起動時に自動適用する
特定ユーザーが対話ログインしたときだけ制限を変えたい場合は、~/.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 |
「Too many open files」で毎回ヒヤッとしていませんか?
ulimitやsystemdのLimitNOFILE設定は、正しい「型」を知っていれば数分で対応できますが、知らないと障害のたびに手探りで消耗します。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます