ある開発者が、クライアント側のポーリング間隔を30秒から15分に延長することで、Neonのサーバーレスデータベースのコンピューティング料金を削減しました。間隔を長くすることで、データベースが十分にアイドル状態になり、スケール・トゥ・ゼロ(scale to zero)が可能になります。これにより、30秒ごとの一定のポーリングによって消費されていたコンピューティング・クレジットを排除できました。

Neonは、コンピューティング・エンジンが稼働しているすべての秒数に対して課金されます。一般的なサーバーレス構成では、どんなに小さなリクエストであっても、エンジンを稼働させたままにしてしまいます。著者のTVダッシュボードは、ユーザーが手動で同期するか新しい放送が始まるまで表示データが変わらないにもかかわらず、30秒ごとにデータベースにクエリを投げていました。このパターンにより、Neonのコンピューティング・プールが課金を停止する「ゼロ状態」に到達できず、Vercelのコストダッシュボードには定期的なスパイク(急増)が表示され、コストが膨らんでいました。

元のポーリングが問題だった理由

  • ダッシュボードは純粋なクライアントサイドのReactコンポーネントであったため、各ブラウザインスタンスが直接Neonにアクセスしていました。
  • Neonの料金体系はリクエスト数ではなくアクティブなコンピューティング時間に基づいているため、30秒ごとの1回のアクセスがベースラインの料金を発生させ続けていました。
  • 著者のVercelモニタリングでは、トラフィックとNeonのコンピューティング使用量に相関関係が見られ、ポーリングがデータベースを稼働させ続けていることが確認されました。

失敗した回避策

ユーザーの最後の操作の後にリクエストを遅延させる簡単なデバウンス(debounce)も効果はありませんでした。タイマーが依然として30秒ごとに作動していたからです。また、Vercel Edge Functionsの使用も試みましたが、複雑になりすぎました。

シンプルな解決策

必要だったコードの変更は、更新間隔を定義する定数を置き換えることだけでした。

  • 30秒5分
  • 次に 5分15分

15分に設定することで、Neonはアイドル状態を認識してコンピューティング・リソースを停止(spin down)させるのに十分な時間を確保できます。ダッシュボードの機能は維持されます。ユーザーが手動で更新すれば最新のデータを確認できますし、時折行われる自動ポーリングによって、絶え間ない通信を行うことなく新しい放送をキャッチできます。

なぜクライアントサイドでポーリングを続けるのか?

  1. シンプルさ – 追加のサーバーレス関数やビルドステップが不要です。
  2. ユーザーの期待 – ダッシュボードはすでにクライアントアプリのように動作しており、手動クリックによる即時更新も可能です。
  3. コストモデルとの整合性 – Neonはリクエスト数ではなくコンピューティングの秒数に対して課金されるため、頻度を減らすことが直接的なコスト削減につながります。

サーバーレス開発者への教訓

  • ポーリングの頻度を、データの実際の更新サイクルに合わせましょう。データセットが1時間に数回しか変わらないのであれば、15分間隔で十分な場合が多いです。
  • サーバーレス環境における頻繁なポーリングは、隠れたコスト要因になります。1分間にたった1回のリクエストが増えるだけで、データベースがスケールダウンできなくなる可能性があります。
  • アーキテクチャの抜本的な見直しをしなくても、小さな設定の微調整だけで大きな節約を実現できることがあります。

結論として、たった一つの定数の変更によって、常に稼働し続けていたデータベースを真のサーバーレスコンポーネントへと変え、ダッシュボードの有用性を維持したままコンピューティング費用を削減できました。Neonや同様の秒単位課金サービスを利用しているチームにとって、ポーリング間隔を見直すことは、今日から試すべき手軽で効果的な改善策です。