GoWindGoWind
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
  • Introduction

    • GoWind UBA Product Introduction
  • Architecture Reference

    • UBA System Architecture
    • UBA Backend Module Overview
    • UBA Backend API Contract
    • UBA Frontend Architecture
  • Developer Guide

    • UBA Installation Guide
    • UBA Code Generation Pipeline Tutorial
    • Adding an External Service Tutorial
    • Adding a Business Entity Tutorial
    • Adding a Frontend Page Tutorial
  • Operations Guide

    • UBA Docker Deployment Guide
    • UBA Configuration Reference & Security Checklist
    • UBA PM2 Deployment Guide
    • UBA Superset BI Deployment Guide
  • Analyst Guide

    • Data Analyst Getting Started Guide
    • Basic Aggregation

      • Event Trend Analysis
      • Active Users Analysis
      • Group By Aggregation
    • Conversion & Paths

      • Funnel Analysis
      • Retention Analysis
      • Top Conversion Paths
      • Behavior Sequence Analysis
    • User Depth

      • Attribution Analysis
      • Distribution Analysis
      • User Segmentation
      • Click Heatmap
      • Interval Analysis
    • Lifecycle

      • User Lifecycle
      • Churn & Reactivation Analysis
      • New vs Returning Users
      • Matrix Quadrant Analysis
    • Revenue & Value

      • Revenue Analysis
      • Whale Tier (Payer Segmentation)
      • Historical LTV Analysis
    • Sessions & Anomalies

      • Session Analysis
      • Period-over-Period Comparison and Anomaly Detection
    • Gaming

      • Level Analysis (Game)
      • Server Retention (Game)
      • Online Stats Analysis (Game)
      • Economy Analysis (Game)
    • OLAP Cookbook
  • SDK Integration

    • Web SDK Integration Guide
    • C# SDK Integration Guide (Unity / Godot / .NET)
  • Appendix

    • UBA Appendix: Ports, Glossary, Known Limitations & FAQ

Retention Analysis

Retention Analysis measures whether users return on day N (week/month) after first performing a behavior, making it the core model for evaluating product stickiness and the user lifecycle. It corresponds to the backend AnalyticsService.Retention.


1. What Questions It Answers

  • What are the day-1, day-7, and day-30 retention rates of users who signed up on June 1?
  • How does retention differ across acquisition channels?
  • Should retention be computed from the "register" event or from "activity"?

2. How Retention Works: the Cohort Matrix

Retention is computed per cohort: users who first performed the target behavior on a given day (or week/month) form a cohort, then we count how many of them return on each subsequent day N and the corresponding ratio.

           Day0   Day1   Day2  ...  Day7
Jun 1 cohort  1000   420    310       180     ← each column = returning users on day N
Jun 2 cohort  950    390    280       160
...
Retention (%)  100%   42%    31%       18%
  • cohort size: number of users in the cohort on its first day.
  • cell.rate: day-N return rate = day-N returning users / cohort size.

3. Backend API

gRPC: AnalyticsService.Retention

FieldTypeDescription
time_rangeTimeRangeTime range for selecting cohorts
app_iduint32 (optional)Filter by app
retention_typeenum (optional)ACTIVE (default, by activity) / EVENT (by a specified event)
event_namestring (optional)Event name when retention_type=EVENT
max_offset_daysint32 (optional)Maximum lookback days, default 7

Response RetentionResponse: cohorts[] (each RetentionCohort contains cohort_date / size / cells[], cell contains offset_days / count / rate), offset_days (all offset columns).

HTTP (admin proxy)

POST /admin/v1/analytics/retention
Content-Type: application/json

{
  "timeRange": { "startMs": 1717200000000, "endMs": 1719791999000 },
  "retentionType": "RETENTION_TYPE_EVENT",
  "eventName": "register",
  "maxOffsetDays": 7
}

4. Underlying SQL

Step by step

  1. Build cohorts: within time_range, take the set of users who first performed the target behavior each day, yielding cohort_date and size.
  2. Count returns: for each cohort's users, check whether there are event records on cohort_date + offset_days.
  3. Compute retention rate: rate = count / size.

Doris example (7-day retention by the register event)

-- Cohort: users who registered each day
WITH cohorts AS (
    SELECT user_id, DATE(event_time) AS cohort_date
    FROM events_fact
    WHERE event_name = 'register'
      AND event_time BETWEEN :start AND :end
    GROUP BY user_id, cohort_date
)
-- Returns: each cohort's activity on subsequent day N
SELECT
    c.cohort_date,
    DATEDIFF(DATE(e.event_time), c.cohort_date) AS offset_days,
    count(DISTINCT c.user_id) AS retained
FROM cohorts c
JOIN events_fact e ON e.user_id = c.user_id
WHERE DATEDIFF(DATE(e.event_time), c.cohort_date) BETWEEN 0 AND 7
GROUP BY c.cohort_date, offset_days;

The backend implementation actually builds cohorts by the date of event_ts and then does count(DISTINCT user_id) per offset — logically equivalent. See app/core/service/internal/data/doris/analytics_repo.go for details.


5. Choosing a Retention Type

TypeFieldUse Case
ACTIVE (default)No event_name neededMeasures "is the user still active" — any event on the day counts as retained. For overall stickiness.
EVENTRequires event_nameMeasures "does the user repeat a specific action" — e.g. "do they purchase again on day N after registering". For feature repeat usage.
  • New-user retention usually uses ACTIVE (cohort = registration day).
  • Feature retention uses EVENT (e.g. repeat-purchase retention).

6. Typical Question Examples

Q1: Next-day / 7-day retention of June's new users

retention_type=ACTIVE, time_range spanning all of June, max_offset_days=7. The Day1 column of the result matrix is next-day retention; the Day7 column is 7-day retention.

Q2: Repeat-purchase retention of paying users

retention_type=EVENT, event_name=purchase, max_offset_days=30. Measures whether users pay again on day N after their first payment.

Q3: Comparing retention across channels

The Retention API does not directly support grouping by channel. To compare channels, write SQL in Superset and build cohorts grouped by register_channel:

WITH cohorts AS (
    SELECT u.user_id, u.register_channel, DATE(u.register_time) AS cohort_date
    FROM users_dim u
    WHERE u.register_time BETWEEN :start AND :end
)
SELECT c.register_channel, DATEDIFF(DATE(e.event_time), c.cohort_date) AS offset_days,
       count(DISTINCT c.user_id) AS retained
FROM cohorts c
JOIN events_fact e ON e.user_id = c.user_id
WHERE DATEDIFF(DATE(e.event_time), c.cohort_date) BETWEEN 0 AND 7
GROUP BY c.register_channel, offset_days;

7. Notes and Caveats

  • max_offset defaults to 7: to see 30-day retention, explicitly pass max_offset_days=30.
  • Time range must be long enough: to see day-N retention, the end of time_range should reach at least "last cohort + N days", otherwise later columns will be missing data.
  • Empty data: retention depends on return-visit events being stored; if returns are missing, check whether the OLAP engine's Kafka consumption job is running (see Getting Started · Current State of Data Storage).

8. Related Documents

  • Data Analyst Getting Started Guide
  • Event Trend Analysis
  • Funnel Analysis
  • OLAP Cookbook
  • Backend API Contract
Edit this page
Last Updated:: 11/3/26, 2:14 PM
Contributors: Bobo
Prev
Funnel Analysis
Next
Top Conversion Paths