App Store Connect の App Analytics には「削除数」という指標があります。インストール数のすぐ隣に並んでいるのに、長いあいだ見ないふりをしていた数字です。
はじめて真面目に眺めた日、それまで追いかけていた指標——星評価、クラッシュ率、DAU——のどれもが、この数字を説明してくれないことに気づきました。評価は付いている。落ちてもいない。それでも人は静かに消していく。
削除されるアプリは、リリースから 3 日以内、長くても 1 週間以内に削除されます。Rork はアプリを素早く立ち上げられるツールなので、この初週の設計を後回しにしたまま次のアプリへ進みがちです。生産性で量産したアプリが、量産したまま消えていく。個人開発で最ももったいない負け方だと考えています。
削除を減らす作業は、機能を足すことではありませんでした。最初の 7 日に何をどの順で見せるかを、リリース前に決めることでした。以下、測り方から順に書いていきます。
ストアの星評価ではなく「削除タイミング」を見る
多くのアプリ運営の解説では、星評価やクラッシュ率を主要な KPI に挙げます。これは間違いではないですが、個人開発者にとって最も大事な KPI は「ユーザーがいつ削除したか」です。星評価は削除しないユーザーが付けるもので、削除する人は静かに去ります。星評価が高いのに DAU が伸びない場合、削除タイミングを見ていない可能性が高いです。
リリース後の最初の一ヶ月は、「インストール後 N 日で削除されたユーザーの割合」を毎朝見ます。私が基準にしている三つの数字です。
D0 削除率 — インストール当日に消された割合(理想は 5% 未満)
D1 削除率 — 翌日までに消された割合(理想は 15% 未満)
D7 削除率 — 一週間以内に消された割合(理想は 40% 未満)
業界の標準値はもっと厳しいですが、個人開発で広告予算を使わない場合の現実的な閾値です。これより悪い場合、機能ではなく初週の設計に問題がある可能性が高いです。
削除率は Firebase では取れない — 実際の測り方
ここで一度、測定の現実に触れておきます。「削除率を Firebase で見ましょう」と書いてある記事をときどき見かけますが、これは正確ではありません。Firebase Analytics が自動収集する app_remove イベントは Android 専用で、Play ストア経由のインストールにしか発火しません。iOS 側には対応するイベントがなく、Firebase のダッシュボードをどれだけ探しても iOS の削除は出てきません。
実際には、次の四つを組み合わせて近似することになります。
| 取得元 | 取れるもの | 粒度と注意点 |
|---|---|---|
| App Store Connect / App Analytics | 削除数(Deletions) | 日次・国別・端末別。ただし診断データの共有に同意した利用者のみが母数のため、実数ではなく傾向値として扱う |
| Google Play Console | アンインストール数 | 日次。インストール日コホート単位ではないので、D0/D1/D7 に直接は割り当てられない |
| Firebase Analytics | app_remove(Android のみ) | iOS では発火しない。Android の削除タイミングを実測できる唯一の経路 |
| FCM / APNs の送信結果 | トークンの無効化 | 送信時に UNREGISTERED / NotRegistered が返ればそのトークンは死んでいる。削除の遅行シグナル |
iOS で D0・D1・D7 の削除率を出したい場合、私は次のように近似しています。まずインストール日をローカルに保存し、日次のアクティブ判定を自前のイベントとして送ります。その上で「インストール日コホートのうち、N 日目以降に一度も起動していない割合」を出し、これを App Store Connect の削除数の日次推移と重ねます。
// インストール日を初回起動時に一度だけ固定し、以降のコホート判定に使う
const INSTALL_KEY = "installed_at_iso";
export async function resolveInstallCohort(storage: Storage, now = new Date()) {
let iso = await storage.getItem(INSTALL_KEY);
if (!iso) {
iso = now.toISOString();
await storage.setItem(INSTALL_KEY, iso);
}
const installedAt = new Date(iso);
const days = Math.floor((now.getTime() - installedAt.getTime()) / 864e5);
return { installedAt, dayIndex: days, cohort: iso.slice(0, 10) };
}dayIndex と cohort をアクティブイベントのパラメータに載せておくと、「4月29日にインストールした人の、3日目の生存率」が後から出せるようになります。ここで出るのは厳密には「離脱率」であって「削除率」ではありません。削除していないが開いていないだけの人が混ざります。それでも、削除数の日次推移と形が一致していれば、初週のどこで人が離れているかの当たりは十分に付きます。
注意点として、この指標は必ずリリース前に仕込んでおいてください。インストール日は後から遡って復元できないため、後付けするとそれ以前の利用者が全員「不明」になります。私は一度これを忘れて、最初の 3 週間分のコホートを丸ごと失いました。
D0: 起動 60 秒以内に「これは私のためのアプリだ」を渡す
D0(インストール当日)に削除されるアプリには、共通のパターンがあります。起動直後にユーザーが「これは私のために作られたアプリだ」と感じるエピソードが用意されていないのです。Rork で作るアプリはコンセプトが先鋭化していることが多いので、本来この設計は得意分野なのですが、ついつい「機能の説明」を最初に置いてしまい、ユーザーが冷めます。
私が D0 で気をつけているのは、起動から 60 秒以内に次の三つを終えることです。
1. 「あなたのことを知りたい」を伝える質問を1問だけする
2. その答えに応じてホーム画面の見え方を実際に変える
3. 「これがあなた専用の状態です」と明示する
質問を1問に絞るのが鍵です。質問が多いと、ユーザーは「面倒なアプリ」と判断して 30 秒で削除します。1問だけ、しかもその答えがホーム画面に即座に反映されることが大事です。たとえば「壁紙アプリなら好きな雰囲気を1つだけ選ばせ、その雰囲気のコレクションだけ最初に見せる」が分かりやすい例です。
Rork のテンプレ的なオンボーディングをそのまま使うと、複数ステップのフォームになりがちです。これは D0 削除率を悪化させる元凶です。私は Rork のオンボーディングを必ず1問に削ります。
なお、この 60 秒で効いているのは文言よりも手触りのほうです。遷移の速度・ハプティクス・アニメーションの詰め方については Rork アプリの『触った瞬間の印象』を決める3つの実装 に分けて書いています。
D1: 起動から 24 時間後に「思い出される理由」を仕込む
D1(インストール翌日)に削除されるユーザーは、「使う理由を見つけられなかった」人です。一日経ってもう一度アプリを開く動機が、明示的に作られていない場合に発生します。
ここで多くの個人開発者が手を伸ばすのが「プッシュ通知」ですが、私の経験では D1 段階でのプッシュ通知は逆効果です。インストール翌日に通知が来ると、「うっとうしい」と感じて即削除する人がいます。代わりに、アプリ自体に「翌日になったら別の表情を見せる」仕掛けを入れます。
具体例を一つ挙げます。私のとあるアプリでは、初日の夜にだけ表示される画面と、翌日の朝にだけ表示される画面を別物にしてあります。ユーザーは翌朝アプリを開いたとき、「あ、昨日とは違う」と気づきます。気づきは記憶を強化し、削除のスイッチを押す指を止めます。
// アプリ起動時に「経過日数」と「時間帯」で見せ方を切り替える
function getMorningSurfaceForDay1(installedAt: Date, now: Date) {
const hours = (now.getTime() - installedAt.getTime()) / 36e5;
if (hours >= 12 && hours <= 36 && now.getHours() < 12) {
return "morning_after_first_day";
}
if (hours < 12) {
return "first_evening";
}
return "regular_home";
}この単純なロジックが入っているだけで、アプリは「時間と一緒に育つ」感じを出せます。プッシュ通知に頼らずに、再訪したときの体験そのもので継続を促すのが、私の好む設計です。
どうしても D1 で通知を使いたい場合は、許可ダイアログを出さずに通知センターへ静かに配信する provisional 認可という選択肢があります。ただし Expo の定番コードをそのまま貼ると provisional の設定が握りつぶされる罠があり、これは 許可を聞かずに通知を届ける — Rork アプリの provisional 認可 にまとめました。
D3: 「使い込んだ感」を可視化する
D3(インストール3日目)の削除は、「もう新鮮味がない」と感じたユーザーが落ちるタイミングです。ここで効くのは「使い込んだ感」を見せる工夫です。
私が好むのは、ユーザーが起動するたびにじわじわ蓄積される小さな履歴の可視化です。たとえば壁紙アプリなら「これまで保存した壁紙の枚数」を、瞑想アプリなら「これまで瞑想した分数」を、シンプルに表示するだけで構いません。重要なのは、その数字が「自分の積み重ね」だと感じられることです。
// ユーザーの累積アクションを軽い演出で見せるパターン
function buildStreakBadge(actionCount: number) {
if (actionCount === 0) return null;
if (actionCount < 10) return { label: `${actionCount}回 はじめての旅`, tone: "soft" };
if (actionCount < 50) return { label: `${actionCount}回 続けています`, tone: "warm" };
return { label: `${actionCount}回 積み上げています`, tone: "deep" };
}ここで気をつけるのは、ゲーミフィケーション的な煽りにしないことです。「あと N 回でレベルアップ!」のような強いインセンティブは、Rork で作るような個人開発のアプリの世界観と相性が悪いことが多いです。淡く、控えめに、ユーザーの行動が積み重なっていることを伝えるだけで十分です。
D7: 「ここから本領発揮」フェーズを明示する
D7(一週間後)まで残ったユーザーは、削除候補ではなく「本当のユーザー」になりかけています。ここで多くのアプリは何もせず、ただ機能を提供し続けます。私はこの時点で「ここから本領発揮」というフェーズを明示することを推奨します。
具体的には、一週間使ったユーザーにだけ表示される機能や設定項目を作ります。これは「上級者向け」というラベルではなく、「あなたはもう新規ユーザーではないので、この機能を使えます」というアンロックの体験です。
function getUnlockedFeatures(daysSinceInstall: number) {
const features = ["basic"];
if (daysSinceInstall >= 1) features.push("personal");
if (daysSinceInstall >= 3) features.push("history");
if (daysSinceInstall >= 7) features.push("advanced_filters");
if (daysSinceInstall >= 30) features.push("custom_themes");
return features;
}機能を後出しにする最大のメリットは、初週の認知負荷を下げることと、長く使うほど「アプリが応えてくれる感」が出ることです。Rork で作るアプリは機能数が控えめになりがちなので、最初から全部出さず、時間で段階的に開く設計と相性がいいです。
削除直前のサインを拾う
ユーザーが削除する前には、必ず「削除を考え始めるサイン」が出ます。代表的なものは次の三つです。
第一に、起動頻度の急激な低下です。たとえば「過去 7 日のうち 5 日起動していたユーザーが、突然 2 日続けて起動しなくなる」。これは離脱の前兆です。
第二に、設定画面への滞在時間の増加です。「通知を切る」「データを消す」といった操作を探しているサインで、削除直前によく見られます。
第三に、アプリ内のヘルプやお問い合わせを開く回数の増加です。困っていることがあるのに解決できていないサインです。
これらを Firebase のイベントとして拾い、特定の閾値を超えたユーザーにだけ「アプリ内のお礼メッセージ」を出すと、削除率が下がるケースを見たことがあります。ただし通知は出してはいけません。アプリを開いている瞬間に、控えめに気持ちを伝えるだけです。
「削除されたユーザー」を呼び戻そうとしない
最後に、これは個人開発者として大事にしている考え方です。削除されたユーザーをメールやリターゲティング広告で呼び戻すのは、個人開発の場合は労力に見合いません。
理由は二つあります。第一に、削除したユーザーは「自分には合わなかった」と判断した人で、その判断は基本的に正しい。第二に、呼び戻しのコストは、新しいユーザーに来てもらうためのオーガニック改善に投じたほうが、長期的に効きます。
削除を真剣に減らす運用とは、削除した人を追わないことと表裏一体です。今いるユーザーが削除しないように体験を磨くこと、それが個人開発の継続率設計の中心です。
残ったユーザーの価値をどう伸ばすかは、初週の設計とは別の話になります。Day 1 以降の長期的なリテンションと LTV の組み立ては Rorkアプリのリテンション・LTV最大化 を参照してください。
次の最小の一歩
明日、自分のアプリを一度アンインストールして、もう一度ストアからインストールしてみてください。最初の 60 秒、最初の翌朝、3 日目の朝で、それぞれアプリは何を見せてきますか。「これは私のためのアプリだ」を 60 秒以内に感じられたか、翌朝に違いを感じたか、3 日目に積み重ねを感じたか。感じなかったポイントが、削除されている原因のすぐ近くにあります。