エックスサーバーのTTFBは実測101ms、キャッシュが切れると326ms|自サイトに270回リクエストして内訳を分解した

本記事には広告(アフィリエイトリンク)を含みます。

レンタルサーバーの「表示速度」は、各社が速さを謳う一方で、契約者が自分で確かめた数字はあまり出てきません。PageSpeed Insightsのスコアは出しやすいものの、あれは総合点なので「サーバーが遅いのか、テーマが重いのか、回線なのか」を切り分けられません。

そこで、このブログ自身(エックスサーバー スタンダードプラン+WordPress+Cocoon)に対して、日本国内の家庭向け回線から 約270回のHTTPリクエストを投げて、TTFBを段階ごとに分解しました。DNS・TCP握手・TLS握手・サーバー応答の4つに分け、さらにサーバー側キャッシュが効いている時と切れている時を比較し、最後にキャッシュの寿命そのものを実測しています。

数値はすべて実際に計測したものです。計測に使っていない推定値を書く場合は「計算値」と明記します。生データは記事末尾の条件どおりに再現できます。

先に結論

  • 当サイトのTTFB中央値は101.2ms(HTML4URL×20回=80サンプル、実測)。Googleが「良好」とする0.8秒の12.7%に収まっている。
  • ただしその101msのうち76.3ms(75.4%)は接続の確立(DNS 1.3ms+TCP握手 12.9ms+TLS握手 62.1ms)で、サーバーが応答に使っているのは24.9msだけ(実測)。1往復分のRTT 12.9msを引くと、サーバー内部の処理は約12ms(計算値)。
  • サーバー側キャッシュが切れていると、同じページのTTFBが101.6ms→326.2msに増える(実測)。サーバー応答だけを見ると25.3ms→249.9msで9.9倍。差の224.6msがWordPressのPHP生成に相当する。
  • そのキャッシュの寿命は60秒(58秒後は命中、62秒後は不命中。実測)。しかも命中しても寿命は延びない。作成から60秒で必ず捨てられる。
  • つまりキャッシュは「毎分1人以上が来るページ」でしか効かない。当サイトのように月45表示(=0.001PV/分)の規模では、ほぼ全員が326msの生成パスを踏んでいる(計算値)。速度対策として最初に効くのはサーバーの乗り換えではなくアクセスを増やすこと、という逆説的な結論になる。
  • 転送量の内訳はHTMLが12.4%、フォントが25.9%。単体最大はFont Awesomeのwoff2で77KB、HTML本体の1.81倍あった(実測)。

計測対象のサーバーは エックスサーバー のスタンダードプラン(12ヶ月契約、当サイトが2026年7月から運用中)です。料金は2026年9月25日時点の公式掲載値で、12ヶ月契約 月額1,100円・初期費用0円(キャンペーン期間中の価格で、公式ページに「2026/9/7 17:00 – 2026/10/5 17:00までのキャンペーン価格が適用されています」との注記あり)。以下の数値はすべてこの環境での実測です。

計測の条件

速度の話は条件を伏せると意味がなくなるので、先に開示します。

項目 内容
計測日時 2026年9月25日 05:09〜05:35(JST)
計測点 日本国内の家庭向け光回線。データセンターやクラウドからではない
計測ツール curl(HTTP/2、brotli有効)。毎回新規接続で、DNSキャッシュは温まった状態
対象 https://biboroku-lab.com/ (エックスサーバー スタンダードプラン、WordPress+Cocoon、公開記事10本)
総リクエスト数 約270回(タイミング計測170、キャッシュ寿命実験34、アセット計測57ほか)
取得した値 time_namelookup / time_connect / time_appconnect / time_starttransfer / size_download
集計 中央値。Python 3で集計・検算
測っていないもの ブラウザのレンダリング時間、LCP・CLSなどのCore Web Vitals、他社サーバーとの比較

重要な限界が2つあります。ひとつは、これは1本の回線・1つのサイトの数字であって、エックスサーバー全体の性能ではないこと。共用サーバーは同居しているサイトの状況で変わります。もうひとつは、他社との比較をしていないことです。比較するなら同じ日・同じ回線・同じテーマ・同じ記事数で並べる必要があり、それは別の検証になります。ここで分かるのは「自分のサイトの101msが、何に使われているか」だけです。

