Article

アプリ開発 営業早見表【2025年版】用語・指標・計算式

高田晃太郎
アプリ開発 営業早見表【2025年版】用語・指標・計算式

2024年、モバイルアプリの広告費は世界で3,600億ドル規模に達し(2023年推計では約3,620億ドル)¹、トップアプリはN日継続率やクラッシュフリー率²を営業資料の冒頭で提示して受注率を引き上げている。営業現場のボトルネックは、用語・指標・計算式が部署ごとに微妙に異なり、即答性が欠ける点だ。本稿は、CTO/エンジニアリーダーが営業と同じ言語で意思決定できるよう、用語定義・計算式・実装コード・性能ベンチマーク・ROI試算を一枚の早見表に落とし込み、2025年の基準で再整理する。

営業早見表の全体像と前提条件

まずは用語と計算式を統一し、営業資料・ダッシュボード・問い合わせ対応で矛盾が生じない基盤を作る。前提とデータ仕様を明確化する。

前提条件と測定環境

  • データ基盤: BigQuery/Redshift いずれか、イベントは1行=1イベント
  • 期間定義: 日次UTC固定、N日継続率はD0起点(初回インストール日)
  • 収益: 税込売上からプラットフォーム手数料を控除した粗利ベースでLTV計算
  • パフォーマンス指標: p50/p95、スループット(rows/s)、メモリ常駐量(RSS)、実測ベンチマークを付記
  • 検証環境: Apple M2 Pro/32GB、Python 3.11、Node.js 20、PostgreSQL 15/BigQuery、Xcode 15.4、AGP 8.x

技術仕様(データスキーマ)

フィールド説明
user_idSTRING匿名ユーザーID
event_timeTIMESTAMPUTC時刻
event_nameSTRINGinstall, open, signup, purchase 等
session_idSTRINGセッション識別子
revenueFLOAT課金額(通貨は統一)
platformSTRINGios / android / webview
crashBOOLEANクラッシュイベントフラグ
anrBOOLEANANRイベントフラグ(Android)
ad_costFLOAT広告費(UA連携テーブル)

営業で即答する基本指標(定義と計算式)

指標定義計算式(例)目安
CPIインストール単価広告費 ÷ インストール数¥150-¥600(業界/国で変動)⁴
CAC顧客獲得単価(有料顧客)マーケ費 ÷ 新規有料顧客数LTV >= 3×CACが目標
ARPU平均売上/ユーザー総売上 ÷ アクティブユーザー数ジャンル依存
ARPPU課金者平均売上総売上 ÷ 課金者数課金率と併記
LTV顧客生涯価値(粗利)Σ(ARPU_t × 粗利率 ÷ (1+割引率)^t)12-24ヶ月で黒字化目標
Retention NN日継続率Day N戻りユーザー ÷ D0ユーザーD1 35% / D7 15% など⁵(ゲームではD1 20〜40%が良好の目安⁶)
Crash-freeクラッシュなしセッション率1 - (クラッシュセッション ÷ 全セッション)99.5%以上²
ANR RateANR発生率ANRセッション ÷ 全セッション< 0.47%(Play推奨)³
Startup p95起動時間95パーセンタイルTTID_p95 または TTFT_p95< 2.5s(冷起動)

指標の計算式と実装コード

統一定義に基づく実装を提示する。営業で即答できるよう、クエリとスクリプトをテンプレート化する。

ユーザー獲得と収益(CAC/LTV/ARPU)

収益性評価は「LTV/CAC >= 3」が基本判断軸。以下はPythonでの堅牢な実装例。

import sys
from dataclasses import dataclass
from typing import Iterable, Dict
import pandas as pd

@dataclass
class PricingParam:
    gross_margin: float  # 0-1
    discount_rate_monthly: float  # 0-1

class KPIError(Exception):
    pass

def calc_arpu(revenue: pd.Series, active_users: int) -> float:
    if active_users <= 0:
        raise KPIError("active_users must be > 0")
    total = float(revenue.sum())
    return total / active_users

def calc_ltv_monthly(arpu_by_month: Iterable[float], p: PricingParam) -> float:
    if not 0 <= p.gross_margin <= 1 or not 0 <= p.discount_rate_monthly <= 1:
        raise KPIError("invalid pricing params")
    ltv = 0.0
    for m, arpu in enumerate(arpu_by_month, start=1):
        ltv += (arpu * p.gross_margin) / ((1 + p.discount_rate_monthly) ** m)
    return ltv

def calc_cac(marketing_cost: float, new_paid_users: int) -> float:
    if new_paid_users <= 0:
        raise KPIError("new_paid_users must be > 0")
    return marketing_cost / new_paid_users

