コンテンツへスキップ
すべての記事
ガイド

Mooveのパフォーマンスを59%改善した方法

Mooveのユーザーの多くはサーバーから遠い場所にいます。サーバーを1台も動かさずに、最初の応答までの時間を59%短縮した方法と、見た目以上に難しかった点を紹介します。
2026年11月6日9分で読めます

距離が最も遅い依存先だった

Moove appを開く人の多くは、ナイジェリアやインドネシアのモバイル回線を使っており、応答を返すサーバーから数千キロメートル離れています。今月、私たちはそうしたリクエストが私たちのもとに届く経路を変更しました。その結果、最初のバイトまでの時間(TTFB)、つまりスマートフォンがリクエストを送ってから応答の最初の一部が届くまでの時間は、0.74秒から0.31秒へと59%短縮されました。サーバーは1台も移動していません。

この記事では、距離が想定以上のコストになっていた理由、私たちが行った変更、変更そのものよりも難しかった部分、そして同じことをこれから行うチームに伝えたいことを説明します。

1回の長い移動が3回になる理由

エンジニアは、何かを送ってからそれが届くまでの遅れをレイテンシと呼び、メッセージがサーバーに届いて返信が戻ってくるまでの時間を**ラウンドトリップタイム(RTT)**と呼びます。ラゴスから私たちのサーバーまでのRTTは200~300ミリ秒です。それだけなら許容できる範囲です。問題は、リクエストが単独で移動することはほとんどない点にあります。

スマートフォンが安全な接続で何かを要求する前に、2つのハンドシェイク、つまり接続を確立するための短いやり取りを完了する必要があります。TCPハンドシェイクで接続を開き、続くTLSハンドシェイクで通信を秘匿する暗号鍵を取り決めます。それぞれが1往復分のコストを要します。その後でようやくリクエスト本体が送られ、これが3回目の往復です。1往復250ミリ秒の場合、サーバーが何も処理しないうちに、ユーザーは約4分の3秒待つことになります。

モバイルネットワークでは、このコストは想像以上の頻度で発生します。スマートフォンは基地局間を移動し、無線は電池を節約するためにスリープし、アプリはバックグラウンドに送られます。これらのどれもが接続を切断する原因になり、次のリクエストはコールド接続、つまりハンドシェイクがまだ1つも済んでいない接続から始まり、セットアップのコストをすべて払い直すことになります。すでに開かれ保護されているウォーム接続であれば、すぐにリクエストへ進めます。

ラゴスを私たちのサーバーに近づけることはできません。しかし、セットアップの場所をラゴスに近づけることはできます。

サーバーではなくハンドシェイクを動かす

コンテンツ配信ネットワーク(CDN)は、通常はキャッシュとして説明されます。世界各地の拠点がファイルの複製を保持し、近くから配信できるようにする仕組みです。私たちは別の目的でCDNを使いました。アプリがあらゆる操作に使うインターフェースである私たちのAPIでは、キャッシュを完全に無効にしています。すべてのリクエストは、これまでどおりオリジン、つまりCDNがその背後にあるサーバーを指す呼び名まで届きます。

変わったのは、接続が始まる場所です。スマートフォンは、最寄りのエッジロケーション、別名接続拠点(PoP)に接続を開くようになりました。これはCDNが世界各地に持つ拠点の1つで、多くの場合、数百ミリ秒ではなく数十ミリ秒の距離にあります。エッジはTLS終端を行います。つまり、スマートフォンからの安全な接続はそこで終わります。その後エッジは、keep-alive(リクエストの合間に接続を閉じずに開いたままにする設定)で維持された、オリジンへのウォーム接続のプールを再利用します。コストの高い2回のセットアップの往復は短い区間で済み、海を越えるのはリクエスト本体だけで、しかもすでにウォームな接続の上を通ります。

3回の長い移動が、1回の長い移動と2回の短い移動に変わります。考え方はこれがすべてです。

それ以外の部分は、意図的に地味なままにしました。

  • クライアントは何も気づきません。 アプリとウェブサイトのアドレスは変わらないため、アプリのリリースは不要で、誰も何も更新する必要がありませんでした。
  • 障害時の挙動は変わりません。 タイムアウトは以前と同じ設定のため、以前に失敗していたものは同じ形で失敗します。新しい種類のエラーを増やしたくありませんでした。
  • アイドル接続は先にエッジが閉じます。 どの接続にもアイドルタイムアウト、つまり使われないまま放置できる時間があり、それを過ぎると閉じられます。エッジはまだ接続が開いていると考えているのに、サーバー側が静かな接続を閉じてしまうと、次のリクエストが失敗します。エッジのタイムアウトを短く設定しておけば、常にエッジが先に接続を閉じ、新しい接続を開き直します。
  • スマートフォン向けの新しいプロトコル。 スマートフォンは、ウェブのリクエストプロトコルの最新版であるHTTP/3で接続できます。HTTP/3はQUICの上で動作し、2つのハンドシェイクを1往復にまとめ、モバイルネットワークで多いパケット損失にもうまく対応します。
  • 除外される地域をなくす。 エッジネットワークの低価格プランでは、私たちのユーザーが暮らす地域がまさに対象外になっていることが少なくないため、全地域をカバーするプランを選びました。