TTFB 101msの内訳 ― 4分の3は接続確立

まずHTML 4URL(トップと記事3本)をそれぞれ20回、合計80サンプル取りました。中央値と分布は次のとおりです。

統計量 TTFB(実測)
最小 98.9ms
中央値 101.2ms
平均 113.5ms
90パーセンタイル 109.8ms
最大 342.7ms

平均が中央値より12ms大きいのは、80回のうち数回、340ms級のスパイクが出たためです。こういう分布では平均よりも中央値とp90を見たほうが実態に合います。p90が109.8msということは、10回に9回は110ms以内で最初のバイトが返っている、ということです。

次に、その101.2msを段階ごとに割りました。

段階 所要(実測・中央値) 割合 誰の責任か
DNS解決 1.3ms 1.3% DNSキャッシュ(温まった状態)
TCP握手 12.9ms 12.7% 回線とサーバーの物理距離(往復1回分)
TLS握手 62.1ms 61.4% 暗号化のネゴシエーション(往復+鍵計算)
サーバー応答 24.9ms 24.6% サーバー本体
合計(TTFB) 101.2ms 100% ―

ここが今回いちばん意外だった点です。TTFBの75.4%はサーバーが仕事を始める前に消えている。TLS握手だけで62.1msあり、これはサーバー応答の2.5倍です。

さらに、サーバー応答の24.9msにも往復1回分が含まれています。TCP握手の12.9msが1RTTの目安なので、これを引くとサーバー内部で実際に処理していたのは約12ms(計算値)。つまりこの構成では、サーバーの速さを1桁改善しても体感のTTFBは101ms→89ms程度にしかなりません。

なおWeb標準の定義では、TTFBはリダイレクト・Service Worker起動・DNS・接続とTLS・リクエストまでを合計した値とされています(Google「Time to First Byte (TTFB)」)。今回の内訳はこの定義に沿った分解です。同記事はTTFBの良好しきい値を0.8秒以下、悪いを1.8秒超としつつ、TTFBはCore Web Vitalsではないため「必ずしも良好しきい値を満たす必要はない」とも明記しています。101msという数字は良好しきい値の12.7%ですが、それ自体が検索順位を押し上げるわけではない、という前提で読む必要があります。

キャッシュが切れていると250ms遅くなる

ここからが本題です。同じURLに ?t=1758… のようなクエリ文字列を足すと、サーバーから見れば「初めて見るURL」になります。これを使って、キャッシュ命中時と不命中時を切り分けました。

リクエスト TTFB(実測) うちサーバー応答 状態
記事HTML(通常URL) 101.6ms 25.3ms キャッシュ命中
記事HTML(クエリ付き) 326.2ms 249.9ms キャッシュ不命中
静的CSS(通常URL) 101.1ms 24.4ms ―
静的CSS(クエリ付き) 101.2ms 25.0ms ―
404ページ 298.6ms 221.9ms 毎回PHPが動く
/wp-json/ REST API 262.9ms 186.7ms キャッシュ対象外

読み取れることが3つあります。

1. HTMLはキャッシュされている。 通常URLのサーバー応答25.3msは、PHPを一切通らない静的CSSの24.4msとほぼ同じです。WordPressが毎回ページを組み立てていたら、この数字にはなりません。

2. 生成コストは約225ms。 不命中時の249.9msから命中時の25.3msを引いた224.6msが、WordPressがPHPでページを組み立てるのに使っている時間です(計算値)。倍率にすると9.9倍。

3. 静的ファイルはクエリ文字列の影響を受けない。 CSSは ? を付けても付けなくても24〜25msでした。PHPを通らないので、そもそも生成コストが存在しないためです。

404ページが221.9msかかっているのも同じ理由です。存在しないURLはキャッシュに無いので、毎回WordPressが404テンプレートを組み立てています。存在しないURLへのアクセスが多いサイトは、その分だけ毎回フルコストを払っていることになります。

/wp-json/ が186.7msなのは、エックスサーバーの公式マニュアルと一致します。Xアクセラレータの仕様表には、キャッシュされないURIとして /wp-admin/ /wp-json/ /xmlrpc.php /feed/ などが明記されています。このブログの記事投稿はREST API経由で行っているのですが、その経路が毎回187msかかるのは仕様どおり、ということです。

キャッシュの寿命を実測する ― 60秒で切れ、アクセスでは延びない