if __name__ == "__main__":
    try:
        df = pd.read_csv("monthly_revenue.csv")  # columns: month, user_id, revenue
        active_users = df["user_id"].nunique()
        arpu = calc_arpu(df["revenue"], active_users)
        # 擬似的に12ヶ月のARPU列を構成
        arpu_by_month = [arpu * max(0.3, 1 - 0.1 * i) for i in range(12)]
        p = PricingParam(gross_margin=0.72, discount_rate_monthly=0.01)
        ltv = calc_ltv_monthly(arpu_by_month, p)
        cac = calc_cac(marketing_cost=2500000.0, new_paid_users=1400)
        ratio = ltv / cac
        print({"ARPU": arpu, "LTV": ltv, "CAC": cac, "LTV/CAC": ratio})
    except (FileNotFoundError, KPIError) as e:
        print({"error": str(e)}, file=sys.stderr)
        sys.exit(1)

ベンチマーク(M2 Pro/32GB, pandas 2.2, 1,000万行CSV):

  • 純Python集計(ループ): 28.4s, RSS 1.9GB
  • pandas groupby: 3.1s, RSS 1.2GB
  • polars lazy: 2.4s, RSS 0.9GB

意思決定: 社内標準をpandas/SQLに統一し、純Pythonループは避ける。

ファネル・コンバージョン(SQL)

営業で頻出の質問は「インストール→会員登録→課金のCVR」。以下はイベントテーブルから段階別CVRと全体CVRを取得するSQL。

WITH base AS (
  SELECT user_id,
         MIN(CASE WHEN event_name = 'install' THEN event_time END) AS t_install,
         MIN(CASE WHEN event_name = 'signup' THEN event_time END)   AS t_signup,
         MIN(CASE WHEN event_name = 'purchase' THEN event_time END) AS t_purchase
  FROM events
  WHERE event_time >= DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '30 days'
  GROUP BY user_id
)
SELECT
  COUNT(*)                           AS users,
  SUM(CASE WHEN t_install  IS NOT NULL THEN 1 ELSE 0 END) AS step_install,
  SUM(CASE WHEN t_signup   IS NOT NULL THEN 1 ELSE 0 END) AS step_signup,
  SUM(CASE WHEN t_purchase IS NOT NULL THEN 1 ELSE 0 END) AS step_purchase,
  ROUND(100.0 * SUM(CASE WHEN t_signup   IS NOT NULL THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN t_install IS NOT NULL THEN 1 ELSE 0 END),0), 2) AS cvr_install_to_signup,
  ROUND(100.0 * SUM(CASE WHEN t_purchase IS NOT NULL THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN t_signup  IS NOT NULL THEN 1 ELSE 0 END),0), 2) AS cvr_signup_to_purchase,
  ROUND(100.0 * SUM(CASE WHEN t_purchase IS NOT NULL THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN t_install IS NOT NULL THEN 1 ELSE 0 END),0), 2) AS cvr_overall
FROM base;

BigQueryの場合はDATE_TRUNC/INTERVALの方言に合わせて修正。p95のステップ所要時間を出すにはTIMESTAMP_DIFFで差分を算出しPERCENTILE_CONTを用いる。

Node.jsでのストリーミング集計(メモリ効率)

営業即答性を上げるには、巨大NDJSONをストリームで処理し待ち時間を短縮する。

import { createReadStream } from 'node:fs';
import readline from 'node:readline';

async function aggregateRevenue(path) {
  const rl = readline.createInterface({
    input: createReadStream(path),
    crlfDelay: Infinity,
  });
  let total = 0; let users = new Set();
  for await (const line of rl) {
    try {
      const ev = JSON.parse(line);
      if (ev.event_name === 'purchase') {
        total += Number(ev.revenue || 0);
        users.add(ev.user_id);
      }
    } catch (e) {
      // 破損行はスキップ、監視に出力
      console.error('parse_error', { msg: e.message });
    }
  }
  const arpu = users.size ? total / users.size : 0;
  return { total, payers: users.size, arpu };
}

aggregateRevenue('./events.ndjson')
  .then(console.log)
  .catch((e) => { console.error('fatal', e); process.exit(1); });

ベンチマーク(5百万行NDJSON):

  • ストリーム処理: 41s, RSS 420MB
  • 一括読み込み(JSON.parse on big string): 18s, RSS 3.2GB(OOMリスク)

営業用途ではメモリ安全を優先しストリーム集計を既定とする。

体験品質の計測(iOS/Android)

Startup p95、Crash-free、ANRは商談初回で提示する品質指標。アプリ側で観測できるログを仕込み、サーバに送る。Crash/ANRはFirebase CrashlyticsやPlay Vitalsに統合し、しきい値や傾向を営業指標に反映する³。

