かごいとの道具は、すべて無料で使えます。となると当然、運営側の費用をどう抑えるかが問題になります。ひとりで7つのサービスを維持している以上、月額の費用がかさむような構成は現実的ではありません。この記事では、裏側の技術構成をどう選んでいるかを書いておきます。
結論を先に書くと、いまはドメイン代程度で回っています。そこに至るまでに、考え方が一度ひっくり返りました。
選び分けから、揃えるへ
最初は、サービスごとに向いている構成を選ぶつもりでいました。
実際そうしていて、最初の道具「かごチケ」はGo言語で書いて、無料で借りられるVPS(自分専用のサーバー)の上で動かしていました。無料枠を組み合わせて、どこまで費用をかけずに運用できるか試してみたかったからです。一方、あとから作った市電なうや今あきは、Cloudflare Workersという別の土台に載せました。アクセスに応じて勝手に増減してくれて、無料の範囲なら費用がかからない点が、いくつも同時に持つには扱いやすかったのです。
しばらくして、この「選び分け」がうまくないと気づきました。
理由は単純で、ひとりで維持しているからです。サービスが7つあって、そのうち1つだけ土台が違うと、その1つに触るたびに勝手が違います。デプロイの手順が違う。ログの見方が違う。データベースの触り方が違う。それぞれにとっての最適を足し合わせても、全体として持ちやすくはならないのでした。
そこで2026年7月30日、かごチケも Cloudflare Workers へ移しました(そのときの話はかごチケの制作ノートに書いています)。これで全部が同じ土台に揃いました。
| サービス | データベース | そのほか |
|---|---|---|
| かごチケ | D1 | R2(チラシ画像)・メール送信 |
| 市電なう | D1 | 時刻表・遅延報告 |
| 市バスなう | D1 | 時刻表は静的ファイル、遅延報告のみDB |
| 灰なう | D1 | 通知の購読・予報のキャッシュ |
| 今あき | D1 | 店舗・報告・通知の購読 |
| 涼しか | 使わない | 施設データは静的ファイル。APIは1本だけ |
| 桜島フェリーなう | 使わない | 時刻表はコードに同梱。APIなし |
土台はすべて Cloudflare Workers です。データベースが要らないものには、置いていません。持たなくて済むものは持たないのが、いちばん安く、いちばん壊れません。
揃えて何がいちばん変わったかというと、デプロイの手順が1つになったことでした。いまはどのサービスも、サービス名を渡すだけの同じコマンドで公開できます。他の端末で入れた変更の取り込み、ビルドの確認、公開用ブランチへの反映、バックアップ先も含めた送信まで、まとめて面倒を見てくれます。
地味に見えますが、これが効きます。7つのうち1つだけ手順が違うと、その1つに触るのが億劫になり、億劫になったものは後回しになり、後回しになったものが古びていくからです。揃えるというのは、続けやすくするということでした。
いちばん設計を変えた制約は、定期実行の枠
無料で使える範囲には、当然いろいろな上限があります。その中で、実際にサービスの作りを変えてしまった制約が一つあります。
利用しているWorkers Freeプランでは、定期実行(Cron Triggers)の枠がアカウント全体で5本という制約です。サービスごとの枠ではないので、7つのサービスで分け合います。有料プランの上限とは異なります(Cloudflareの公式上限表を2026年9月28日に確認)。
この上限に気づいたとき、私の環境ではコード本体の反映は成功して、定期実行の登録だけが失敗しました。確認したログでは理由を読み取れず、ビルドの表示は赤いのに、サイトを開くと新しいコードで動いていました。「デプロイに失敗した」と思って調べ始めると、まったく違うところを探すことになります。これは当時の環境で起きた記録で、すべてのデプロイで同じ表示になるという意味ではありません。
枠が5本しかないと分かってから、いくつかのサービスの作りが変わりました。
| サービス | 定期実行 | 代わりにしていること |
|---|---|---|
| 灰なう | 使う | 5分おきに気象庁のフィードを見にいく(通知の要) |
| かごチケ | 使う | 5分おきにメールを送る。積んだ直後にも送る |
| 市電なう | 使わない | 月初のアクセスを起点に、時刻表を1回1バッチずつ取り直す |
| 市バスなう | 使わない | 月1回、配布ファイルの更新を検知して取り込み直す |
| 涼しか | 使わない | アラートは必要になったとき取りにいってキャッシュする |
| 今あき | 使わない | 一覧を取りにきたついでに、古い行を掃除する |
| 桜島フェリーなう | 使わない | 時刻表を更新するときに作り直して置く |
とくに涼しかは、二段階で変えました。もともと3本の定期実行を使っていたのを、まず1本にまとめて枠を空けました。時刻を並べて書けば1本で複数回動かせるので、分ける必要がなかったのです。
そのあと、そもそも効いていなかったことが分かって、丸ごと廃止しました。アラートの取得結果をあらかじめ温めておくつもりだったのですが、Cloudflareのキャッシュは世界中の拠点それぞれに別々に持たれます。定期実行が走るのは1拠点だけなので、温まるのもその1拠点だけ。ほとんどの人には効いていませんでした。
市電なうは、そもそも定期実行を使わない形にしました。時刻表の取り直しは月に一度あればいいので、月の初めに誰かがアクセスしたら、そのついでに少しずつ書き込むようにしています。利用者を待たせないよう、応答を返したあとに裏で進めます。
枠が5本、という一行の制約が、ここまで作りを動かしました。制約は不便ですが、「本当に定期実行でなければいけないのか」を一つずつ考え直すきっかけにはなりました。実際、そのほとんどは要りませんでした。
本番でだけ壊れる、いちばん厄介な罠
いちばん時間を取られたのは、上限の話ではありませんでした。
サーバーは、返すデータごとに「これは何秒くらい使い回していい」という指示を付けられます。予報なら120秒、お店の空き状況なら20秒、といった具合です。鮮度が命の情報ほど短くします。
ところが、ドメイン側の設定が、この指示を4時間に書き換えていました。
20秒のつもりの空き状況が、4時間そのまま使われる。空席が満席に変わっても、画面は何時間も前のままです。今あきにとっては、サービスの前提が崩れる不具合でした。
厄介だったのは、これが見つけにくい壊れ方をすることです。
- 書き換わるのは、キャッシュに当たったときだけ。同じURLでも、取るタイミングによって20秒だったり4時間だったりする。1回確かめて「大丈夫だった」と結論を出せてしまう
- 手元では再現しない。本番のドメインを通ったときにだけ起きる
- 症状は「たまに情報が古い」なので、キャッシュの設定を疑うところまでなかなか行き着かない
灰なうの予報(120秒のつもり)、今あきの一覧(20秒のつもり)、市電なうの運行状況(20分のつもり)——3つのサービスで同じことが起きているのを突き合わせて、ようやく「サービスの問題ではなく、ドメインの設定の問題だ」と分かりました。1つのサービスだけを見ていたら、たぶん見つけられませんでした。同じ作りのものを複数持っていることが、初めて役に立った瞬間でした。
いまは、鮮度が要る取得についてはブラウザ側でキャッシュを使わないよう指定して回避しています。
無料枠に載せる、ということ
無料の範囲で動かすというのは、我慢することではなく、無駄を持たないことだと思っています。結果的に、そのほうが良くなったものがいくつもありました。
静的なファイルは、プログラムを通さずそのまま配る。画像もCSSもHTMLも、サーバーのプログラムを経由させると、そのぶん実行回数を消費します。だから「APIのときだけプログラムを通す」設定にしてあります。ただしその代わり、セキュリティ関連の設定はプログラムの外側に別途書く必要があります。節約には、こういう手間がついてきます。
重い読み出しは、必要なときだけ。灰なうがデータベースを本気で読むのは、噴火があったときだけです。何も起きていない大半の時間は、キャッシュを返すだけで済ませています。
データベースを持たない選択もある。涼しかの施設データは750件ありますが、1日に何度も変わるものではありません。だから静的なファイルとして丸ごと配って、サーバーが持つAPIは「いまアラートが出ているか」の1本だけにしました。桜島フェリーなうに至っては、APIがありません。
バックアップを自前で持たない。データベース側に、過去のある時点へさかのぼって復元できる仕組みが付いています。かごチケをGo版から移したときも、自前で書いていたバックアップ処理は移植せず、そちらに任せました。同じことをする道具を二重に持つと、二重に壊れます。
ここまで「全部 Cloudflare に揃った」と書いてきましたが、ひとつだけ、Cloudflare の中で完結しないものがあります。メールの送信です。
かごチケの予約確認メールには、外部の送信サービスを使っています。Cloudflareにメール送信機能がないわけではありません。現在はCloudflare Email ServiceのEmail Sendingがあり、任意の宛先への送信にはWorkers Paidプランが必要です。アカウントで検証済みの宛先へ送る機能とは、条件が異なります(公式の提供条件を2026年9月28日に確認)。
この構成では、無料枠を中心に運用するため、引き続き外部サービスの無料枠を利用しています。サービスの有無と、自分の運用で採用しているかどうかは、分けて説明すべきでした。
外部に頼る以上、その相手の都合にも付き合うことになります。送信サービスには1日に送れる通数の上限があって、上限に当たったときの扱いには気を使いました。断られたことを普通の失敗として数えてしまうと、何度か続いただけで「送信不能」の扱いになり、本文も消えて復旧できなくなるからです。時間が経てば解決する失敗は、失敗の回数に数えない。自分で決められない部分を持つというのは、こういう区別を一つずつ入れていく作業でもありました。
そして、節約のためにやったことが、別の意味を持つこともありました。今あきと涼しかは、お店や施設までの距離をブラウザの中で計算しています。もともとはサーバーの実行回数を減らすためでしたが、結果として、利用者の現在地をサーバーに預けずに済んでいます。設計の都合がプライバシーの都合と一致した、運のいい例です。
「小さく作る」は、技術選定にも表れる
制作ノートの別の記事にも書きましたが、「自分が使う側だったら、そうしてほしい」という考え方が、かごいとの作り方の基本になっています。それは画面のデザインや機能だけでなく、こうした裏側の技術選定にも、同じようにつながっています。
無料で使ってもらうサービスだからこそ、運営側のコストも小さく保ちたい。そして小さく保とうとすると、持ち物が減り、壊れる場所も減ります。制約は面倒ですが、面倒なぶん、余計なものを作らずに済んでいる気がします。
提供条件の確認先と、この記録の範囲
この記事は、かごいとの実装・運用で経験したことをまとめた記録です。構成表は2026年8月時点のもので、無料枠に収まるかはアクセス数・実行時間・保存量などによって変わります。同じ構成を選べば、どのサイトでも無料になるという意味ではありません。
- Workersの上限表:Cron Triggersなど、プラン別の上限。
- Workersの料金表:無料枠と、超過・有料プランの扱い。
- Email Serviceの料金・提供条件:任意の宛先と検証済み宛先への送信の違い。
2026年9月28日にメール送信の説明と無料プランの適用範囲を修正しました。サービスの構成を変更した日ではありません。