では、そのキャッシュは何秒もつのか。公式マニュアルに書かれている「保存期間2分間」は静的ファイル(.css .js .png .woff2 など)の仕様で、HTMLは対象拡張子に含まれていません。それでも実測ではHTMLがキャッシュされているので、寿命は自分で測るしかありません。

手順はシンプルです。毎回新しいクエリ文字列でユニークなURLを作り、1回目(必ず不命中=キャッシュ生成)を投げ、N秒待ってから同じURLを投げます。2回目が速ければ生きている、遅ければ切れている。

経過時間 1回目のサーバー応答 2回目のサーバー応答 判定
20秒後 265.3ms 24.7ms 命中
40秒後 262.7ms 25.0ms 命中
55秒後 269.6ms 23.5ms 命中
58秒後 309.1ms 25.2ms 命中
62秒後 269.6ms 281.9ms 不命中
65秒後 264.4ms 286.9ms 不命中
75秒後 246.2ms 421.4ms 不命中

58秒と62秒の間で切り替わりました。HTMLキャッシュの寿命は60秒と判断できます。

もうひとつ確かめたのが「アクセスがあると寿命が延びるのか」です。延びる実装(アクセスのたびに有効期限を更新する方式)と、延びない実装(作成時刻から固定時間で捨てる方式)では、運用上の意味がまったく違います。同じユニークURLで3回測りました。

タイミング サーバー応答(実測) 状態
0秒(初回) 266.9ms 不命中=キャッシュ生成
40秒後 23.7ms 命中
80秒後(=前回アクセスから40秒) 263.6ms 不命中

40秒の時点で確かに命中しているのに、その40秒後(生成から80秒後)には切れていました。命中しても寿命は延びない。作成から60秒で必ず捨てられる方式です。

これは実装としては素直で、記事を更新したときに古い内容が延々と残り続けないという利点があります。一方で、後述するとおりアクセスの少ないサイトにはほぼ恩恵がありません。

月45表示のサイトでは、キャッシュはほぼ効かない

寿命60秒・延長なしという性質は、必要なアクセス頻度を決めてしまいます。60秒の枠ごとに必ず1回は生成が走るので、その枠に何回アクセスが来るかで命中率が決まります。

単純化したモデル(60秒の枠あたりλ回アクセスがあり、うち1回だけが生成にあたる)で計算すると次のようになります。以下は実測値101.6msと326.2msを使った計算値であり、実際の命中率を測ったものではありません。

そのページの毎分PV キャッシュ命中率(計算値) 平均TTFB(計算値)
1回未満 0% 326.2ms
2回 50.0% 213.9ms
3回 66.7% 176.5ms
5回 80.0% 146.5ms
10回 90.0% 124.1ms
30回 96.7% 109.1ms
60回 98.3% 105.3ms

当サイトの直近の検索表示回数は28日で45回です。これは0.001PV/分にあたり、上の表では最下段のさらに下、命中率0%です。つまり実際に訪れてくれた人のほぼ全員が、326msのほうを踏んでいることになります。

普段の計測で101msが出ていたのは、連続してリクエストを投げていたから自分でキャッシュを温めていただけでした。自分で測ると速く見えるが、読者の体感は3倍遅い——これは速度計測をするなら知っておくべき落とし穴だと思います。

そしてこの構造は、対策の優先順位をひっくり返します。サーバーを速いプランに替えても、生成コスト225msの側を縮めなければ、読者が実際に見る数字は大きく変わりません。逆にアクセスが毎分数件に増えた時点で、何もしなくても平均TTFBは半分以下になる。速度は、アクセスが増えた結果として自動的に改善する側面がある、ということです。

個人ブログで先に手を付けるべきなのは、この計測結果から言えば次の順になります。

  1. 記事を増やして、そもそもアクセスを作る(キャッシュ命中率が上がり、平均TTFBが下がる)
  2. 生成コスト225msを縮める(プラグインの整理、PHPバージョン、DBクエリ)
  3. 転送量を減らす(後述。TTFBではなく表示完了までの時間に効く)
  4. サーバーの乗り換え(内部処理12msを削っても、TTFBは12%しか改善しない)

転送量の内訳 ― HTMLは12%、フォントが26%

