※この記事は、Claude Codeで1人開発しているSNS運用SaaS「ThreadPost」の開発日記です。
SNS運用を自動化しませんか?
ThreadPostなら、投稿作成・画像生成・スケジュール管理まで全てAIにお任せ。
終わりのないモグラ叩きの幕開け
タイムラインの高速化を目指してAPIを触った。動いたと思った瞬間に別の機能が沈黙した。

エラーすら吐かずに画面が真っ白になる。直せば直すほど、別の場所が崩壊していく。無限地獄だった。
48回のコミットと崩壊の記録
今週はタイムラインの表示速度とX API連携の安定化に取り組んだ。結果として大量のコードを書き直した。

今週の格闘を数字で並べる。
- 総コミット: 48件
- 新機能: 3件
- バグ修正: 5件
データベースのキャッシュとAPIの並列処理を入れた。タイムラインは爆速になった。その代償として非同期処理の魔境に足を踏み入れた。
しんたろー:
48件のコミット。新機能は3つだけ。残りは全部バグ修正。これサボると来週死ぬやつだ。
タイムライン爆速化と幽霊ロードの恐怖
SNSのタイムライン表示速度は命だ。遅いだけでユーザーは離脱する。企業ならRedisを挟むのが定石だが、僕はSupabaseをそのままキャッシュとして使う構成にした。
「feat: タイムラインタブをDBキャッシュ即表示+バックグラウンドX API更新に変更」
以下の戦略で表示遅延をゼロにする。
- タブ切り替えを検知
- データベースの既存データを即表示
- 裏でX APIから最新を取得して差分更新
初期ロードは0.3秒を切った。完璧だ。ただしAPIリクエスト数は3倍に跳ね上がった。トレードオフの計算を間違えた。
さらに体感速度を上げるため、楽観的UI更新を導入した。
「feat: いいね・リポスト・フォローを楽観的更新に変更」
クリック即座にUIを切り替え、ローディングスピナーを廃止した。API失敗時のみ元に戻す。実装直後、画面の挙動がおかしくなった。
- 画面はフリーズ
- インジケーターは回転
- ネットワーク通信は完了している
ユーザーには何も届かない「幽霊ロード」状態だ。非同期処理の競合が起きていた。ReactのuseEffectでクリーンアップ関数を忘れると悲惨だ。古いリクエストが状態を上書きするレースコンディションが頻発した。
さらに致命的な問題があった。キャッシュヒット時のslice処理が漏れていた。データベースにある数千件のデータを一気にフロントへ投げつけた。ブラウザが悲鳴を上げてフリーズした。爆速にするはずが、アプリ全体を道連れにしてクラッシュさせた。
僕は慌ててバッチ処理を分割した。941件のIDを一括で投げた結果、別のエラーも引き起こした。
「fix: タイムラインのコメント・アクション取得をバッチ分割」
PostgRESTはクエリパラメータをURLに埋め込む。IDリストが長すぎると、414 Request-URI Too Largeエラーで即死する。200件ずつバッチ分割して取得するように書き直した。
並列化も進めた。エンゲージメント関連の全タブで、データベースへの問い合わせを同時に走らせる。
「feat: エンゲージメント全タブのDB問い合わせをPromise.allで並列化」
タイムラインタブではOAuthトークンの取得とバッチ分割クエリを同時に回す。これでようやく、目指していた爆速タイムラインが形になった。代償として、僕の休日は完全に消滅した。
認証方式の壁と沈黙するX記事
タイムラインが落ち着いたと思ったら、次はAPIの認証周りが牙を剥いた。全エンドポイントの認証をOAuth 1.0aに統一しようとした。
「feat: 競合タブをメンション検索ベースに変更、全APIをOAuth1.0aに統一」
ユーザーごとのリミットを管理しやすくなる。これでAPIの制限問題は解決すると踏んでいた。甘かった。認証方式を変えた途端、X記事の個別取得APIが完全に沈黙した。
エラーすら吐かない。特定のデータ型だけが透明人間になったような不気味さだった。
しんたろー:
ログにはステータス200が残っていた。中身は空っぽ。エラーを出さないAPIがこの世で一番タチが悪い。
X API v2の認証は複雑だ。Bearer Tokenでは取得できていたデータが、OAuth 1.0aでは権限スコープの不一致でサイレント失敗する。デバッグに丸一日を費やした。
「fix: X記事(note_tweet)の個別取得をOAuth 1.0aに変更」
結局、OAuth 1.0a認証でリトライ処理を入れることで、全文取得の成功率を無理やり引き上げた。根本的な解決にはなっていない。今はこれで動かすしかない。
YouTubeのOGP取得にも苦労した。
「fix: OGPカード表示改善(YouTube対応 + t.co→X記事フォールバック)」
YouTubeはBotからのOGP取得をブロックする。HTMLの読み取りサイズを50KBから800KBへ拡大した。軽量なスクレイピングでは取得できない。読み取りサイズを800KBに拡大し、og:title発見時に早期終了させる。
一番キツかったのは、画像や引用ツイートが過去投稿で消えていたバグだ。
「fix: 画像・引用ツイートをDBに永続化(過去投稿で消失するバグ修正)」
データベースに永続化していなかっただけだ。シンプルなミスほど見つけにくい。全タブで確認するまで動いたと言わないことにした。
ここまで読んだあなたに
今なら無料で全機能をお試しいただけます。設定後は完全放置でプロ品質の投稿を毎日生成。
落とし穴
タイムラインの更新インジケーターを消そうとした。
「fix: タイムライン更新中インジケーターが消えないバグ修正」
幽霊ロードを直すために、finallyブロック内のキャンセルチェックを外した。それが最悪の引き金になった。APIが成功しても失敗しても、別の非同期処理が走るたびにインジケーターが点滅し続ける。
画面上部でずっとチカチカ光っている。アプリを開くたびに、僕の心拍数に合わせてインジケーターが明滅する仕様が完成した。次からはインジケーターの制御は状態管理ライブラリに任せる。たぶん。
今日の数字
| 項目 | 数字 | 比較対象 |
|------|------|----------|
| 総コミット数 | 48件 | 先週は12件。バグ修正の嵐だった |
| 新機能追加 | 3件 | バグ修正は5件。機能より修正が多い |
| バッチ分割サイズ | 200件 | 一括941件投げでURL長制限エラー即死 |
| 開発・修正期間 | 1日 | 企業ならAPI仕様調査とテストで最低1週間 |
個人開発で48件のコミットを1日で完遂した。通常ならAPI仕様の調査とテストだけで最低1週間はかかる規模だ。
しんたろー:
12時間ぶっ通しでコードを書いた。Claude Codeのコーディング速度がなければ完全に心が折れていた。
よくある質問
APIの月間コストをどうやって削減したのか?
URL検索を公式APIからサードパーティのAPIへ移行した。公式APIは月間の取得上限が厳しく、すぐにコストが跳ね上がる。外部サービスを経由することで、上限消費を回避しながらデータを取得している。
DBの正規化でパフォーマンスはどう変わったか?
フロントエンドで全件受け取ってからフィルタしていた処理を、データベース側でのフィルタリングに変更した。不要なデータをネットワークに流さないため、レスポンスサイズが激減した。クライアント側のメモリ消費も大幅に抑えられている。
RLSによるセキュリティ対策はどうなっているか?
非表示ユーザーの管理テーブルなどに、Row Level Securityを適用している。データベースレベルで自分のデータしか読み書きできない制約をかけている。APIトークンが漏洩しても、他人のデータにはアクセスできない構造だ。
終わらない開発の日常
動いたと思ったら別の場所が壊れる、モグラ叩きのような1週間だった。

この記事が参考になったら、ThreadPostを試してみませんか?
投稿作成・画像生成・スケジュール管理まで、全てAIにお任せできます。
ThreadPostをもっと知る