計測したこと

私たちはシドニーから計測しました。シドニーは、ラゴスとほぼ同じくらい私たちのサーバーから離れています。古い経路と新しい経路を比較し、それぞれについて新しいコールド接続を5回開きました。モバイルネットワークで最も重要なケースです。そして中央値、別名p50を取りました。これは真ん中の結果で、リクエストの半分はこれより速く、半分は遅いという値です。同じプロジェクトでは、それまで元のサイズのまま送られていたウェブサイトのスクリプトに対して圧縮も有効にしました。圧縮はファイルを送信前に小さくし、ブラウザーが到着時に元に戻す仕組みです。ここでは、ウェブ向けに作られた圧縮形式であるBrotliを使いました。

計測内容変更前変更後改善率
TCPとTLSのハンドシェイク完了(p50)490 ms59 ms88%高速化
最初のバイトまでの時間(p50)743 ms307 ms59%高速化
ホームページのスクリプトのペイロード1.76 MB560 KB68%縮小

59%という数字は、最初のバイトまでの時間から来ています。以前は確立に0.5秒かかっていた接続が、今では0.1秒未満で使えるようになりました。また、ウェブサイトへの初回訪問でのダウンロード量は3分の2減りました。多くの人が1メガバイトごとに料金を払っている回線では大きな違いです。

これらの数値は1つの都市で測ったもので、世界的なベンチマークではありません。ただし、計算はラゴスやジャカルタにもそのまま当てはまり、そこが私たちのユーザーのいる場所です。

難しかったのは、誰が呼び出しているかを知ること

サーバーの前に何かを置くのは簡単です。その背後でも保護機能が働き続けるようにすることに、労力の大半がかかりました。

多くの決済プラットフォームと同様に、Mooveはレート制限、つまり1人の呼び出し元が一定時間内に行えるリクエスト数の上限を使っており、その制限は呼び出し元のIPアドレス、つまりインターネット上で端末を識別する番号をキーにしています。エッジネットワークの背後では、すべてのリクエストがユーザーのアドレスではなくエッジロケーションのアドレスから届きます。他に何も変えなければ、ラゴスの全員が1つの枠を共有することになり、忙しい午後が1度あるだけで、何も悪いことをしていない人たちが拒否され始めていたでしょう。

解決策は2つの考え方に基づいています。

信頼するのは、実際に存在する層だけにする。 CDNはリバースプロキシ、つまりサーバーの前に置かれてリクエストを転送するサーバーの一種です。各プロキシは、リクエストを受け取った相手のアドレスをX-Forwarded-Forという標準的なヘッダーに追加するため、本当の呼び出し元は、そのリストの中で一定の段数、つまりホップ数だけ手前にいます。この数を間違えると、どちらの方向でもバグになります。層の数を少なく数えると、すべてのユーザーがエッジロケーションに見えてしまいます。多く数えると、呼び出し元自身が書いた項目を信頼し始めてしまいます。そこで私たちは、この数をコードではなくインフラの属性にしました。ネットワークが変わる瞬間に同時に変わり、値が不合理な場合は、推測せずにサービスの起動を拒否します。

エッジに呼び出し元を保証させ、信じるのはエッジだけにする。 エッジは、すべてのリクエストに本当の呼び出し元のアドレスを書き込み、呼び出し元が送ってきた値があれば上書きするようになりました。私たちの保護機能は、リクエストが確かに自社のエッジを通過したことを検証できる場合にのみ、この値を信じます。ネットワークアドレスをキーにしていたすべての制限は、エッジ経由のトラフィックについては本当の呼び出し元をキーにするようになりました。これらのルールは既存のルールを変更するのではなく、並べて追加しました。そのため、展開の各変更は純粋な追加であり、誰でも1回読めばレビューできました。

リリース前に見つけたバグ

Moove Profilesは、加盟店の独自ドメイン上で運用できます。それらのドメインへのリクエストは、加盟店のドメインが付いた状態で私たちのウェブサイトに渡され、サイトはどのプロフィールを表示するかを判断していました。

ウェブサイトの前に置く新しいエッジは、この種の情報を受信リクエストから取り除きます。訪問者がそれを設定できてはならないので、これはまさに正しい動作です。しかしそれは同時に、ウェブサイトがエッジの背後に移った時点で、すべての加盟店ドメインが加盟店のプロフィールではなくMooveのホームページを黙って表示してしまうことも意味していました。

私たちはこれをレビューで見つけ、加盟店ドメインの経路を先に専用のルートへ移し、その移行が済んでいない環境ではウェブサイトの変更を適用することをインフラが拒否するようにしました。かつてはレビュアーの頭の中にしかなかった見落としが、今ではビルドが止めてくれるものになっています。

