{"name":"Telemetry SaaS SQL Lab dataset","version":"2026-07-28","synthetic":true,"license":"Use and adapt for learning and testing.","tables":[{"name":"accounts","description":"One synthetic SaaS account with the dimensions and recurring revenue needed for customer-impact analysis.","grain":"One row per account.","joinKeys":["account_id"],"schema":[{"name":"account_id","type":"Utf8","description":"Stable synthetic account identifier."},{"name":"plan","type":"Utf8","description":"Commercial plan at the end of the sample window."},{"name":"region","type":"Utf8","description":"Coarse hosting or customer region."},{"name":"signup_at","type":"Timestamp","description":"When the account entered the sample cohort."},{"name":"monthly_revenue_usd","type":"Float64","description":"Synthetic normalized monthly recurring revenue."}],"rows":[{"account_id":"acct_acme","plan":"growth","region":"north_america","signup_at":"2026-07-01T09:00:00Z","monthly_revenue_usd":2400},{"account_id":"acct_beacon","plan":"business","region":"europe","signup_at":"2026-07-02T10:30:00Z","monthly_revenue_usd":1200},{"account_id":"acct_cinder","plan":"starter","region":"north_america","signup_at":"2026-07-03T13:15:00Z","monthly_revenue_usd":299},{"account_id":"acct_delta","plan":"growth","region":"asia_pacific","signup_at":"2026-07-04T08:45:00Z","monthly_revenue_usd":1800},{"account_id":"acct_ember","plan":"starter","region":"europe","signup_at":"2026-07-05T16:20:00Z","monthly_revenue_usd":199},{"account_id":"acct_fjord","plan":"free","region":"north_america","signup_at":"2026-07-06T11:10:00Z","monthly_revenue_usd":0}]},{"name":"product_events","description":"Durable account and user milestones for activation, adoption, and journey analysis.","grain":"One completed product milestone.","joinKeys":["account_id","user_id","session_id"],"schema":[{"name":"timestamp_utc","type":"Timestamp","description":"When the milestone completed."},{"name":"event_id","type":"Utf8","description":"Stable identifier for deduplication."},{"name":"account_id","type":"Utf8","description":"Joins the event to the synthetic account."},{"name":"user_id","type":"Utf8","description":"Synthetic actor identifier."},{"name":"session_id","type":"Utf8","description":"Groups ordered events within a visit."},{"name":"event_name","type":"Utf8","description":"Stable product milestone name."},{"name":"feature","type":"Utf8","description":"Product surface responsible for the event."},{"name":"status","type":"Utf8","description":"Final milestone outcome."},{"name":"release","type":"Utf8","description":"Application release that produced the event."}],"rows":[{"timestamp_utc":"2026-07-01T09:00:00Z","event_id":"evt_001","account_id":"acct_acme","user_id":"user_acme","session_id":"session_acme_1","event_name":"account_signed_up","feature":"onboarding","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-01T09:22:00Z","event_id":"evt_002","account_id":"acct_acme","user_id":"user_acme","session_id":"session_acme_1","event_name":"integration_connected","feature":"integration","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-02T14:10:00Z","event_id":"evt_003","account_id":"acct_acme","user_id":"user_acme","session_id":"session_acme_2","event_name":"first_query_completed","feature":"sql","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-03T15:40:00Z","event_id":"evt_004","account_id":"acct_acme","user_id":"user_acme","session_id":"session_acme_3","event_name":"dashboard_created","feature":"dashboards","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-09T12:05:00Z","event_id":"evt_005","account_id":"acct_acme","user_id":"user_acme","session_id":"session_acme_4","event_name":"feature_used","feature":"alerts","status":"success","release":"2026.07.2"},{"timestamp_utc":"2026-07-02T10:30:00Z","event_id":"evt_006","account_id":"acct_beacon","user_id":"user_beacon","session_id":"session_beacon_1","event_name":"account_signed_up","feature":"onboarding","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-02T11:05:00Z","event_id":"evt_007","account_id":"acct_beacon","user_id":"user_beacon","session_id":"session_beacon_1","event_name":"integration_connected","feature":"integration","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-02T11:45:00Z","event_id":"evt_008","account_id":"acct_beacon","user_id":"user_beacon","session_id":"session_beacon_1","event_name":"first_query_completed","feature":"sql","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-08T09:20:00Z","event_id":"evt_009","account_id":"acct_beacon","user_id":"user_beacon","session_id":"session_beacon_2","event_name":"dashboard_created","feature":"dashboards","status":"success","release":"2026.07.2"},{"timestamp_utc":"2026-07-03T13:15:00Z","event_id":"evt_010","account_id":"acct_cinder","user_id":"user_cinder","session_id":"session_cinder_1","event_name":"account_signed_up","feature":"onboarding","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-03T13:35:00Z","event_id":"evt_011","account_id":"acct_cinder","user_id":"user_cinder","session_id":"session_cinder_1","event_name":"integration_connected","feature":"integration","status":"error","release":"2026.07.1"},{"timestamp_utc":"2026-07-05T10:10:00Z","event_id":"evt_012","account_id":"acct_cinder","user_id":"user_cinder","session_id":"session_cinder_2","event_name":"integration_connected","feature":"integration","status":"success","release":"2026.07.2"},{"timestamp_utc":"2026-07-05T10:42:00Z","event_id":"evt_013","account_id":"acct_cinder","user_id":"user_cinder","session_id":"session_cinder_2","event_name":"first_query_completed","feature":"sql","status":"success","release":"2026.07.2"},{"timestamp_utc":"2026-07-04T08:45:00Z","event_id":"evt_014","account_id":"acct_delta","user_id":"user_delta","session_id":"session_delta_1","event_name":"account_signed_up","feature":"onboarding","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-04T09:08:00Z","event_id":"evt_015","account_id":"acct_delta","user_id":"user_delta","session_id":"session_delta_1","event_name":"integration_connected","feature":"integration","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-04T09:35:00Z","event_id":"evt_016","account_id":"acct_delta","user_id":"user_delta","session_id":"session_delta_1","event_name":"first_query_completed","feature":"sql","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-04T10:05:00Z","event_id":"evt_017","account_id":"acct_delta","user_id":"user_delta","session_id":"session_delta_1","event_name":"dashboard_created","feature":"dashboards","status":"success","release":"2026.07.1"},{"timestamp_utc":"2026-07-12T14:25:00Z","event_id":"evt_018","account_id":"acct_delta","user_id":"user_delta","session_id":"session_delta_2","event_name":"feature_used","feature":"ai_query","status":"success","release":"2026.07.2"},{"timestamp_utc":"2026-07-05T16:20:00Z","event_id":"evt_019","account_id":"acct_ember","user_id":"user_ember","session_id":"session_ember_1","event_name":"account_signed_up","feature":"onboarding","status":"success","release":"2026.07.2"},{"timestamp_utc":"2026-07-06T11:10:00Z","event_id":"evt_020","account_id":"acct_fjord","user_id":"user_fjord","session_id":"session_fjord_1","event_name":"account_signed_up","feature":"onboarding","status":"success","release":"2026.07.2"},{"timestamp_utc":"2026-07-06T11:50:00Z","event_id":"evt_021","account_id":"acct_fjord","user_id":"user_fjord","session_id":"session_fjord_1","event_name":"integration_connected","feature":"integration","status":"success","release":"2026.07.2"}]},{"name":"api_requests","description":"Completed API request events with stable route, release, latency, and customer context.","grain":"One completed API request.","joinKeys":["account_id","request_id"],"schema":[{"name":"timestamp_utc","type":"Timestamp","description":"When the request completed."},{"name":"request_id","type":"Utf8","description":"Stable request correlation identifier."},{"name":"account_id","type":"Utf8","description":"Joins the request to the synthetic account."},{"name":"route_template","type":"Utf8","description":"Bounded route shape without raw identifiers."},{"name":"status_code","type":"Int64","description":"Final HTTP response status."},{"name":"latency_ms","type":"Float64","description":"End-to-end request duration."},{"name":"release","type":"Utf8","description":"Application release serving the request."}],"rows":[{"timestamp_utc":"2026-07-14T08:00:00Z","request_id":"req_001","account_id":"acct_acme","route_template":"/api/reports/export","status_code":200,"latency_ms":820,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:05:00Z","request_id":"req_002","account_id":"acct_acme","route_template":"/api/reports/export","status_code":503,"latency_ms":2200,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:12:00Z","request_id":"req_003","account_id":"acct_acme","route_template":"/api/query","status_code":500,"latency_ms":1450,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:18:00Z","request_id":"req_004","account_id":"acct_beacon","route_template":"/api/query","status_code":502,"latency_ms":1780,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:22:00Z","request_id":"req_005","account_id":"acct_beacon","route_template":"/api/query","status_code":200,"latency_ms":340,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:28:00Z","request_id":"req_006","account_id":"acct_cinder","route_template":"/api/query","status_code":200,"latency_ms":280,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:32:00Z","request_id":"req_007","account_id":"acct_delta","route_template":"/api/query","status_code":500,"latency_ms":1620,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:38:00Z","request_id":"req_008","account_id":"acct_delta","route_template":"/api/dashboards","status_code":503,"latency_ms":1960,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:44:00Z","request_id":"req_009","account_id":"acct_ember","route_template":"/api/integrations","status_code":500,"latency_ms":1100,"release":"2026.07.2"},{"timestamp_utc":"2026-07-14T08:51:00Z","request_id":"req_010","account_id":"acct_fjord","route_template":"/api/integrations","status_code":200,"latency_ms":190,"release":"2026.07.2"}]},{"name":"llm_requests","description":"Normalized provider usage, estimated cost, retry, and reviewed product-outcome fields.","grain":"One completed model request, including provider retries as separate rows.","joinKeys":["account_id","request_id"],"schema":[{"name":"timestamp_utc","type":"Timestamp","description":"When the provider request completed."},{"name":"request_id","type":"Utf8","description":"Stable model request identifier."},{"name":"account_id","type":"Utf8","description":"Joins model usage to the synthetic account."},{"name":"feature","type":"Utf8","description":"Product workflow using the model."},{"name":"provider","type":"Utf8","description":"Normalized model provider."},{"name":"model","type":"Utf8","description":"Provider model identifier captured at request time."},{"name":"input_tokens","type":"Int64","description":"Provider-reported input-token count."},{"name":"output_tokens","type":"Int64","description":"Provider-reported output-token count."},{"name":"estimated_cost_usd","type":"Float64","description":"Estimated request cost under a versioned pricing rule."},{"name":"status","type":"Utf8","description":"Final provider request outcome."},{"name":"retry_count","type":"Int64","description":"Automatic provider retry count for this logical operation."},{"name":"accepted","type":"Boolean","description":"Whether the user accepted or saved the resulting output."}],"rows":[{"timestamp_utc":"2026-07-15T09:00:00Z","request_id":"llm_001","account_id":"acct_acme","feature":"draft_reply","provider":"provider_a","model":"model_fast","input_tokens":2100,"output_tokens":480,"estimated_cost_usd":0.02,"status":"success","retry_count":0,"accepted":true},{"timestamp_utc":"2026-07-15T09:12:00Z","request_id":"llm_002","account_id":"acct_acme","feature":"draft_reply","provider":"provider_a","model":"model_fast","input_tokens":1950,"output_tokens":420,"estimated_cost_usd":0.018,"status":"success","retry_count":1,"accepted":true},{"timestamp_utc":"2026-07-15T09:30:00Z","request_id":"llm_003","account_id":"acct_acme","feature":"summarize","provider":"provider_b","model":"model_balanced","input_tokens":1300,"output_tokens":260,"estimated_cost_usd":0.012,"status":"success","retry_count":0,"accepted":false},{"timestamp_utc":"2026-07-15T10:00:00Z","request_id":"llm_004","account_id":"acct_beacon","feature":"draft_reply","provider":"provider_a","model":"model_fast","input_tokens":1100,"output_tokens":250,"estimated_cost_usd":0.01,"status":"success","retry_count":0,"accepted":true},{"timestamp_utc":"2026-07-15T10:18:00Z","request_id":"llm_005","account_id":"acct_beacon","feature":"summarize","provider":"provider_b","model":"model_balanced","input_tokens":1200,"output_tokens":300,"estimated_cost_usd":0.011,"status":"success","retry_count":0,"accepted":false},{"timestamp_utc":"2026-07-15T11:00:00Z","request_id":"llm_006","account_id":"acct_cinder","feature":"draft_reply","provider":"provider_a","model":"model_fast","input_tokens":650,"output_tokens":90,"estimated_cost_usd":0.005,"status":"success","retry_count":0,"accepted":false},{"timestamp_utc":"2026-07-15T12:00:00Z","request_id":"llm_007","account_id":"acct_delta","feature":"agent_research","provider":"provider_b","model":"model_balanced","input_tokens":2600,"output_tokens":610,"estimated_cost_usd":0.025,"status":"success","retry_count":0,"accepted":true},{"timestamp_utc":"2026-07-15T12:22:00Z","request_id":"llm_008","account_id":"acct_delta","feature":"agent_research","provider":"provider_b","model":"model_balanced","input_tokens":2500,"output_tokens":590,"estimated_cost_usd":0.024,"status":"success","retry_count":0,"accepted":true},{"timestamp_utc":"2026-07-15T12:50:00Z","request_id":"llm_009","account_id":"acct_delta","feature":"agent_research","provider":"provider_c","model":"model_reasoning","input_tokens":3100,"output_tokens":720,"estimated_cost_usd":0.03,"status":"success","retry_count":0,"accepted":true},{"timestamp_utc":"2026-07-15T13:30:00Z","request_id":"llm_010","account_id":"acct_ember","feature":"draft_reply","provider":"provider_a","model":"model_fast","input_tokens":720,"output_tokens":120,"estimated_cost_usd":0.006,"status":"success","retry_count":0,"accepted":false},{"timestamp_utc":"2026-07-15T14:00:00Z","request_id":"llm_011","account_id":"acct_fjord","feature":"summarize","provider":"provider_a","model":"model_fast","input_tokens":500,"output_tokens":80,"estimated_cost_usd":0.004,"status":"success","retry_count":0,"accepted":true}]},{"name":"job_runs","description":"Attempt-level background-job outcomes with queue and execution timing.","grain":"One attempt of a logical background job.","joinKeys":["account_id","job_id"],"schema":[{"name":"timestamp_utc","type":"Timestamp","description":"When the attempt reached a terminal outcome."},{"name":"job_id","type":"Utf8","description":"Logical job identifier shared by retries."},{"name":"account_id","type":"Utf8","description":"Joins job impact to the synthetic account."},{"name":"job_name","type":"Utf8","description":"Bounded worker operation name."},{"name":"status","type":"Utf8","description":"Attempt outcome."},{"name":"attempt","type":"Int64","description":"One-indexed attempt number."},{"name":"queue_wait_ms","type":"Float64","description":"Time waiting before execution."},{"name":"duration_ms","type":"Float64","description":"Worker execution time."},{"name":"error_type","type":"Utf8","description":"Controlled failure category or null on success."}],"rows":[{"timestamp_utc":"2026-07-16T08:00:00Z","job_id":"job_001","account_id":"acct_acme","job_name":"report_export","status":"failed","attempt":1,"queue_wait_ms":4200,"duration_ms":12000,"error_type":"upstream_timeout"},{"timestamp_utc":"2026-07-16T08:08:00Z","job_id":"job_001","account_id":"acct_acme","job_name":"report_export","status":"completed","attempt":2,"queue_wait_ms":1800,"duration_ms":9100,"error_type":null},{"timestamp_utc":"2026-07-16T08:12:00Z","job_id":"job_002","account_id":"acct_beacon","job_name":"billing_sync","status":"completed","attempt":1,"queue_wait_ms":600,"duration_ms":2400,"error_type":null},{"timestamp_utc":"2026-07-16T08:20:00Z","job_id":"job_003","account_id":"acct_cinder","job_name":"integration_backfill","status":"failed","attempt":1,"queue_wait_ms":9800,"duration_ms":15000,"error_type":"provider_unavailable"},{"timestamp_utc":"2026-07-16T08:24:00Z","job_id":"job_004","account_id":"acct_delta","job_name":"report_export","status":"completed","attempt":1,"queue_wait_ms":720,"duration_ms":6800,"error_type":null},{"timestamp_utc":"2026-07-16T08:30:00Z","job_id":"job_005","account_id":"acct_ember","job_name":"integration_backfill","status":"failed","attempt":1,"queue_wait_ms":11300,"duration_ms":13200,"error_type":"provider_unavailable"},{"timestamp_utc":"2026-07-16T08:35:00Z","job_id":"job_006","account_id":"acct_fjord","job_name":"billing_sync","status":"completed","attempt":1,"queue_wait_ms":450,"duration_ms":1700,"error_type":null}]},{"name":"billing_events","description":"Synthetic subscription outcomes for connecting product behavior and reliability to commercial context.","grain":"One completed billing lifecycle event.","joinKeys":["account_id","event_id"],"schema":[{"name":"timestamp_utc","type":"Timestamp","description":"When the billing event completed."},{"name":"event_id","type":"Utf8","description":"Stable provider-event identifier."},{"name":"account_id","type":"Utf8","description":"Joins the event to the synthetic account."},{"name":"event_name","type":"Utf8","description":"Normalized billing lifecycle outcome."},{"name":"amount_usd","type":"Float64","description":"Synthetic normalized amount."},{"name":"status","type":"Utf8","description":"Final billing-event outcome."}],"rows":[{"timestamp_utc":"2026-07-18T09:00:00Z","event_id":"bill_001","account_id":"acct_acme","event_name":"invoice_paid","amount_usd":2400,"status":"success"},{"timestamp_utc":"2026-07-18T09:10:00Z","event_id":"bill_002","account_id":"acct_beacon","event_name":"invoice_paid","amount_usd":1200,"status":"success"},{"timestamp_utc":"2026-07-18T09:20:00Z","event_id":"bill_003","account_id":"acct_cinder","event_name":"payment_failed","amount_usd":299,"status":"error"},{"timestamp_utc":"2026-07-18T09:30:00Z","event_id":"bill_004","account_id":"acct_delta","event_name":"invoice_paid","amount_usd":1800,"status":"success"},{"timestamp_utc":"2026-07-18T09:40:00Z","event_id":"bill_005","account_id":"acct_ember","event_name":"payment_failed","amount_usd":199,"status":"error"}]}],"lessons":[{"slug":"daily-product-activity","title":"Summarize daily product activity","question":"Which milestones are users completing on each day?","description":"Start with one event table, group durable product milestones into UTC days, and keep successful volume separate from all attempts.","track":"Foundations","difficulty":"Beginner","sql":"SELECT\n  CAST(date_trunc('day', timestamp_utc) AS DATE) AS activity_day,\n  COUNT(*) AS events,\n  SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS successful_events,\n  COUNT(DISTINCT account_id) AS active_accounts\nFROM product_events\nGROUP BY CAST(date_trunc('day', timestamp_utc) AS DATE)\nORDER BY activity_day;","result":{"columns":["activity_day","events","successful_events","active_accounts"],"rows":[{"activity_day":"2026-07-01","events":2,"successful_events":2,"active_accounts":1},{"activity_day":"2026-07-02","events":4,"successful_events":4,"active_accounts":2},{"activity_day":"2026-07-03","events":3,"successful_events":2,"active_accounts":2},{"activity_day":"2026-07-04","events":4,"successful_events":4,"active_accounts":1},{"activity_day":"2026-07-05","events":3,"successful_events":3,"active_accounts":2},{"activity_day":"2026-07-06","events":2,"successful_events":2,"active_accounts":1},{"activity_day":"2026-07-08","events":1,"successful_events":1,"active_accounts":1},{"activity_day":"2026-07-09","events":1,"successful_events":1,"active_accounts":1},{"activity_day":"2026-07-12","events":1,"successful_events":1,"active_accounts":1}]},"visualization":{"title":"Daily successful product milestones","labelKey":"activity_day","valueKey":"successful_events"},"explanation":["The UTC day is derived from the event timestamp instead of a client-supplied date label.","Event volume and distinct active accounts answer different questions, so both remain visible.","The status condition prevents a failed integration attempt from being counted as a completed milestone."],"decisions":["Decide whether retries and repeated milestones should remain visible.","Exclude internal, test, or bot accounts before treating this as adoption.","Use complete time buckets when comparing recent days."],"relatedPaths":[{"label":"SQL time bucketing","path":"/docs/discussion-topics/sql-time-bucketing"},{"label":"Conditional aggregation","path":"/docs/discussion-topics/sql-conditional-aggregation"}]},{"slug":"account-activation-funnel","title":"Build an account activation funnel","question":"How many signed-up accounts connect data, run a first query, and create a dashboard?","description":"Join the account cohort to ordered product milestones so the denominator includes every eligible account, including those that never progress.","track":"Product analytics","difficulty":"Intermediate","sql":"WITH milestones AS (\n  SELECT\n    a.account_id,\n    MIN(CASE\n      WHEN p.event_name = 'account_signed_up' AND p.status = 'success'\n      THEN p.timestamp_utc\n    END) AS signed_up_at,\n    MIN(CASE\n      WHEN p.event_name = 'integration_connected' AND p.status = 'success'\n      THEN p.timestamp_utc\n    END) AS connected_at,\n    MIN(CASE\n      WHEN p.event_name = 'first_query_completed' AND p.status = 'success'\n      THEN p.timestamp_utc\n    END) AS first_query_at,\n    MIN(CASE\n      WHEN p.event_name = 'dashboard_created' AND p.status = 'success'\n      THEN p.timestamp_utc\n    END) AS dashboard_at\n  FROM accounts AS a\n  LEFT JOIN product_events AS p ON p.account_id = a.account_id\n  GROUP BY a.account_id\n),\nstages AS (\n  SELECT 1 AS step, 'Signed up' AS stage, COUNT(*) AS accounts\n  FROM milestones\n  WHERE signed_up_at IS NOT NULL\n  UNION ALL\n  SELECT 2, 'Connected data', COUNT(*)\n  FROM milestones\n  WHERE connected_at >= signed_up_at\n  UNION ALL\n  SELECT 3, 'Ran first query', COUNT(*)\n  FROM milestones\n  WHERE first_query_at >= connected_at\n  UNION ALL\n  SELECT 4, 'Created dashboard', COUNT(*)\n  FROM milestones\n  WHERE dashboard_at >= first_query_at\n)\nSELECT\n  stage,\n  accounts,\n  ROUND(100.0 * accounts / MAX(accounts) OVER (), 1) AS conversion_pct\nFROM stages\nORDER BY step;","result":{"columns":["stage","accounts","conversion_pct"],"rows":[{"stage":"Signed up","accounts":6,"conversion_pct":100},{"stage":"Connected data","accounts":5,"conversion_pct":83.3},{"stage":"Ran first query","accounts":4,"conversion_pct":66.7},{"stage":"Created dashboard","accounts":3,"conversion_pct":50}]},"visualization":{"title":"Signup-to-dashboard activation funnel","labelKey":"stage","valueKey":"conversion_pct","suffix":"%"},"explanation":["The account table establishes the cohort independently from product-event volume.","MIN reduces repeated attempts to the first successful milestone for each account.","Ordering conditions stop an out-of-sequence event from incorrectly advancing an account."],"decisions":["Choose the account, user, or workspace as the funnel unit before writing SQL.","Set a cohort window and allow every account the same activation opportunity.","Document whether a later retry can satisfy a failed milestone."],"relatedPaths":[{"label":"Activation SQL recipe","path":"/sql/signup-activation-funnel"},{"label":"SQL funnel analysis","path":"/docs/discussion-topics/sql-funnel-analysis"},{"label":"Retention use case","path":"/for/product-analytics-retention"}]},{"slug":"llm-unit-economics","title":"Calculate LLM cost per accepted output","question":"Which plans consume the most model spend, and how much does each accepted output cost?","description":"Join normalized provider usage to account context, then compare raw request cost with a reviewed product outcome.","track":"AI economics","difficulty":"Intermediate","sql":"SELECT\n  a.plan,\n  COUNT(*) AS requests,\n  SUM(r.retry_count) AS automatic_retries,\n  ROUND(SUM(r.estimated_cost_usd), 4) AS estimated_cost_usd,\n  SUM(CASE WHEN r.accepted THEN 1 ELSE 0 END) AS accepted_outputs,\n  ROUND(\n    SUM(r.estimated_cost_usd)\n      / NULLIF(SUM(CASE WHEN r.accepted THEN 1 ELSE 0 END), 0),\n    4\n  ) AS cost_per_accepted_output_usd\nFROM llm_requests AS r\nJOIN accounts AS a ON a.account_id = r.account_id\nWHERE r.status = 'success'\nGROUP BY a.plan\nORDER BY estimated_cost_usd DESC;","result":{"columns":["plan","requests","automatic_retries","estimated_cost_usd","accepted_outputs","cost_per_accepted_output_usd"],"rows":[{"plan":"growth","requests":6,"automatic_retries":1,"estimated_cost_usd":0.129,"accepted_outputs":5,"cost_per_accepted_output_usd":0.0258},{"plan":"business","requests":2,"automatic_retries":0,"estimated_cost_usd":0.021,"accepted_outputs":1,"cost_per_accepted_output_usd":0.021},{"plan":"starter","requests":2,"automatic_retries":0,"estimated_cost_usd":0.011,"accepted_outputs":0,"cost_per_accepted_output_usd":null},{"plan":"free","requests":1,"automatic_retries":0,"estimated_cost_usd":0.004,"accepted_outputs":1,"cost_per_accepted_output_usd":0.004}]},"visualization":{"title":"Estimated LLM cost by plan","labelKey":"plan","valueKey":"estimated_cost_usd","suffix":" USD"},"explanation":["Provider-specific usage is normalized before the query, preserving a stable analysis contract.","Acceptance is a product outcome, not a property of the provider response itself.","NULLIF leaves cost per accepted output undefined when a segment has no accepted outputs."],"decisions":["Keep current model pricing in versioned configuration and retain the pricing version on each event.","Separate automatic retries from deliberate user regenerations.","Use invoices as billing truth; the event field is an analytical estimate."],"relatedPaths":[{"label":"OpenAI cost attribution","path":"/for/openai-cost-tracking"},{"label":"LLM cost recipe","path":"/sql/llm-cost-by-feature"},{"label":"Accepted output per dollar","path":"/sql/accepted-ai-output-per-dollar"}]},{"slug":"incident-customer-impact","title":"Connect API failures to customer impact","question":"Which plans and recurring revenue were exposed to API failures during the incident?","description":"Reduce request failures to one row per account before joining commercial context, preventing high-volume customers from being counted repeatedly.","track":"Reliability","difficulty":"Advanced","sql":"WITH account_errors AS (\n  SELECT\n    account_id,\n    SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors\n  FROM api_requests\n  GROUP BY account_id\n)\nSELECT\n  a.plan,\n  COUNT(*) AS accounts,\n  SUM(CASE WHEN COALESCE(e.errors, 0) > 0 THEN 1 ELSE 0 END) AS impacted_accounts,\n  ROUND(\n    100.0 * SUM(CASE WHEN COALESCE(e.errors, 0) > 0 THEN 1 ELSE 0 END)\n      / NULLIF(COUNT(*), 0),\n    1\n  ) AS impacted_pct,\n  SUM(CASE\n    WHEN COALESCE(e.errors, 0) > 0 THEN a.monthly_revenue_usd\n    ELSE 0\n  END) AS mrr_exposed_usd\nFROM accounts AS a\nLEFT JOIN account_errors AS e ON e.account_id = a.account_id\nGROUP BY a.plan\nORDER BY mrr_exposed_usd DESC;","result":{"columns":["plan","accounts","impacted_accounts","impacted_pct","mrr_exposed_usd"],"rows":[{"plan":"growth","accounts":2,"impacted_accounts":2,"impacted_pct":100,"mrr_exposed_usd":4200},{"plan":"business","accounts":1,"impacted_accounts":1,"impacted_pct":100,"mrr_exposed_usd":1200},{"plan":"starter","accounts":2,"impacted_accounts":1,"impacted_pct":50,"mrr_exposed_usd":199},{"plan":"free","accounts":1,"impacted_accounts":0,"impacted_pct":0,"mrr_exposed_usd":0}]},"visualization":{"title":"Recurring revenue exposed to API failures","labelKey":"plan","valueKey":"mrr_exposed_usd","suffix":" USD"},"explanation":["Request rows are reduced to one account-level impact result before the commercial join.","The left join preserves accounts with no errors so the impacted percentage has the correct denominator.","Exposed MRR describes incident scope; it does not claim that revenue was lost."],"decisions":["Define the incident window and affected routes before calculating account impact.","Use privacy-approved identifiers and restrict access to commercial dimensions.","Keep exposed, at-risk, refunded, and actually lost revenue as different measures."],"relatedPaths":[{"label":"Customer impact recipe","path":"/sql/incident-customer-impact-by-plan"},{"label":"Incident response guide","path":"/docs/guides/incident-response-with-sql"},{"label":"API reliability use case","path":"/for/api-reliability-monitoring"}]},{"slug":"job-recovery-by-plan","title":"Measure job recovery by customer plan","question":"Which failed jobs recovered on retry, and which accounts still need intervention?","description":"Collapse attempt-level worker events into one logical job before comparing recovery and unresolved failures by plan.","track":"Reliability","difficulty":"Advanced","sql":"WITH logical_jobs AS (\n  SELECT\n    job_id,\n    account_id,\n    MAX(attempt) AS attempts,\n    MAX(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS had_failure,\n    MAX(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed\n  FROM job_runs\n  GROUP BY job_id, account_id\n)\nSELECT\n  a.plan,\n  COUNT(*) AS logical_jobs,\n  SUM(had_failure) AS jobs_with_failure,\n  SUM(CASE WHEN had_failure = 1 AND completed = 1 THEN 1 ELSE 0 END)\n    AS recovered_jobs,\n  SUM(CASE WHEN had_failure = 1 AND completed = 0 THEN 1 ELSE 0 END)\n    AS unresolved_jobs\nFROM logical_jobs AS j\nJOIN accounts AS a ON a.account_id = j.account_id\nGROUP BY a.plan\nORDER BY unresolved_jobs DESC, jobs_with_failure DESC, a.plan;","result":{"columns":["plan","logical_jobs","jobs_with_failure","recovered_jobs","unresolved_jobs"],"rows":[{"plan":"starter","logical_jobs":2,"jobs_with_failure":2,"recovered_jobs":0,"unresolved_jobs":2},{"plan":"growth","logical_jobs":2,"jobs_with_failure":1,"recovered_jobs":1,"unresolved_jobs":0},{"plan":"business","logical_jobs":1,"jobs_with_failure":0,"recovered_jobs":0,"unresolved_jobs":0},{"plan":"free","logical_jobs":1,"jobs_with_failure":0,"recovered_jobs":0,"unresolved_jobs":0}]},"visualization":{"title":"Unresolved logical jobs by plan","labelKey":"plan","valueKey":"unresolved_jobs"},"explanation":["Attempts are grouped by logical job identifier before failure and recovery are counted.","A job may have both a failed attempt and a completed retry, which is recovery rather than permanent failure.","Joining after the reduction prevents a retried job from multiplying account-level counts."],"decisions":["Define terminal job statuses and the maximum expected retry delay.","Distinguish automatic retry recovery from manual replay.","Alert on unresolved work and age, not every transient failed attempt."],"relatedPaths":[{"label":"Job retry-rate recipe","path":"/sql/background-job-retry-rate"},{"label":"Stalled jobs recipe","path":"/sql/find-stalled-background-jobs"},{"label":"Background-job use case","path":"/for/background-job-monitoring"}]}]}