こんにちは、夏猫です。この記事はバーチャルケモミミ Advent Calendar 2025 21日目の記事です。
わたしは2年程度 Catalyst という VR-SNS 向けフォトシェアリングサービスを開発、運営しています。
技術スタックの紹介
技術スタックとしては、以下のような構成になっています。 SaaS モリモリですね (コストもモリモリです)。
- フレームワーク:Next.js App Router
- ID プロバイダー:Hanko.io
- データベース:PlanetScale (MySQL)
- Redis キャッシュ:Upstash Redis
- フロントエンド:Tailwind CSS
- ストレージ (大容量):Cloudflare R2
- ストレージ (小容量):Cloudflare Images
- プロキシサーバー:Cloudflare Workers
- 検索エンジン:Meilisearch
一応 FANBOX で支援いただいているおかげで黒字運営になっています。ありがとうございます! 構成図を書いてみると、こんな感じになっています。最近は iOS ネイティブクライアントも開発しているので、 api.natsuneko.com へ直接アクセスしているケースもあります。

メインである catalyst.natsuneko.com 、 API サーバーである api.natsuneko.com、アカウントサービスである accounts.natsuneko.com は Vercel 上の Next.js App Router で、 citlali.natsuneko.com での画像配信は Cloudflare Workers で最適な画像サイズ、フォーマットへ変換した後、 Cloudflare ネットワークを介して配信されます。 ストレージバックエンドにはほとんどのケースで Cloudflare R2 を、一部軽量画像については Cloudflare Images で直接配信しています。前段に Cloudflare Workers を通している理由としては、 Cloudflare Images は画像のキャッシュ効率がいまいち (おそらく結構な頻度で画像の再圧縮が行われている) で、配信速度が十分な速度を満たせなかったため、 Cloudflare Workers 上で事前にいくつかのパターンの画像を生成し、 R2 へ格納することで、2回目以降の問い合わせを高速で行っています。
Catalyst では、画像のメタデータを解析して保存する機能もあるので、それらの画像については Cloudflare R2 のアップロードイベントなどを経由して Workers へ問い合わせ、解析を行っています。

IdP には海外の Passkeys ネイティブ対応の Hanko.io というサービスを使っています。 Auth0 に比べて安価で、かつ Passkeys 対応が早かったことから採用しています (パスワードなんて持たないのが一番ですからね)。が Auth0 と比べるとログインに使える OAuth プロバイダーの選択肢がかなりビジネスよりなこと (GitHub, Microsoft, LinkedIn など......) と、そこそこの頻度で障害が起きたりするので、なんとも言えない気分になります。
データベースとしては MySQL サーバーには PlanetScale を、 Redis キャッシュには Upstash Redis を採用しています。 PlanetScale は2〜3年前は無料だったんですが、有料化してしまって、特に移行することなくそのまま払い続けています。しかし Primary と Replica 2台が付いて 49USD/mo ということで、まぁ許容範囲かなと言う感じ。実際には Catalyst のみでなく、他サービスのデータベースも一緒に住んでいるので、 Catalyst 単体で見るともっとコストとしては安い想定です。

Upstash Redis にはキャッシュデータとして、トレンド機能の提供や、iOS ネイティブクライアントのアクセストークンの有効性の確認などを行っています。こちらは Pay as You Go プランで、こちらは Redis の容量とコマンド問い合わせ回数による課金です。今のところかかっているコストはおおよそ 〜2USD/mo という感じ。安いと 1USD 行かないケースもあります。

フロントエンドの CSS フレームワークには、 TailwindCSS と shadcn/ui を採用しました。サービス開始当初は自前でデザインしていたのですが、思ったより整合性を取るのが大変なので、最終的には shadcn/ui に落ち着きました。 TailwindCSS はわたしが CSS 書くのが苦手だから採用しています。 HTML がやんちゃになる代わりに、 CSS のスコープやセレクターの名前付けから解放されます。

Next.js は App Router を採用しています。最近は React2Shell なんかで話題になっていた RSC を結構使っています (うちのサービスたちは対策済みです)。主に Googlebot 向けの SSR 用途でですが、そもそも画像中心のサービスというのもあって、インデクシングする文章も少ないですし、実は SSR しなくても良いのでは?という気持ちもあったりします。
検索エンジンには Meilisearch を採用しています。 Meilisearch は軽量で高速な検索エンジンです。これは Oracle Cloud 上で運用している自前 k8s クラスタ上で運用しています。なんと無料枠で収まる。 (クラスタ含め) アップデートが難しいことが難点ですが、Meilisearch Cloud では 30USD/mo が最低ラインだと考えると、多少の手間は許容できるでしょう。
コストの話
コストとしてはちまちま紹介してきましたが、次のモノがベースラインとして乗っかってきます:
- PlanetScale 49USD/mo
- Hanko.io 29USD/mo
- Cloudfalre Workers 5USD/mo
- Cloudflare Images Storage 5USD/mo
- Vercel Pro 20USD/mo
ここに従量課金として
- Cloudflare R2
- Cloudflare Workers
- Upstash Redis
が数ドル程度、かかってくるイメージです。月120USDちょい。だいたい月2万円行かないくらい。結構かかっていますね。データベースが一番高いですが、先に述べたとおりいろいろなサービスが同一のデータベースを共用していること、 Vercel Pro も十数サービスが同居していることを考えると、 Catalyst 単体ではもっとコストは低いと考えられます。ところで 120USD が2万円くらいになるなんて、円安許せなく無いですか?悲しい。
今後の話
今後はコストを下げたい気持ちはありつつ、まずは Catalyst のユーザー増を狙っています。ユーザーが増えればユーザー当たりのコストも減るので。今は毎日投稿してくれるユーザーがいたり、リアクションもしてくれるユーザーがいるので、そういったユーザーを増やしつつ、インターネットの隅で開発・運用していきたいですね。
ということで
ということで、バーチャルケモミミ Advent Calendar 2025 21日目の記事でした。明日の記事はまどさんで、「全身で風を感じろ!バイクで行く旅行(ツーリング)の良さとスポット、注意点」です。楽しみですね。 また、裏で Catalyst Advent Calender 2025 もやっております。皆さん良い写真を投稿されているので、是非見ていってください!