「1 分おき」の監視は、1 件あたり 10 分に 1 回だった:速くする前に、見直しの間隔と、通知が届いた数を数えた
トレカダッシュ 開発の記録 / 2026年9月
iOS アプリ「トレカダッシュ」の中でも、先着販売(在庫が数分で消える販売)の通知は、速さが勝負です。そこで、先着の監視は、「1 分おきに動く」ように作りました。
2026 年 9 月 7 日に、その反応速度を実際に測ってみると、設計の意図と実態が約 10 倍ずれていました。この記事は、そこから、さらに「速くした結果、別のものが遅くなった」ことまで見つかった記録です。
数字は、2026 年 9 月 7 日の測定の記録から書いています。
「1 分おき」は、1 件あたり 10 分に 1 回だった
| 測ったこと | 値 |
|---|---|
| ジョブの間隔 | 約 61 秒(設計どおり) |
| 監視する対象 | 63 件 |
| 1 回で見られる件数 | 4〜9 件(53 回中 48 回が、時間予算切れ) |
| 1 件あたりの見直しの間隔 | 約 10 分に 1 回 |
| 7 日間で、先着を捕まえた回数 | 3 回(空振りは 8,648 回) |
「1 分おきに動く」と書いてあると、速いつもりになります。しかし、利用者が体感するのは、1 件あたり、何分に 1 回見に行くかです。63 件を、1 回に 4〜9 件しか見られないなら、1 周するのに約 10 分かかります。計算式は、対象の件数 ÷ 1 回に見られる件数 × 間隔です。この式を一度も出していなかったので、「動いているのに、勝てない」状態が続いていました。
原因:共有の外部 API の枠を、対等に奪い合っていた
在庫を見に行くときに使う、楽天の API は、1.5 秒に 1 回しか呼べません。この枠を、5 つのジョブが対等に奪い合っていました。いちばん急ぐ監視の取り分は、13%しかありませんでした。
直し方は、急ぐ処理が走っている間だけ、まとめて見る系の処理が、枠を取りに行かないようにすることでした。ここで、見つけた落とし穴があります。
- 譲る印を、1 回の呼び出しごとに立てて、下ろすと、呼び出しの合間に、奪い返されます。実測では、「1 回 4 件」の回が、20 回中 13 回、残りました。
- 印を、巡回のあいだ立てっぱなしにすると、1 回に見られる件数が、30〜33 件になりました。
- 譲る側には、必ず待ちの上限を置きます。置かないと、譲りっぱなしで飢えます。
速くしたら、いちばん速く見たいものが、遅くなった
同じ日に、先着の反応を上げようとして、いくつかのジョブの間隔を詰めました。Amazon の確認を 5 分おきにしたところ、今度は、楽天ブックスの瞬殺監視が遅くなりました。
| 前 | 間隔を詰めた後 | 戻した後 | |
|---|---|---|---|
| 楽天ブックスの瞬殺監視の完了間隔 | 60〜80 秒 | 2 分 41 秒・3 分 52 秒 | 60〜110 秒 |
| 同じ監視の見送り(10 分あたり) | 0 回 | 6 回 | 0 回 |
| ジョブの順番待ち | 0 | 17〜29 | 0 |
原因は、Amazon の確認が 1 回 5〜8 分かかるのに、間隔を 5 分にしたことです。1 回の所要時間が、間隔以上になると、そのジョブは、同時に走れる枠(8 つ)の 1 つを、ずっと占有します。その分だけ、ほかのジョブが順番を待ちます。間隔を戻すと、元に戻りました。
もう 1 つ:「審査しない」ものには、通知が飛ばない
先着の通知は、出品が「定価より高い転売」ではないかを、価格で審査してから送ります。この審査は、単位が食い違って比べられないとき、「審査しない」として通り過ぎる作りでした。コメントには「推測しない、安全側」と書いてありました。
ところが、「審査しなかった出品」には、「価格が確認できていない」という印が付き、通知が止まります。直近 7 日間の先着 148 件を数えると、こうでした。
| 結果 | 件数 |
|---|---|
| 通知した | 41 件 |
| 通知を見送った(定価を確認できていない) | 25 件 |
画面に出た 55 件のうち、45% に、通知が飛んでいませんでした。記事はフィードに出るので、監査にも映りません。苦情も出ません。検知を 10 分から 80 秒に速くしても、その先で、半分が静かに落ちていたのです。
しかも、「比べられない」は思い込みでした。カタログの定価 5,280 円を、1 箱のパック数 12 で割ると 440 円で、ちゃんとしたパック 1 つの値段です。つまり、その金額は、すでに 1 箱ぶんの値段で、掛けずに、そのまま比べればよかったのです。
分かったこと
「速くして」の答えは、たいてい「速くする」ではなく、「途中で落ちているものを見つける」。
- 間隔ではなく、1 件あたりの見直しの間隔を測る。対象の件数 ÷ 1 回の処理件数 × 間隔。
- 届いた数を数える。作った記事の数ではなく、通知まで届いた数です。
- 「判断できないとき」に、どちらへ倒れるかを書き出す。倒れた先が、利用者に届かない側なら、それは安全側ではありません。
- 速くするほど、ほかが遅くなることがある。同時に走れる枠は、有限です。
- 「比べられない」と書いてあるところは、実データで見直す。単位をそろえたら、比べられました。
この話に出てくるもの
- トレカダッシュ — トレカの抽選・予約・先着の情報を集める iPhone アプリ
- 配備のたびに、日次の処理が丸ごと走り直していた — 同じ「定期処理」の、別の失敗
- 通知は取り消せない — 通知の誤りを、数えて見つけた記録
- 確認できなかったときに、通していた — 関門が倒れる向きの話
ほかの記録
- 1 つの記事を商品ごとに分ける処理で起きた 3 つの取り違え:子が親になり、共有リンクが別の店を指し、名前が 2 つの商品のものだった — 分けた「子」の記事に親向けの処理をもう一度かけて、締切当日の抽選 60 件(23 店)が消えた。13 店が共有するリンクで別の店の親を引いた。2 つの商品が名乗る名前が 267 組あった。画面に何も出ないまま、本物が消える失敗の記録。
- 本物の抽選を、静かに捨てていた 4 つの実例:正規表現・年のない日付・まとめて聞く・null — 「x.com」が「e-starbox.com」に一致して応募リンクが一度も採用されなかった、年のない日付が 6 年前と読まれてポケカ案件が 0 件だった、まとめ判定の数がずれた、「決められない」が「無い」と読まれ 129 件を伏せかけた。捨てる判定の失敗の記録。
- 配備のたびに、日次の処理が丸ごと走り直していた:48 時間で 477 回、その日の Gemini 費用の 46.6% — 1 日 1 回のはずの処理が 43 回走り、Gemini の費用の 46.6% を占めていた。タイムアウトした回は最終実行時刻が書かれず、再起動のたびに取りこぼし扱いされていた。逆に、配備が 8 時に重なって、ダイジェストが 1 通も届かなかった問題も。
コメント
感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。
押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはあつかいに書いています。