Totals, unique users and counting traps
Why the same week of data gives different numbers of 'active users', and how to count them right.
Lesson 2 of 32~22 min of learningIncludes ~13 min for questions and tasks
Contents1 of 39 steps
Maya
You
Alex Tutor
Alex Tutor
Dataset · 147 rows
Halves event log, 1–7 June (147 rows)
Every event from last week, in time order. Times are UTC.
- Columns
- event_time
- When it happened, in UTC
- user_id
- Who: the Halves account
- event
- What happened: app_opened, expense_added or settle_up_recorded
- platform
- Where the event was logged: ios, android or server
- entry_method
- expense_added only: manual, receipt_scan or recurring (created by the server)
- amount_usd
- Amount in US dollars, for expenses and settle-ups
- settlement_id
- settle_up_recorded only: which settlement the row belongs to
Data
| event_time | user_id | event | platform | entry_method | amount_usd | settlement_id |
|---|---|---|---|---|---|---|
| 2026-06-01T06:00:00Z | u001 | expense_added | server | recurring | 420 | |
| 2026-06-01T06:00:00Z | u005 | expense_added | server | recurring | 420 | |
| 2026-06-01T06:00:00Z | u015 | expense_added | server | recurring | 55 | |
| 2026-06-01T06:01:00Z | u001 | expense_added | server | recurring | 38 | |
| 2026-06-01T06:01:00Z | u015 | expense_added | server | recurring | 650 |
Show 142 more rows
| 2026-06-01T06:41:00Z | u008 | app_opened | ios | |||
| 2026-06-01T06:44:00Z | u007 | app_opened | ios | |||
| 2026-06-01T06:46:00Z | u007 | expense_added | ios | receipt_scan | 116 | |
| 2026-06-01T07:29:00Z | u019 | app_opened | ios | |||
| 2026-06-01T07:30:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-01T07:38:00Z | u002 | app_opened | android | |||
| 2026-06-01T07:39:00Z | u002 | expense_added | android | manual | 1 | |
| 2026-06-01T09:39:00Z | u002 | app_opened | android | |||
| 2026-06-01T09:40:00Z | u002 | expense_added | android | receipt_scan | 1 | |
| 2026-06-01T09:43:00Z | u019 | app_opened | ios | |||
| 2026-06-01T09:44:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-01T15:32:00Z | u008 | app_opened | ios | |||
| 2026-06-01T16:36:00Z | u020 | app_opened | android | |||
| 2026-06-01T16:38:00Z | u020 | expense_added | android | manual | 35 | |
| 2026-06-01T22:09:00Z | u009 | app_opened | ios | |||
| 2026-06-01T22:11:00Z | u009 | expense_added | ios | manual | 19 | |
| 2026-06-02T02:39:00Z | u018 | app_opened | ios | |||
| 2026-06-02T07:11:00Z | u002 | app_opened | android | |||
| 2026-06-02T07:12:00Z | u002 | expense_added | android | manual | 1 | |
| 2026-06-02T07:25:00Z | u019 | app_opened | ios | |||
| 2026-06-02T07:26:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-02T08:31:00Z | u016 | app_opened | ios | |||
| 2026-06-02T09:44:00Z | u019 | app_opened | ios | |||
| 2026-06-02T09:45:00Z | u019 | expense_added | ios | receipt_scan | 1 | |
| 2026-06-02T09:46:00Z | u002 | app_opened | android | |||
| 2026-06-02T09:47:00Z | u002 | expense_added | android | manual | 1 | |
| 2026-06-02T15:05:00Z | u018 | app_opened | ios | |||
| 2026-06-02T16:07:00Z | u014 | app_opened | ios | |||
| 2026-06-02T16:09:00Z | u014 | expense_added | ios | manual | 31 | |
| 2026-06-02T16:49:00Z | u004 | app_opened | ios | |||
| 2026-06-02T16:51:00Z | u004 | expense_added | ios | manual | 34 | |
| 2026-06-02T18:49:00Z | u014 | app_opened | ios | |||
| 2026-06-02T19:11:00Z | u004 | app_opened | ios | |||
| 2026-06-02T19:13:00Z | u004 | expense_added | ios | manual | 69 | |
| 2026-06-02T20:50:00Z | u020 | app_opened | android | |||
| 2026-06-02T23:10:00Z | u012 | app_opened | android | |||
| 2026-06-02T23:13:00Z | u012 | expense_added | android | manual | 19 | |
| 2026-06-02T23:14:00Z | u010 | app_opened | android | |||
| 2026-06-02T23:16:00Z | u010 | expense_added | android | receipt_scan | 8 | |
| 2026-06-03T02:30:00Z | u011 | app_opened | ios | |||
| 2026-06-03T02:33:00Z | u011 | expense_added | ios | manual | 89 | |
| 2026-06-03T07:14:00Z | u002 | app_opened | android | |||
| 2026-06-03T07:15:00Z | u002 | expense_added | android | manual | 1 | |
| 2026-06-03T07:53:00Z | u019 | app_opened | ios | |||
| 2026-06-03T07:54:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-03T09:19:00Z | u002 | app_opened | android | |||
| 2026-06-03T09:20:00Z | u002 | expense_added | android | manual | 1 | |
| 2026-06-03T09:37:00Z | u019 | app_opened | ios | |||
| 2026-06-03T09:38:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-03T10:02:00Z | u004 | app_opened | ios | |||
| 2026-06-03T10:04:00Z | u004 | expense_added | ios | manual | 105 | |
| 2026-06-03T10:07:00Z | u004 | settle_up_recorded | ios | 152 | s002 | |
| 2026-06-03T15:46:00Z | u018 | app_opened | ios | |||
| 2026-06-03T15:48:00Z | u018 | expense_added | ios | manual | 66 | |
| 2026-06-03T16:39:00Z | u021 | app_opened | ios | |||
| 2026-06-04T01:40:00Z | u017 | app_opened | ios | |||
| 2026-06-04T01:43:00Z | u017 | expense_added | ios | manual | 59 | |
| 2026-06-04T02:31:00Z | u008 | app_opened | ios | |||
| 2026-06-04T02:33:00Z | u008 | expense_added | ios | manual | 49 | |
| 2026-06-04T07:08:00Z | u019 | app_opened | ios | |||
| 2026-06-04T07:09:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-04T07:35:00Z | u002 | app_opened | android | |||
| 2026-06-04T07:36:00Z | u002 | expense_added | android | receipt_scan | 1 | |
| 2026-06-04T09:03:00Z | u002 | app_opened | android | |||
| 2026-06-04T09:04:00Z | u002 | expense_added | android | receipt_scan | 1 | |
| 2026-06-04T09:24:00Z | u019 | app_opened | ios | |||
| 2026-06-04T09:25:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-04T10:35:00Z | u020 | app_opened | android | |||
| 2026-06-04T12:22:00Z | u013 | app_opened | ios | |||
| 2026-06-04T12:27:00Z | u013 | settle_up_recorded | ios | 185 | s004 | |
| 2026-06-04T18:10:00Z | u020 | app_opened | android | |||
| 2026-06-04T18:12:00Z | u020 | expense_added | android | manual | 91 | |
| 2026-06-04T18:15:00Z | u020 | settle_up_recorded | android | 67 | s008 | |
| 2026-06-04T21:19:00Z | u013 | app_opened | ios | |||
| 2026-06-04T21:21:00Z | u014 | app_opened | ios | |||
| 2026-06-04T21:22:00Z | u014 | settle_up_recorded | ios | 185 | s004 | |
| 2026-06-04T23:48:00Z | u010 | app_opened | android | |||
| 2026-06-04T23:50:00Z | u010 | expense_added | android | manual | 95 | |
| 2026-06-05T02:13:00Z | u018 | app_opened | ios | |||
| 2026-06-05T02:15:00Z | u018 | expense_added | ios | manual | 36 | |
| 2026-06-05T06:24:00Z | u008 | app_opened | ios | |||
| 2026-06-05T06:26:00Z | u008 | expense_added | ios | manual | 101 | |
| 2026-06-05T07:17:00Z | u019 | app_opened | ios | |||
| 2026-06-05T07:18:00Z | u019 | expense_added | ios | manual | 1 | |
| 2026-06-05T07:21:00Z | u002 | app_opened | android | |||
| 2026-06-05T07:22:00Z | u002 | expense_added | android | receipt_scan | 1 | |
| 2026-06-05T09:11:00Z | u002 | app_opened | android | |||
| 2026-06-05T09:12:00Z | u002 | expense_added | android | manual | 1 | |
| 2026-06-05T09:40:00Z | u019 | app_opened | ios | |||
| 2026-06-05T09:41:00Z | u019 | expense_added | ios | receipt_scan | 1 | |
| 2026-06-05T12:36:00Z | u013 | app_opened | ios | |||
| 2026-06-05T12:37:00Z | u016 | app_opened | ios | |||
| 2026-06-05T12:39:00Z | u016 | expense_added | ios | manual | 40 | |
| 2026-06-05T12:44:00Z | u016 | app_opened | ios | |||
| 2026-06-05T14:27:00Z | u021 | app_opened | ios | |||
| 2026-06-05T14:29:00Z | u021 | expense_added | ios | manual | 11 | |
| 2026-06-05T15:23:00Z | u008 | app_opened | ios | |||
| 2026-06-05T15:25:00Z | u008 | expense_added | ios | receipt_scan | 84 | |
| 2026-06-05T18:05:00Z | u014 | app_opened | ios | |||
| 2026-06-05T18:30:00Z | u014 | app_opened | ios | |||
| 2026-06-05T18:32:00Z | u014 | expense_added | ios | manual | 64 | |
| 2026-06-05T21:03:00Z | u013 | app_opened | ios | |||
| 2026-06-05T21:05:00Z | u013 | expense_added | ios | manual | 17 | |
| 2026-06-06T00:05:00Z | u011 | app_opened | ios | |||
| 2026-06-06T00:08:00Z | u011 | expense_added | ios | manual | 73 | |
| 2026-06-06T05:40:00Z | u012 | app_opened | android | |||
| 2026-06-06T05:43:00Z | u012 | expense_added | android | manual | 21 | |
| 2026-06-06T08:32:00Z | u013 | app_opened | ios | |||
| 2026-06-06T14:21:00Z | u008 | app_opened | ios | |||
| 2026-06-06T14:23:00Z | u008 | expense_added | ios | receipt_scan | 16 | |
| 2026-06-06T16:08:00Z | u006 | app_opened | ios | |||
| 2026-06-06T16:10:00Z | u006 | expense_added | ios | receipt_scan | 41 | |
| 2026-06-06T18:05:00Z | u006 | app_opened | ios | |||
| 2026-06-06T18:07:00Z | u006 | expense_added | ios | receipt_scan | 22 | |
| 2026-06-06T18:10:00Z | u006 | settle_up_recorded | ios | 131 | s003 | |
| 2026-06-06T18:22:00Z | u013 | app_opened | ios | |||
| 2026-06-06T18:24:00Z | u013 | expense_added | ios | manual | 8 | |
| 2026-06-06T18:27:00Z | u013 | settle_up_recorded | ios | 138 | s005 | |
| 2026-06-06T19:01:00Z | u020 | app_opened | android | |||
| 2026-06-06T19:03:00Z | u020 | expense_added | android | manual | 6 | |
| 2026-06-07T02:38:00Z | u018 | app_opened | ios | |||
| 2026-06-07T02:40:00Z | u018 | expense_added | ios | manual | 32 | |
| 2026-06-07T02:43:00Z | u018 | settle_up_recorded | ios | 158 | s007 | |
| 2026-06-07T06:28:00Z | u003 | app_opened | ios | |||
| 2026-06-07T06:37:00Z | u007 | app_opened | ios | |||
| 2026-06-07T06:38:00Z | u007 | settle_up_recorded | ios | 158 | s007 | |
| 2026-06-07T10:04:00Z | u016 | app_opened | ios | |||
| 2026-06-07T10:05:00Z | u016 | settle_up_recorded | ios | 131 | s003 | |
| 2026-06-07T12:50:00Z | u021 | app_opened | ios | |||
| 2026-06-07T12:52:00Z | u021 | expense_added | ios | manual | 51 | |
| 2026-06-07T14:25:00Z | u018 | app_opened | ios | |||
| 2026-06-07T14:27:00Z | u018 | expense_added | ios | manual | 69 | |
| 2026-06-07T18:29:00Z | u003 | app_opened | ios | |||
| 2026-06-07T18:31:00Z | u003 | expense_added | ios | manual | 37 | |
| 2026-06-07T18:34:00Z | u003 | settle_up_recorded | ios | 69 | s001 | |
| 2026-06-07T19:14:00Z | u014 | app_opened | ios | |||
| 2026-06-07T19:16:00Z | u014 | app_opened | ios | |||
| 2026-06-07T19:18:00Z | u014 | expense_added | ios | manual | 15 | |
| 2026-06-07T19:21:00Z | u014 | settle_up_recorded | ios | 110 | s006 | |
| 2026-06-07T20:37:00Z | u022 | app_opened | ios | |||
| 2026-06-07T21:17:00Z | u022 | app_opened | ios | |||
| 2026-06-07T21:19:00Z | u022 | expense_added | ios | manual | 39 |
Alex Tutor
Dataset · 22 rows
Halves users in the log (22 rows)
One row per account that appears in the event log.
- Columns
- user_id
- The Halves account
- signup_date
- Date the account was created
- platform
- The user's phone platform: ios or android
- acquisition_channel
- How the user came to Halves: invite, app_store_search, paid_social, referral_link or staff
- timezone
- The user's home time zone
- is_internal
- true for a team account, false for a customer; not always filled in
Data
| user_id | signup_date | platform | acquisition_channel | timezone | is_internal |
|---|---|---|---|---|---|
| u001 | 2026-04-23 | ios | invite | Europe/Kyiv | false |
| u002 | 2026-02-10 | android | staff | Europe/Kyiv | |
| u003 | 2026-05-10 | ios | paid_social | Europe/Kyiv | false |
| u004 | 2026-05-22 | ios | paid_social | Europe/Kyiv | false |
| u005 | 2026-04-20 | android | app_store_search | Europe/Kyiv | false |
Show 17 more rows
| u006 | 2026-05-16 | ios | invite | Europe/Kyiv | false |
| u007 | 2026-05-08 | ios | referral_link | Asia/Bangkok | false |
| u008 | 2026-05-08 | ios | app_store_search | Asia/Bangkok | false |
| u009 | 2026-05-04 | ios | paid_social | Europe/Lisbon | false |
| u010 | 2026-05-29 | android | invite | America/New_York | false |
| u011 | 2026-05-28 | ios | invite | America/New_York | false |
| u012 | 2026-05-30 | android | invite | Asia/Bangkok | false |
| u013 | 2026-05-11 | ios | paid_social | Europe/Lisbon | false |
| u014 | 2026-05-30 | ios | referral_link | Europe/Kyiv | false |
| u015 | 2026-03-13 | android | invite | Europe/Kyiv | false |
| u016 | 2026-05-14 | ios | paid_social | Europe/Lisbon | false |
| u017 | 2026-06-01 | ios | paid_social | America/New_York | false |
| u018 | 2026-05-27 | ios | app_store_search | Asia/Bangkok | false |
| u019 | 2026-02-10 | ios | staff | Europe/Kyiv | true |
| u020 | 2026-05-06 | android | referral_link | Europe/Kyiv | false |
| u021 | 2026-05-12 | ios | app_store_search | Asia/Bangkok | false |
| u022 | 2026-05-11 | ios | app_store_search | Europe/Lisbon | false |
You
Alex Tutor
Alex Tutor
Question 1
u014 already opened Halves this week. Next week the same person opens it 10 more times than usual. True or false: both the event total and the number of unique users go up.
Alex Tutor
platform = server, entry_method = recurring.Maya
Alex Tutor
Alex Tutor
Question 2
Use the event log. How many unique users opened the app (app_opened) at least once during the week?
Units: users
You
Alex Tutor
Maya
is_internal flag. Filter it out.Alex Tutor
is_internal, because someone forgot to set it. Another column in the users file gives it away.Alex Tutor
Question 3
Now remove every staff account, flagged or not. How many real users opened the app at least once during the week?
Units: users
Theo
expense_added rows. Can I use 60?Alex Tutor
You
recurring rows and both staff accounts, then count rows?Alex Tutor
Alex Tutor
Question 4
Theo needs “expenses added by people last week”. Of the 60 expense_added rows, how many were added by real users in the app, without recurring bills and staff accounts?
Units: expenses
You
settle_up_recorded rows.Alex Tutor
settlement_id.Maya
Alex Tutor
Alex Tutor
Question 5
The log has 11 settle_up_recorded rows. How many settle-ups (payments) do they describe?
Units: settle-ups
Alex Tutor
Alex Tutor
Maya
Alex Tutor
You
Alex Tutor
Question 6Short answer · AI-checked task
Write to Maya in 2–3 sentences: why “22 active users” is wrong for last week and what number should go on the slide instead, with its definition.
Write your answer and get a score with feedback from our AI reviewer.
Log in to get AI feedbackAlex Tutor
Alex Tutor
That’s the lesson. You answered every task — nicely done.