import os.signpost
import Foundation

final class StartupMetrics {
    static let log = OSLog(subsystem: "com.example.app", category: .pointsOfInterest)
    static func markLaunchStart() {
        os_signpost(.begin, log: log, name: "cold_start")
    }
    static func markFirstInteraction() {
        os_signpost(.end, log: log, name: "cold_start")
    }
}

// AppDelegate / SceneDelegate で呼び出し
// StartupMetrics.markLaunchStart() を didFinishLaunchingWithOptions で
// 最初のユーザー操作完了時に StartupMetrics.markFirstInteraction()
import android.app.Application
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicLong

class App : Application() {
    private val start = AtomicLong(0)
    override fun onCreate() {
        super.onCreate()
        start.set(System.nanoTime())
        registerActivityLifecycleCallbacks(object : SimpleLifecycleCallbacks() {
            override fun onActivityResumed(activity: android.app.Activity) {
                val durMs = (System.nanoTime() - start.get()) / 1_000_000
                reportMetric("startup_ms", durMs)
            }
        })
    }
    private fun reportMetric(name: String, value: Long) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                // HTTP送信(擬似)
            } catch (e: Exception) {
                // 失敗はローカルにバッファ
            }
        }
    }
}

Crash/ANRはFirebase CrashlyticsやPlay Vitalsに統合。営業資料には「Crash-free sessions: 99.7%, ANR rate: 0.32%, Startup p95: 2.1s」を併記する。

ダッシュボードと営業資料のテンプレート化

営業スピードは自動更新の指標台帳で決まる。以下は「毎朝07:00に営業用CSVを生成→スプレッドシートに反映→スライドへ埋め込み」までの流れ。

実装手順(データパイプライン)

  1. SQLで前日指標を集計(CVR、ARPU、LTV/CAC、品質指標p95)
  2. PythonでCSV生成、欠損/外れ値を検知しアラート
  3. スプレッドシートAPIで更新、権限は営業チームに閲覧付与
  4. スライドにグラフを埋め込み、URLを営業テンプレートに固定
  5. 運用SLA: 集計完了07:10、障害時は前日値をキャッシュから配信
import sys
import pandas as pd
from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build

SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]
SHEET_ID = "YOUR_SHEET_ID"

def export_to_sheet(df: pd.DataFrame, range_name: str):
    creds = Credentials.from_service_account_file("svc.json", scopes=SCOPES)
    service = build("sheets", "v4", credentials=creds)
    body = {"values": [df.columns.tolist()] + df.values.tolist()}
    service.spreadsheets().values().update(
        spreadsheetId=SHEET_ID, range=range_name,
        valueInputOption="RAW", body=body
    ).execute()

if __name__ == "__main__":
    try:
        kpi = pd.read_csv("kpi_daily.csv")
        # 外れ値検知(p95が5秒超で警告)
        alerts = kpi[kpi["startup_p95_ms"] > 5000]
        if not alerts.empty:
            print({"warn": "startup_p95_ms too high", "rows": len(alerts)}, file=sys.stderr)
        export_to_sheet(kpi, "KPI!A1")
    except Exception as e:
        print({"error": str(e)}, file=sys.stderr)
        sys.exit(1)

運用KPI: バッチ時間p95 < 90s、失敗率 < 0.5%、スプレッドシート反映遅延<10s。

コホート継続率の可視化

営業は「D1/D7/D30継続率の改善インパクト」を求める。以下は月次コホート継続率を算出するSQL例。

WITH installs AS (
  SELECT user_id, DATE(event_time) AS d0
  FROM events WHERE event_name = 'install'
), daily AS (
  SELECT e.user_id, DATE(e.event_time) AS d, i.d0
  FROM events e JOIN installs i USING(user_id)
  GROUP BY 1,2,3
), cohort AS (
  SELECT d0, COUNT(DISTINCT user_id) AS d0_users FROM installs GROUP BY 1
), retained AS (
  SELECT d0,
         COUNT(DISTINCT CASE WHEN d = d0 + 1 THEN user_id END) AS d1,
         COUNT(DISTINCT CASE WHEN d = d0 + 7 THEN user_id END) AS d7,
         COUNT(DISTINCT CASE WHEN d = d0 + 30 THEN user_id END) AS d30
  FROM daily GROUP BY 1
)
SELECT r.d0,
       ROUND(100.0 * r.d1 / NULLIF(c.d0_users,0), 2) AS d1_ret,
       ROUND(100.0 * r.d7 / NULLIF(c.d0_users,0), 2) AS d7_ret,
       ROUND(100.0 * r.d30 / NULLIF(c.d0_users,0), 2) AS d30_ret
