MacでSSHが5倍速い件を真面目に考察する
はじめに
Xでちょっと話題になったアレ。んなわけあるかいなって思ったけど、ちょっと思い当たるフシもあるので(AIと一緒に)真面目に考える。
直感的に「いやそれは盛りすぎでしょ」と思いつつ、よく考えると「条件によっては5倍もあり得るか…?」とも思う。本記事では、この主張をプロトコル・実装・OS・ハードウェアの各レイヤーに分解して、「5倍」が成立しうる条件と、フェアな比較での実態を真面目に考察してみる。
結論を先に言うと、
- 同一OpenSSHでフェアに測れば5倍は出ない
- ただし測定条件が「不公平」だと簡単に5倍以上の差が出る
- 多くの場合、SSHプロトコルじゃなくて周辺レイヤー(ターミナル描画・名前解決・セキュリティソフト)の問題
です。
まず「SSH接続速度」を分解する
「速い/遅い」と言うとき、SSHには実は4つの異なるメトリクスが混在している。これを切り分けないと議論にならない。
| メトリクス | 測り方 | 主なボトルネック |
|---|---|---|
| 接続確立時間 | time ssh host exit |
TCP・DNS・鍵交換・認証 |
| スループット | dd | ssh host 'cat > /dev/null' |
暗号処理・ネットワーク帯域・ディスクI/O |
| 対話レイテンシ | キー入力→画面反映の体感 | RTT・ターミナル描画 |
| 大量出力速度 | ssh host 'cat large.log' |
ターミナル描画・帯域 |
X上の「5倍」がどれを指しているかで、説の妥当性は大きく変わる。
各シナリオで「5倍」は成立しうるか
接続確立時間:ほぼ差なし
WindowsのOpenSSH(Win10 1809以降に組み込み)は、MicrosoftがPortable OpenSSHを移植したもので、macOSの /usr/bin/ssh と同じコードベースである。暗号処理はどちらもAES-NI/SHA拡張で加速されるため、純粋なハンドシェイクに5倍の差がつく要素は理論上ない。
ただしWindows側にだけ初回ペナルティが乗る典型シナリオは存在する(後述)。これが重なると初回数秒の差は出る。
スループット:差はあってもハード依存
純粋なTCPスループットは、暗号スループットとネットワークで決まる。M3/M4のSHAアクセラレータは速いが、最近のRyzen / Core Ultraも同等。むしろローカル側のNVMe速度が scp のボトルネックになるケースが多く、ここはApple Silicon機が有利になりやすい。
ただし「SSHが速い」というよりは「ストレージが速い」話。
対話レイテンシ:ここが本命
これが「体感5倍」の正体である可能性が高い。理由はSSHではなくターミナルレンダラの差。
- macOS: Terminal.app は遅いが、iTerm2 / Ghostty / WezTerm / Alacritty がGPUレンダリングで爆速
- Windows: 旧
conhost.exeは壊滅的に遅い。Windows Terminalで大幅改善されたが、PowerShellパイプライン経由だと変換オーバーヘッドが残る
tail -f でログを追ったり、htop でリアルタイム表示すると、SSHプロトコルじゃなくて画面の描画速度で差が出る。これなら5倍どころか10倍以上の差が出ても不思議じゃない。
大量出力:完全にターミナル依存
cat 100MB.log のような大量出力を流したときの差は、ほぼ100%ターミナルエミュレータの描画性能で決まる。GhosttyとPowerShell + conhost で比較すれば、二桁倍の差は普通に出る。
Windows側だけ遅くなる要因
ではなぜ「Windowsだと遅い」と感じやすいのか。要因を層ごとに整理する。
ネットワークスタック由来
getaddrinfo の挙動: WindowsはデフォルトでIPv6 → IPv4の順で問い合わせる。サーバがAAAAレコードを持っていなかったり、ネットワーク自体がIPv6非対応だと、タイムアウト待ちの段差が初回接続だけ乗る。Macも IPv6優先だが、Happy Eyeballs (RFC 6555/8305) の実装が攻めていて、両方並列で投げて速い方を採用する。
WFP (Windows Filtering Platform) の層の厚さ: カーネルレベルで複数のフィルタドライバが順番にパケットを検査する。古いLSP残骸・VPNクライアント・プロキシ系ソフトが残っていると、累積で数十ms単位の遅延が乗る。
netsh winsock show catalog
で見える層がすべてコストになる。Macには対応する概念がない(PFやNECPはあるが、ここまで肥大化しない)。
Wi-Fiドライバ品質のばらつき: Intel / Realtek / Broadcom / Killer等でかなり挙動が違う。特にRealtekやKiller系は省電力モード復帰がもっさりして、IDLE状態からの最初のパケットだけ遅延する。Apple Silicon機は自社Wi-Fiチップ + 自社ドライバで一貫性がある。
セキュリティソフト由来
Microsoft Defender + リアルタイム保護: 標準でも初回TCPストリームを検査する。普通の用途では無視できるが、ssh exit を何度も繰り返すような測定だと初回ペナルティが目立つ。
企業EDR (CrowdStrike Falcon / SentinelOne / Carbon Black 等): DLLインジェクションでネットワークAPIをフックし、プロセスごとに挙動を見ている。ssh.exe のような短命プロセスだとフックのアタッチ/デタッチが毎回走るため、コストが乗りやすい。
SSLインスペクションプロキシ: 企業ネットワークだとZscaler/Netskope等がSSHトラフィックも経由する構成がある。Mac/WindowsでBYODポリシーが違って「Macは素通り、Windowsは強制経由」みたいなケースは、もはやSSHの問題ではないが…
SSH実装・設定由来
GSSAPI Authentication のタイムアウト: 両方ともデフォルトで GSSAPIAuthentication yes だが、Kerberos環境がない場合、Windows側のSSPI実装がドメインコントローラを探しに行ってタイムアウトするまで待つことがある。~/.ssh/config に以下を追加すると別物になることがある。
Host *
GSSAPIAuthentication no
WSL2経由のssh: Hyper-V仮想スイッチ + NAT + WSL内部のLinuxスタックを経由するため、物理NIC直で出るMacより構造的に不利。WSL2のミラーモード/NAT設定によっても差が出る。
PuTTY / Tera Term等の独自実装: chacha20-poly1305@openssh.com や curve25519-sha256 等のモダン暗号スイートに非対応のことがあり、古いAES-CBC + SHA1にフォールバックして遅くなる。これは「SSHの速度差」というより実装そのものの差。
PowerShellパイプライン由来
ssh.exe の出力をPowerShellで受けると、
- UTF-16 ↔ UTF-8変換
- CRLF変換
- オブジェクトパイプライン化
が挟まる。cmd.exeなら多少マシ。Macのzsh/bashはバイトストリームをそのまま流すだけなので、ここで詰まることはない。
Macが対話レイテンシで有利な理由
逆側から見て、Macが「速く感じる」要因を整理する。
ターミナルエコシステムが強い
iTerm2、Ghostty、WezTerm、Alacrittyなど、GPUレンダリング前提の高速ターミナルが無料で揃っている。Windows Terminalは大幅に改善されたが、それでも cat large.log の流速では Ghostty や Alacritty に分がある。これがSSH越しの tail -f 体感に直結する。
UNIXネイティブで変換レイヤーがない
シェル (zsh/bash) が一級市民で、tty/pty実装が30年以上枯れている。stty、ANSIエスケープシーケンス、UTF-8、ジョブコントロール、シグナル伝播がすべて素直に動く。Windowsは ConPTY (Win10で実装) でようやくpty相当になったが、まだ細かい挙動差が残る。
mDNSResponder と名前解決の速さ
ローカルホスト名解決にBonjour/mDNSがOSレベルで統合されていて速い。.local ドメインやLAN内ホストへの初回接続で、Windowsだと数百ms待つようなケースでもMacは即座に解決する。
SSH agent + Keychain統合
ssh-agent がKeychain連携でログイン中常駐していて、鍵のパスフレーズ入力がOS認証に統合される。
Host *
UseKeychain yes
AddKeysToAgent yes
Windows側は ssh-agent サービスを手動で有効化する必要があり、デフォルトでは停止している。これも「初回がもたつく」体感差の一因。
ハードウェア最適化
Apple SiliconのAES/SHAアクセラレータに加え、NVMeのシーケンシャル/ランダムREADがどちらも速いので、scp/rsync のローカル側ディスクI/Oがボトルネックになりにくい。Windowsノートは SSD の品質がメーカー依存でばらつく。
キーリピートとIME挙動
地味だがデカい話。macOSはキーリピート開始ディレイと連射速度を独立して設定でき、Karabiner-ElementsでさらにOS手前で扱える。Windowsはレジストリ経由でしか触れず、IMEオン状態での挙動が不安定になることがある。SSHの問題ではないが、「ターミナルでの操作レイテンシ」という体感に効く。
真面目に検証する方法
ここまで言っておいて測らないのも気持ち悪いので、フェアに測るためのテンプレートを置いておく。
1. 接続確立時間の純粋計測
# ControlMasterを無効にして毎回まっさらな接続を測る
for i in {1..10}; do
time ssh -o ControlMaster=no -o ControlPath=none host exit
done
real だけでなく user と sys を見るのが大事。real が大きいのに user+sys が小さければ、それはSSHのCPU処理ではなく待ち時間(DNS・ネットワーク・認証応答)。
2. ボトルネック箇所の特定
ssh -vvv host exit 2>&1 | ts '[%H:%M:%.S]'
ts (moreutils) でタイムスタンプを付けると、どのフェーズで止まっているかが秒単位で見える。具体的には、
-
Connecting to host...で詰まる → DNS -
Connection establishedの後で止まる → 鍵交換 -
Authentications that can continueの後で止まる → 認証 (GSSAPI / publickey の試行)
を切り分けられる。
3. スループット計測
# 暗号オーバーヘッド込みの帯域
dd if=/dev/zero bs=1M count=1000 status=progress \
| ssh host 'cat > /dev/null'
ローカル側のディスクI/Oを除外したい場合は /dev/zero を使う。実ファイルで測ると Mac の NVMe が有利すぎて SSH の比較にならない。
4. ターミナル描画を除外したスループット
ssh host 'yes | head -c 100M' > /dev/null
出力を /dev/null に捨てることで、ターミナル描画コストを排除できる。これと、
ssh host 'yes | head -c 100M'
(出力を画面に流す)を比較すると、SSHの問題かターミナルの問題かが一発で分かる。
5. 暗号スイートを揃える
ssh -c chacha20-poly1305@openssh.com \
-m hmac-sha2-256-etm@openssh.com \
-o KexAlgorithms=curve25519-sha256 \
host exit
PuTTY等の独自実装と比較する場合、暗号スイートをモダンなものに揃えないとフェアじゃない。
結論
「MacのSSHが5倍速い」という主張は、
- 同じOpenSSH同士の純粋なSSH性能比較としては成立しない
-
「Windows Terminal + ssh.exe vs Ghostty + ssh on Mac で
tail -fした体感」なら成立しうる(実態はターミナル描画とパイプライン処理の差) - 「WSL2のssh vs Mac native」や「Defender/EDR入りWindows vs クリーンなMac」なら初回接続で数倍は普通
つまり「5倍」は比較条件が不公平なときに観測される数字としては妥当で、フェアな条件で5倍出たら、それはSSHではなく別の問題(DNS、AV、NIC設定、ターミナル選択)を踏んでいる。
Macが体感速い理由は「SSHプロトコルが速い」ではなく、
- GPUレンダリングのターミナルが充実
- UNIXネイティブで変換レイヤーがない
- 名前解決と鍵管理がOS統合されている
- 自社ハードウェアで一貫した最適化
の積み上げによる周辺レイヤーの差である。WindowsでもGhostty相当を使い、Defenderを適切に除外し、WSL2を経由せず、GSSAPIAuthentication no を入れて、ssh-agent を常駐させれば、ほぼ差はなくなる。
「SSHが速いから Mac」ではなく「ターミナル周辺の総合体験が速いから Mac」、というのが正しい言い回しに思うます。
暇な人は実際に検証してみてくださいな。
Discussion
自分の前の環境(Win10)だと特定のサーバーにSSH接続するときに
sshコマンドを入力してからパスワード入力待機になるまで5秒位かかってたんですよね...Win11にクリーンインストールしたら発生しなくなって未だに原因がよくわかってないです
もしかしたらそれかも