TTFBは「最初のバイト」までの話で、表示が終わるまでの時間は転送量で決まります。記事ページ1本を開いたときに自ドメインから読み込まれるファイルを全部数えました(圧縮後の実転送バイト、実測)。

種別 本数 転送量 割合
HTML 1 42,682 B 12.4%
フォント 2 88,738 B 25.9%
CSS 9 81,840 B 23.9%
画像 5 68,654 B 20.0%
JavaScript 11 61,050 B 17.8%
合計 28 342,964 B(334.9 KB) 100%

単体で最大だったのは fontawesome-webfont.woff2 の77,165バイト。これ1本で全体の22.5%、HTML本体の1.81倍あります。アイコンフォントは既にwoff2で圧縮済みなので、gzipやbrotliでは小さくなりません。HTMLを削るよりアイコンフォントを見直すほうが効く、という順序がここで見えます。

一方、HTMLの圧縮はよく効いていました。

ページ 無圧縮 gzip brotli brotliの削減率
記事ページ 334,665 B 48,295 B 42,681 B 87.2%減
トップページ 305,962 B 36,732 B 32,423 B 89.4%減

brotliはgzipより11.6%小さくなっていました(記事ページ、実測)。ブラウザは基本的にbrotliを要求するので、実際に流れているのは42KBのほうです。無圧縮の334KBという数字を見て「HTMLが重い」と判断するのは誤りで、転送されているHTMLは全体の12.4%にすぎません。

もうひとつ、接続の使い回しの効果も測れました。28本を同じHTTP/2接続で取ると、2本目以降のTTFBは13〜16msでした。新規接続の101msとの差76msが、前述の握手コストです。握手は1回払えば済むので、ファイル数を減らす価値はHTTP/2以前より小さくなっています。

ブラウザキャッシュは静的ファイルだけに効いている

レスポンスヘッダも確認しました。ここはサーバー側キャッシュとは別の話で、「読者が2回目に来たとき」に効く部分です。

ヘッダ CSS(静的) HTML
cache-control max-age=604800(7日) なし
etag あり なし
last-modified あり なし
content-encoding br br
vary Accept-Encoding Accept-Encoding

静的ファイルには7日間のキャッシュ指示が付いています。エックスサーバーの「ブラウザキャッシュ設定」(公式の説明は「ブラウザのキャッシュ利用を指示する設定をレスポンスヘッダに付加し、再アクセス時にキャッシュデータを読み込むことでサイト表示速度を向上します」)が効いている状態です。2回目の訪問では、CSS・JS・フォント・画像の合計300KBがネットワークに出ません。

対してHTMLには cache-control も etag も付いていません。HTMLは毎回サーバーまで取りに行くということです。記事を更新したら即座に反映される、という意味では妥当な設計ですが、その毎回のリクエストが前述の「60秒で切れるキャッシュ」に当たるかどうかで101msか326msかが決まる、という構造になっています。

公式仕様と実測の突き合わせ

エックスサーバーの公式マニュアルに書かれている内容と、今回の実測を並べます。

公式に書かれていること 今回の実測 一致するか
Xアクセラレータの静的ファイルキャッシュ対象拡張子に .css .js .woff2 等を含む/保存期間2分間 静的CSSはクエリ有無にかかわらず24〜25ms 矛盾しない
対象拡張子にHTMLの記載はない HTMLも60秒キャッシュされている 別の機能によると考えられる
キャッシュされないURI に /wp-json/ /wp-admin/ /feed/ 等 /wp-json/ は186.7ms(生成パス) 一致
ブラウザキャッシュ設定がレスポンスヘッダを付加する CSSに max-age=604800 一致
Webサーバーにnginxを採用 server: nginx、HTTP/2で応答 一致
Xアクセラレータ Ver.2 はPHPを最大20倍高速化(※同一構成サーバーへのApache Bench比較) 今回は未検証(設定値を確認・変更していない) ―

1点だけ、はっきりさせておきたいことがあります。HTMLを60秒キャッシュしているのがどの機能なのかは、今回は特定していません。 サーバーパネルの設定を確認していないためです(このサイトは自動化で運用しており、設定変更を伴う操作は行わない方針を取っています)。公式マニュアルのXアクセラレータの仕様(静的ファイル・2分間)とは対象も時間も合わないので、別の仕組み——サーバーキャッシュ設定かCocoon側のキャッシュ——だと推測されますが、推測の域を出ないので断定はしません。実測として言えるのは「HTMLは60秒キャッシュされ、命中で25ms、不命中で250msになる」ところまでです。