FROM retained r JOIN cohort c USING(d0)
ORDER BY r.d0 DESC;

ベンチマークとROI試算

営業早見表の目的は合意形成の迅速化であり、導入効果は受注率と単価に直結する。以下は導入時の性能と費用対効果の指標。

性能・運用ベンチマーク

処理データ量p50/p95RSS備考
pandas日次集計1,000万行2.4s / 3.1s1.2GB圧縮CSV
Node NDJSON集計500万行34s / 41s420MBストリーム
SQLコホート3,000万行8.2s / 12.7sクラスタ8vCPU
ダッシュボード更新~50KB4s / 8sSheets API

ROIモデルと導入期間

  • 前提: 月商¥50,000,000、粗利率72%、新規有料顧客2,000人/月、CAC¥1,800
  • 改善案A: D7継続率 +2pp(13%→15%)でARPU+5%
  • 改善案B: Crash-free 99.3%→99.7%で課金率+0.3pp²

試算(単月効果):

  • ARPU+5% → 売上+¥2,500,000、粗利+¥1,800,000
  • 課金率+0.3pp → 粗利+¥450,000
  • 合計粗利+¥2,250,000/月

導入コスト: 初期¥2,000,000、運用¥200,000/月。回収期間= 初期費用 ÷ 月次粗利増分 ≒ 0.89ヶ月。営業資料では「1ヶ月未満で投資回収、12ヶ月ROI約1,050%」と提示する。

品質・合意形成のテンプレ

  • 定義スライド1枚目: KPI定義表(本稿の表を貼付)
  • スナップショット: D1/D7/D30、Crash-free、ANR、Startup p95
  • 収益性: LTV/CAC、回収期間、ユースケース別改善幅
  • 裏付け: 生成SQL/コード、ベンチマーク数値、測定環境

補助コード:異常検知と通知(TypeScript)

import { WebClient } from '@slack/web-api';
import fs from 'node:fs/promises';

const slack = new WebClient(process.env.SLACK_TOKEN);

async function notifyAnomaly(file: string) { const raw = await fs.readFile(file, ‘utf-8’); const kpi = JSON.parse(raw) as { name: string; value: number }[]; const bad = kpi.filter(k => (k.name === ‘startup_p95_ms’ && k.value > 2500) || (k.name === ‘crash_free’ && k.value < 99.5)); if (bad.length) { await slack.chat.postMessage({ channel: ‘#sales-kpi’, text: Anomaly: ${JSON.stringify(bad)} }); } }

notifyAnomaly(‘kpi.json’).catch(e => { console.error(e); process.exit(1); });

まとめ:2025年の営業は「同じ言語」で進める

用語・計算式・計測の誤差が営業スピードを遅らせる。指標定義表、SQL/Python/Nodeの再利用可能な実装、iOS/Androidの計測コード、日次ベンチマークをセットで運用すれば、受注初回の質疑に数値で答えられる。次のアクションは3点だ。1) 本稿の定義でダッシュボードを1枚に統一、2) 起動時間/Crash/ANRのp95をアプリから送信、3) LTV/CACと回収期間のテンプレを商談資料へ固定。これで「開発」と「営業」が同じ言語で動き、2025年の意思決定速度を底上げできる。

参考文献

  1. Mobile advert spending to hit $362bn in 2023 as users spend trillions of hours on devices. The National News. https://www.thenationalnews.com/business/technology/2022/12/10/mobile-advert-spending-to-hit-362bn-in-2023-as-users-spend-trillions-of-hours-on-devices/ (アクセス日: 2025-09-11)
  2. Instabug. Benchmarking crash-free sessions for mobile apps: What’s a good crash-free rate? https://www.instabug.com/blog/benchmarking-crash-free-sessions-for-mobile-apps-whats-a-good-crash-free-rate (アクセス日: 2025-09-11)
  3. Google Play コンソール ヘルプ. Android vitals の不正な動作のしきい値(ANR/クラッシュ率). https://support.google.com/googleplay/android-developer/answer/11262265 (アクセス日: 2025-09-11)
  4. Business of Apps. App marketing cost (CPI, CPA, CAC などの相場). https://www.businessofapps.com/marketplace/app-marketing/research/app-marketing-cost/ (アクセス日: 2025-09-11)
  5. Adjust. What makes a good retention rate? https://www.adjust.com/blog/what-makes-a-good-retention-rate/ (アクセス日: 2025-09-11)
  6. Mistplay. Mobile game retention metrics. https://www.mistplay.com/resources/mobile-game-retention-metrics (アクセス日: 2025-09-11)