Measuring Active Users with Clean Insights

Daily Active Users (DAUs), Weekly Active Users (WAUs), and Monthly Active Users (WAUs)

Clean Insights has features built in to make measuring DAUs (Daily Active Users), WAUs (Weekly Active Users), and MAUs (Monthly Active Users) easy. Here, we’ll use the JS SDK to count them for a web application.

What are DAUs, WAUs, and MAUs?

They’re the count of how many unique people accessed your app during a given day, week or month. For example, if you want to know how many unique people used your application in a day, you want to know the number of “Daily Active Users” or DAUs. If you want to know how many users you had in the last 30 days, you’d want to know your “Monthly Active Users”.

Measuring DAUs

To measure DAUs, we set up a campaign as follows:

// Daily Active User measurements
const ci = CleanInsights({
    "server": "http://example.com/ci/cleaninsights.php",
    "siteId": 1,
    "campaigns": {
        "daily_active_users": {
            "start": "2024-01-01T00:00:00-00:00",
            "end": "2024-12-31T23:59:59-00:00",
            "aggregationPeriodLength": 1, // days
            "numberOfPeriods": 365,       // Measure all year
            “onlyRecordOnce”: true
        }
    }
});

// Don’t forget to get and record consent.

const measureActiveUser = () => {
    ci.measureEvent(“activity”, “daily”, “daily_active_users”);
}

measureActiveUser();

This campaign reports once per day because we set the aggregationPeriodLength to 1.

While sometimes, we want to count how many times something happens (say, the number of times a user sends a message in a chat app), sometimes we just want to know if a user did something at all. That’s the case here. If you load the page twice in one day, you’re still only one user who was active on that day. So we use “onlyRecordOnce”: true.

For more information on these configuration options and their potential values, see the Clean Insights JSON Schema spec.

Measuring WAUs

We can’t simply add up the DAUs to get Weekly Active Users (WAUs). If only one person uses our app and they use it every day, we’d see 1 DAU on Monday, 1 DAU on Tuesday and so on. If we added those, we’d get 7, which isn’t right. We really only have 1 WAU.

Clean Insights doesn’t track users uniquely, so you can’t tell just by looking only at DAUs how many WAUs you have. So how do we measure WAUs?

Easy! We aggregate over 7 day periods instead of 1 day periods. Since our daily_active_users campaign is already set with "aggregationPeriodLength": 1, we’ll just need a new campaign.

// Daily and Weekly Active User measurements
const ci = CleanInsights({
    "server": "http://example.com/ci/cleaninsights.php",
    "siteId": 1,
    "campaigns": {
        "daily_active_users": {
            "start": "2024-01-01T00:00:00-00:00",
            "end": "2024-12-31T23:59:59-00:00",
            "aggregationPeriodLength": 1, // days
            "numberOfPeriods": 365,       // Measure all year
            “onlyRecordOnce”: true
        },
        "weekly_active_users": {
            "start": "2024-01-01T00:00:00-00:00",
            "end": "2024-12-31T23:59:59-00:00",
            "aggregationPeriodLength": 7, // days
            "numberOfPeriods": 365,       // Measure all year
            “onlyRecordOnce”: true
        }
    }
});

// Don’t forget to get and record consent.

const measureActiveUser = () => {
    ci.measureEvent(“activity”, “daily”, “daily_active_users”);
    ci.measureEvent(“activity”, “weekly”, “weekly_active_users”);
}

measureActiveUser();

You can probably guess how to do Monthly Active Users. Simply set up a third campaign with an aggregation period length of 30 days.

// Daily, Weekly, and Monthly Active User measurements
const ci = CleanInsights({
    "server": "http://example.com/ci/cleaninsights.php",
    "siteId": 1,
    "campaigns": {
        "daily_active_users": {
            "start": "2024-01-01T00:00:00-00:00",
            "end": "2024-12-31T23:59:59-00:00",
            "aggregationPeriodLength": 1, // days
            "numberOfPeriods": 365,       // Measure all year
            “onlyRecordOnce”: true
        },
        "weekly_active_users": {
            "start": "2024-01-01T00:00:00-00:00",
            "end": "2024-12-31T23:59:59-00:00",
            "aggregationPeriodLength": 7, // days
            "numberOfPeriods": 53,       // Measure all year
            “onlyRecordOnce”: true
        },
        "monthly_active_users": {
            "start": "2024-01-01T00:00:00-00:00",
            "end": "2024-12-31T23:59:59-00:00",
            "aggregationPeriodLength": 30,// days
            "numberOfPeriods": 12,       // Measure all year
            “onlyRecordOnce”: true
        }
    }
});

// Don’t forget to get and record consent.

const measureActiveUser = () => {
    ci.measureEvent(“activity”, “daily”, “daily_active_users”);
    ci.measureEvent(“activity”, “weekly”, “weekly_active_users”);
    ci.measureEvent(“activity”, “monthly”, “monthly_active_users”);
}

measureActiveUser();

All of these aggregation periods begin from the start. So if you want to have your weeks start on Sunday, pick a Sunday as the starting day.

What is a month, anyways?

Of course, 30 days doesn’t always align with the Julian calendar month, so you’ll eventually see a drift from the calendar month start. The reason we do that is so that each month is the same length and can be directly compared. If you really want to compare apples to apples, use 28 day months so they include the same number of weekdays and weekends in each period.

Remember to consider the right consent model for your use case and your users. In a case like this where all 3 campaigns are similar, grouping consent into one user action and recording it three times in the app probably makes life simpler for everyone.

const grantAll() = () => {
    grantCampaign(“daily_active_users”);
    grantCampaign(“weekly_active_users”);
    grantCampaign(“monthly_active_users”);
}

Clean Insights + Matomo Setup Guide
Specification and Design

Related Docs