なお、自宅PCとVPSのどちらでEAを動かすか、といった「常時稼働のコスト」を計算した記事もあります(EAを24時間動かすなら自宅PCの分岐点は約96W|電気代とVPS月額を公式単価で計算した)。このブログをエックスサーバーで立ち上げたときの記録は【構築ログ】WordPressクイックスタートは本当に10分で終わるのか?実際にやってみたにまとめています。

この計測から言えること/言えないこと

言えること

  • 当サイトのTTFBは中央値101.2ms、p90 109.8ms。Googleの良好しきい値0.8秒の12.7%(実測)
  • その75.4%は接続確立で、サーバー応答は24.9ms(実測)
  • HTMLは60秒キャッシュされ、切れているときは326.2ms、サーバー応答だけで9.9倍になる(実測)
  • キャッシュ寿命はアクセスでは延びない(実測)
  • この性質上、アクセスの少ないページでは常に遅いほうの数字が読者に見えている(計算値)

言えないこと

  • エックスサーバーが他社より速い/遅い(比較していない)
  • プランを上げると速くなるか(1プランしか測っていない)
  • この数字が検索順位にどう影響するか(TTFBはCore Web Vitalsではない、とGoogleの文書が明記している)
  • HTMLキャッシュの正体がどの機能か(設定を確認していない)
  • レンダリング完了までの時間(ブラウザ側を測っていない)

次にやるなら、同じ手順を別のサーバーで走らせて条件を揃えた比較にするか、生成コスト225msの中身をプラグイン単位で分解するか、のどちらかだと考えています。

この記事の検証環境

  • 対象サーバー:エックスサーバー スタンダードプラン(12ヶ月契約/2026年7月から運用中)。料金は2026年9月25日時点の公式掲載値で12ヶ月契約 月額1,100円・初期費用0円。公式ページに「2026/9/7 17:00 – 2026/10/5 17:00までのキャンペーン価格が適用されています」との注記があるため、通常価格とは異なります
  • 対象サイト:https://biboroku-lab.com/ (WordPress+Cocoon、公開記事10本、AdSenseコード設置済み)
  • 計測端末:Windows 11 PC上のLinux環境。日本国内の家庭向け光回線
  • 計測ツール:curl(HTTP/2・brotli有効)。集計と検算はPython 3
  • 計測日時:2026年9月25日 05:09〜05:35(JST)
  • サンプル数:TTFB計測170リクエスト(うちHTML80サンプル)、キャッシュ寿命実験34リクエスト、アセット計測57リクエスト。合計約270
  • この記事の数値は、断りのない限りすべて実測値です。 「計算値」と明記した箇所(サーバー内部処理12ms、生成コスト224.6ms、アクセス頻度別の命中率と平均TTFB)のみ、実測値からの計算です

出典

  • エックスサーバー「料金・お申し込み」(2026年9月25日確認。キャンペーン価格の適用期間の注記あり)
    https://www.xserver.ne.jp/price/
  • エックスサーバー「Xアクセラレータ」マニュアル(Ver.1/Ver.2の違い、静的ファイルキャッシュの対象拡張子・保存期間2分間、キャッシュされないURI、PHP最大20倍の注釈。2026年9月25日確認)
    https://www.xserver.ne.jp/manual/man_server_xaccelerator.php
  • エックスサーバー「機能一覧」(nginx採用、NVMe SSD、HTTP/2、ブラウザキャッシュ設定の説明。2026年9月25日確認)
    https://www.xserver.ne.jp/functions/index.php
  • Google「Time to First Byte (TTFB)」(しきい値0.8秒/1.8秒、TTFBに含まれる段階の定義、Core Web Vitalsではない旨。2026年9月25日確認)
    https://web.dev/articles/ttfb

【免責】本記事は当サイト1件の計測結果であり、エックスサーバーおよび他社サービスの性能を一般化して示すものではありません。共用サーバーの応答時間は同居環境・時間帯・回線によって変動します。料金・仕様・キャンペーン内容は改定により変わるため、契約前に必ず公式ページでご確認ください。計測結果は将来の同等の結果を保証するものではありません。

タイトルとURLをコピーしました