一般的な教訓はこうです。入力を整理する層を追加するときは、これから整理する入力に依存していたものをすべて探してください。

展開の進め方

決済インフラでは「デプロイして様子を見る」は通用しないので、まずステージングを変更し、本番はその後にしました。切り替えを平穏に終えるために、いくつかの工夫をしています。まず、DNSレコードの**TTL(存続時間)**を引き下げました。DNSは、moove.xyzのような名前をサーバーのアドレスに変換する、インターネットの電話帳です。TTLは、インターネットのほかの部分がその回答をキャッシュしてよい時間で、私たちはこれを1時間から5分に短縮しました。何かを動かす丸1時間前に行ったので、古い回答はあらゆる場所で失効しており、ロールバックも数分で反映されます。アドレスレコードは、その場で切り替えられる形のまま維持しました。削除して作り直すと空白ができ、空白は障害になるからです。リスクのある各ステップは独立した小さな変更にし、元に戻す手順を順番に書き残しました。

別のチームに伝えたいこと

ユーザーがサーバーから遠い場所にいるなら、何もキャッシュしなくてもエッジネットワークを導入する価値があります。切り替える前に、次の点を確認してください。

  • 呼び出し元のアドレスを読むものをすべて洗い出してください。レート制限、許可リスト、不正検知のシグナル、監査ログ、セキュリティルールなどです。変更しない限り、それらはすべてエッジのアドレスを見ることになります。
  • 信頼する層の数をインフラの一部にして、間違っているときは起動を拒否するようにしてください。
  • エッジに本当の呼び出し元を記録させ、その記録は、自社のエッジから来たと検証できるトラフィックに対してのみ信頼してください。
  • サーバーがエッジ経由のトラフィックだけを受け付けるようにし、強制する前に様子を観察してください。
  • ページをキャッシュする場合は、レスポンスが実際に変化する要素のすべてからキャッシュキー、つまりキャッシュが2つのリクエストで1つの保存済みレスポンスを共有できるかどうかを判断するためのリクエスト情報の組を作ってください。サーバーはそれらの情報をVaryヘッダーに列挙するので、記憶に頼らずにそれを読んでください。
  • 変更の前後で計測し、ハンドシェイク時間と最初のバイトまでの時間を別々に見てください。そうすれば、接続のセットアップと、サーバーが処理に費やす時間を区別できます。

今後の展望

私たちのページの多くはパーソナライズされているため、ウェブサイトのエッジキャッシュは今のところほとんど使われていません。接続の改善はページを問わずすべてに効いており、共有しても安全なページは、個別にキャッシュを有効にできるようになりました。APIのレスポンスをキャッシュするには、独自の設計とレビューが必要であり、次に検討したいテーマです。

お金は、海を越える光の速さではなく、ネットワークの速さで動くべきです。

Mooveの上で開発するなら、Web3決済APIとSDKの紹介とMoove Developer Programをお読みください。

moove.xyzエンジニアリングチームより。

moove.xyzについて

moove.xyzは、価値のパーミッションレスで手間のかからない移動のために構築されたグローバルなWeb3フィンテックプラットフォームです。私たちは世界中のビジネスと消費者が、1つのプラットフォームですべてのブロックチェーンで任意の暗号通貨を送受信、ステーキング、スワップできるよう支援します。

私たちは、マルチチェーンウォレットアクセス、パーソナライズされたウォレットハンドル、クロスチェーントークンスワップ、埋め込みクロスチェーン取引、分散型ソーシャルファイナンシャルネットワークにわたる統合された包括的なカバレッジを可能にするフルスタック暗号決済および分散型金融インフラを革新・構築する世界初のWeb3フィンテック企業の一つです。主要製品にはMoove Profile、Moove Send、Moove Receive、Moove Stake、Moove Swap、Moove Rewards、Moove Discoverなどがあります。

私たちのミッションはシンプルです——次の10億のWeb3ユーザーのためのパーミッションレスで手間のかからない金融テクノロジーを創造・配布すること。私たちは、お金と価値の移動の未来はコストゼロ、ボーダーレス、パーミッションレス、手間なし、そしてすべての人のために構築されるものだと根本的に信じています——そして、その未来を現実にするための究極のWeb3フィンテックプラットフォームを構築しています。

あなたのお金。あなたの一手。

あわせて読みたい。

Web3決済APIとSDK:Mooveで構築する開発者ガイド
ガイド

Web3決済APIとSDK:Mooveで構築する開発者ガイド

2026年7月16日9分で読めます
Moove Developer Programのすべて
ガイド
稼ぐ

Moove Developer Programのすべて

2026年9月6日8分で読めます
Moove App:iOS・Android向け暗号資産決済アプリ
視点

Moove App:iOS・Android向け暗号資産決済アプリ

2026年3月28日7分で読めます

あなたのお金を、あなたの手で。

スキャンして Moove アプリをダウンロード
App Store からダウンロードGoogle Play で手に入れよう