Repository navigation
Releases: naimulnashid/data-usage-tracker
Release list
Data Usage Tracker 3.6.0
The phone app now sends each sync once, and the dashboard's Sync now button can collect a phone's upload from the cloud inbox straight away. This release also adds a project site.
Added
- A project site, live at https://data-usage-tracker-site.vercel.app/: what the project is for, how the Windows and Android collectors work, every chart type drawn live on invented data with a laptop / phone switch, and every feature. Plain HTML, CSS and one script in
site/, dark and light themes. Vercel rebuilds it only whensite/ordocs/screenshots/changes. Shared links unfurl with a preview image. - Light-theme screenshots.
npm run demo:shotscaptures every page in the dark theme and again in the light one, from one demo history, so each pair shows the same numbers.
Changed
- Sync now is on the phone pages too when the cloud inbox is configured. A run empties the inbox, so a phone's upload lands at once instead of at the next scheduled run, and the message counts phone uploads that landed beside the laptop's new rows. Without an inbox the button stays on the laptop's pages.
- A phone's Sync Status page no longer states a sync interval. It said "every 6 hours, on unmetered networks only", which is only the app's default: both are settings on the phone, and the dashboard cannot see them.
Fixed
- Data Usage Reporter 1.5.1 sends each sync once. Pressing Sync now on the phone re-registered the background job, and Android treats a newly registered periodic job as due at once, so a second sync ran beside the button's own, sometimes a third. About a quarter of uploads were such repeats. Nothing was double-counted, since a repeat stores no new rows, but each one was a full extra upload. The job is now re-registered only when its interval or network setting changes, and only one sync runs at a time.
Upgrading
Pull, then npm install and npm run build, and restart the dashboard. The database schema is unchanged.
On each phone, install data-usage-reporter-1.5.1.apk over 1.3 or later; settings, token and sync state are kept. On Xiaomi phones adb install is refused unless Developer options → Install via USB is on, so download the APK on the phone and open it from the file manager instead.
Android app
data-usage-reporter-1.5.1.apk is Data Usage Reporter 1.5.1 (versionCode 8, Android 8.0+), built from this release's android/ source and signed with the project's release key:
CN=Data Usage Tracker
SHA-256 ab:34:f0:77:4f:3d:c5:0b:7e:0d:e7:c0:04:7e:ee:ce:82:01:89:1a:a4:da:37:73:ca:b1:52:19:06:13:4f:a1
File SHA-256: c06cdefa3520ab919059370b2288026c17c81241c9338fc39dc0c3668ac3f679
Data Usage Tracker 3.5.1
The cloud inbox function now serves the sibling Screen Time Tracker too, so one free Supabase project covers both.
Changed
- One inbox function, two mailboxes. Screen Time Tracker's phones post to
/inbox/screen-time; this project's address,/inbox, is unchanged, so phones already set up keep working. Each app has its own tokens and its own uploads, and every query is scoped to the app, so neither project's token can read or delete the other's uploads. npm run inbox -- sqlnow registers each token for its app.
Upgrading
If you set up the cloud inbox with 3.5.0:
- Run
supabase/migrations/20261014120000_inbox_per_app.sqlin the project's SQL editor. Existing uploads and tokens are kept as this app's. - Redeploy the function:
supabase functions deploy inbox --no-verify-jwt.
Without a cloud inbox, there is nothing to do; git pull is enough.
Android app
Unchanged. Use data-usage-reporter-1.5.apk from the 3.5.0 release.
Data Usage Tracker 3.5.0
Phones can now report from any network, even while the PC is off, through an optional encrypted cloud inbox. The Android app also has a redesigned screen.
Added
- A cloud inbox, so a phone can report from anywhere. On its own, the phone posts straight to the dashboard, so it must be on the PC's network, the PC must be on, and the address changes whenever the router hands the PC a new one. With the inbox, the app posts to a fixed
https://address on any network, and the PC collects whatever is waiting when it next runs. It is optional and off unlessinboxis set inconfig/collector.json. - The inbox cannot read what it holds. The app encrypts each upload to a key only the PC has (P-256 ECDH, HKDF-SHA256, AES-256-GCM), with your ingest token mixed into the key derivation, so the inbox cannot forge an upload either. It sees an upload's size, its time and the phone's random device id.
- It runs on Supabase's free tier: one Edge Function and two tables, in
supabase/. Setup is in the README, under Optional: a cloud inbox. In short: deploy the function, setinboxin config, thennpm run inbox -- keygen,drain-tokenandsql. On each phone, at home, press Set up from the dashboard, which fetches the inbox address and the PC's key from the dashboard over your network, never from the inbox. - The hourly collector empties the inbox at the end of each run;
npm run inbox -- draindoes it by hand.
Changed
- Android app 1.5 has a redesigned screen. A status card at the top answers "is it working?": green when synced, amber after three days without a sync, red with the reason when a sync fails. Below it: when the data runs to, where it is sent, the interval Android actually accepted, and the last attempt. The dashboard, cloud inbox, background sync and full resync each get a card. Permissions appear only while one is missing. Turning the inbox off and re-sending everything ask first.
- The phone's Sync Status page marks an upload that came through the inbox with when it reached the database, and lists uploads by when the phone sent them.
Fixed
- The app showed the ingest token in plain text. Every earlier build made the token field single-line after making it a password field, which silently removed the masking. It is masked now, with Show / Hide. If anyone has seen the app's screen, consider changing the token.
Upgrading
Pull, then npm install and npm run build, and restart the dashboard. The database gains one column (android_sync_log.landed_at), added automatically the first time it is written.
On each phone running 1.3 or later, install data-usage-reporter-1.5.apk over it; settings and sync state are kept. On Xiaomi phones adb install is refused unless Developer options → Install via USB is on, so download the APK on the phone and open it from the file manager instead. A phone still on 1.2 has to uninstall it first; see the 3.4.0 notes.
Without an inbox configured, nothing changes: the app keeps posting to the dashboard address.
Android app
data-usage-reporter-1.5.apk is Data Usage Reporter 1.5 (versionCode 7, Android 8.0+), built from this release's android/ source and signed with the project's release key:
CN=Data Usage Tracker
SHA-256 ab:34:f0:77:4f:3d:c5:0b:7e:0d:e7:c0:04:7e:ee:ce:82:01:89:1a:a4:da:37:73:ca:b1:52:19:06:13:4f:a1
Data Usage Tracker 3.4.1
The Android app now catches a mistyped dashboard address before saving it.
Changed
-
Android app 1.4.1 checks the dashboard address before saving it. It used to accept anything:
http:192.168.1.20:7843, with the//forgotten on a phone keyboard, was saved, and every sync then failed without pointing at the address. Save and test, Sync now and Full resync now refuse a malformed address, keep the last working one, and say on the field what is wrong and what it should read. For example: Missing "//" after "http:". It should read http://192.168.1.20:7843.It catches a missing
//or:, nohttp://at all, an unsupported scheme (htttp://,ftp://), a missing, non-numeric or out-of-range port, a path or?queryon the end, auser@part, and spaces. Background syncs check an address saved by an older version the same way and report the problem in the status line. When the connection test fails on an address with no port, the message adds that the dashboard listens on 7843.
Upgrading
The dashboard is unchanged apart from the version number; git pull is enough.
On each phone running 1.3 or 1.4, install data-usage-reporter-1.4.1.apk over it; settings and sync state are kept. On Xiaomi phones adb install is refused unless Developer options → Install via USB is on, so download the APK on the phone and open it from the file manager instead.
A phone still on 1.2 has to uninstall it first, because 1.2 was signed with a different key. It then reports under a new device id; see the 3.4.0 notes for npm run android:merge, which folds the old entry into the new one.
Android app
data-usage-reporter-1.4.1.apk is Data Usage Reporter 1.4.1 (versionCode 6, Android 8.0+), built from this release's android/ source and signed with the project's release key:
CN=Data Usage Tracker
SHA-256 ab:34:f0:77:4f:3d:c5:0b:7e:0d:e7:c0:04:7e:ee:ce:82:01:89:1a:a4:da:37:73:ca:b1:52:19:06:13:4f:a1
Data Usage Tracker 3.4.0
Moving a phone from the 1.2 app to a release-signed build no longer leaves it in the sidebar twice.
Added
npm run android:mergefolds a phone's old history into the id it reports under now. The reporter app's device id lives only on the phone, so uninstalling and reinstalling the app gives it a new one and the dashboard shows the phone twice. That is unavoidable once when moving from the debug-signed 1.2 (from 3.1.1) to 1.3 or later, because Android refuses an update across signing keys. With no arguments it lists the phones, their ids and app versions;--from <old id> --into <new id>shows what would move;--applybacks the database up beside your backup and merges. Where both ids hold the same bucket, the larger reading is kept, as at every sync.
Fixed
npm run android:ssidworks with a release-signed app. It read the phone's device id withrun-as, which Android allows only for a debuggable build, so since 1.3 it stopped at "Could not read the reporter app's device id". It now takes--device <id>, or uses the one phone in the database with the handset's brand and model, and stops and lists them when more than one matches.
Security
next15.5.27, for two cache-poisoning advisories affecting SSG and ISR pages, and through itsharp0.35.5 (librsvg) andsource-map-js1.2.2. Exposure here was small: nothing uses ISR, the only prerendered pages are the login page and the manifest, and image optimisation is off, so sharp never ran.
Upgrading
git pull, npm ci, npm run build, then restart the dashboard.
The Android app is unchanged: use data-usage-reporter-1.4.apk from the 3.3.0 release. If a phone runs 1.2, uninstall it first, install 1.4, enter the address and token again, grant usage access and sync once. Then run npm run android:merge to find the phone's old and new ids and merge them.
If the install still fails after uninstalling ("package conflicts with an existing package"), a copy is left in another profile such as Private Space, Dual Apps or a work profile, or the uninstall kept the app's data. With the phone on USB, adb uninstall com.naimul.datausage removes it for every user.
Data Usage Tracker 3.3.0
The Android app warns you when it stops syncing, and the dashboard restarts itself after a crash.
Added
- Android app 1.4: a notification after 7 days without a successful sync. Android keeps about 90 days of per-app history, so a week loses nothing. The alert is there so a changed dashboard address, a rotated token, revoked usage access, or a phone that never reaches home Wi-Fi is noticed with most of that window left. The check is its own twice-daily job with no network requirement, because the sync job runs only on unmetered networks and so could never report the commonest failure. It repeats at most once a day and clears on the next successful sync. On Android 13+ the app asks for notification permission; the status screen shows "Sync alerts: OFF" when it is denied, and now lists the last successful sync.
npm run firewall(scripts/firewall-private-only.ps1, run once from an Administrator shell) blocks the dashboard's port, 7843, on Public networks. Windows' first prompt for Node.js usually allows Public networks too, so with network access on, a laptop on cafe or hotel Wi-Fi offered the login form, over plain HTTP, to everyone there. It refuses to run while you are on a network marked Public, so a home network still filed as Public is not cut off.stop-dashboard.bat: a double-click off switch for the dashboard. It stops only this project's server on 7843 and leaves collection and the logon task alone.
Changed
- The dashboard restarts itself after a crash, 60 s apart and at most 3 times in 10 minutes;
stop-dashboard.batmarks its stop as wanted first. Every scheduled task also retries 3 times, a minute apart, when it fails to start. start-data-usage-dashboard.bat:FORCE_BUILD=1rebuilds first, and when the port is already in use it says what is most likely holding it and waits, instead of closing at once.
Upgrading
git pull, npm ci, npm run build, then restart the dashboard. To pick up the task retries, re-run scripts\register-task.ps1 and scripts\install-autostart.ps1 from an Administrator PowerShell. To block the port on Public networks, run npm run firewall once from an Administrator shell.
On each phone, install data-usage-reporter-1.4.apk over 1.3 (adb install -r data-usage-reporter-1.4.apk); settings and sync state are kept. Open the app once afterwards, which schedules the new check and, on Android 13+, asks for notification permission.
A phone still on 1.2 cannot install 1.4 over it. 1.2 was debug-signed and Android refuses an update across signing keys, with "App not installed as package conflicts with an existing package". Uninstall it first (if that is still refused, adb uninstall com.naimul.datausage removes copies left in Private Space, Dual Apps or a work profile), install 1.4, set it up again and sync. The reinstalled app reports under a new device id, so the phone appears twice; 3.4.0 adds npm run android:merge to fold the old entry into the new one.
Android app
data-usage-reporter-1.4.apk is Data Usage Reporter 1.4 (versionCode 5, Android 8.0+), built from this release's android/ source and signed with the project's release key:
CN=Data Usage Tracker
SHA-256 ab:34:f0:77:4f:3d:c5:0b:7e:0d:e7:c0:04:7e:ee:ce:82:01:89:1a:a4:da:37:73:ca:b1:52:19:06:13:4f:a1
Data Usage Tracker 3.2.1
The collector's hourly snapshot moves off the system drive.
Correction (2 October 2026). These notes first said this change fixes Fast Startup shutdowns that stall with the fans running. It does not. Measured since, those stalls came from the system SSD writing the hibernation image slowly (11-50 MB/s instead of ~700 MB/s) when its write cache was full, before and after this change alike. If your shutdowns do that, Windows records it as
HiberWriteDurationin the Power-Troubleshooter event at the next start; turning off Fast Startup or freeing space on the system drive is what helps.
Changed
-
The snapshot is off the system drive. The elevated snapshot task kept its ~99 MB copy of the SRUM database, its deployed script and its status file in
%ProgramData%\DataUsageTracker, so every hourly collection wrote and replaced 99 MB onC:, about 2.4 GB a day on the drive Windows runs from.register-task.ps1now deploys toDataUsageTracker-snapshotat the root of your database's drive when that drive is NTFS (-DeployRootpicks another folder), and keeps%ProgramData%\DataUsageTrackerotherwise. The folder is still created admin-only in one step and checked on every run; the collector finds it through the snapshot task, and re-registering removes the old one. YourscratchDirwas already yours to place, and stays whereconfig\collector.jsonputs it.
Fixed
- Light theme: hovered rows, the band behind a hovered bar, and never-collected heat-map days are now visible on white.
Upgrading
git pull, npm ci, npm run build, restart the dashboard, then re-run scripts\register-task.ps1 from an Administrator PowerShell. That is what moves the snapshot folder; until you do, the collector keeps using the old one and logs that the deployed script differs from the repo. The Android app is unchanged: keep 1.3 from the 3.1.2 release.
Prefer a native Windows app over the dashboard? Data Usage 0.2.1 makes the same change. Run one collector or the other, not both: each takes its own hourly snapshot.
Data Usage Tracker 3.2.0
A light theme, your own app colours, clickable Top 10 bars, loading skeletons that match every page exactly, and a pager that goes straight to any page. Plus everything since 3.1.2: hourly collection, renaming apps, "Where it went" on the laptop, and an installable app.
Added
- Light theme. A Dark / Light / System menu in the top bar. Its own design, not the dark theme inverted: a pale grey canvas under white cards, real borders and soft shadows, hover as elevation, text colours measured for contrast, each device's accent deepened until it reads as text on white, and a heat map that runs light to dark. App colours are painted within a per-theme lightness band, so near-white brand colours stay visible on white. Remembered per browser and applied before the first paint, so no page flashes the other theme. Dark stays the default.
- Choose any app's colour. The rename pencil now also sets the colour: a colour picker and a hex field that stay in step, and "Default colour" to go back. Stored in the database (new
app_colorstable, schema 6) beside renames, so it is backed up with the history. - Top 10 bars open the app. Clicking a bar on either By App page goes to that app's detail page, for the apps that have one.
- Go to any page of the history. The Sync Status run history has Newest and Oldest, Newer and Older, the page numbers around the current one, and a "Go to page" box. The phone's upload history, which used to stop at its newest 25, now pages the same way. Pages are URLs.
- Rename any app from the pencil beside its name; the name is stored with the history.
- "Where it went" on the laptop's overview: Wi-Fi against wired, then one row per network.
- Busiest-hour callout and a Download / Upload legend on every Hour of day card.
- Installable web app with an offline page (which caches nothing else).
Changed
- Loading skeletons are exact at every width. They now render each page's own markup, headings and fixed text, instead of one measured height per section, so nothing moves when the data lands.
- The collector runs hourly, so the dashboard is never more than an hour behind the machine.
- Activity's Expand button is always shown.
Removed
- The network selector in the top bar. "Where it went" answers the same question on one card.
Upgrading
git pull, npm ci, npm run build, then restart the dashboard. The database gains its new table the first time something writes to it (a collection, a phone sync, or a rename or colour change). Re-run scripts\register-task.ps1 as Administrator if you have not since hourly collection arrived. The Android app is unchanged: keep 1.3 from the 3.1.2 release.
Data Usage Tracker 3.1.2
The Android app is now release-signed with a permanent key.
Added
- Release signing for the Android app.
android\local.propertiescan name a properties file (signing.properties=...) that points to a keystore outside the repo, andassembleReleasethen signs with it. Without that line a release build is unsigned, as before. With it, a missing file or an uneditedCHANGE_MEfails the build instead of signing with nothing. The README explains the setup.
Changed
- Android app 1.3 (
versionCode4).
Android app
data-usage-reporter-1.3.apk is Data Usage Reporter 1.3 (Android 8.0+), built from this release's android/ source and signed with the project's release key:
CN=Data Usage Tracker
SHA-256 ab:34:f0:77:4f:3d:c5:0b:7e:0d:e7:c0:04:7e:ee:ce:82:01:89:1a:a4:da:37:73:ca:b1:52:19:06:13:4f:a1
apksigner verify --print-certs data-usage-reporter-1.3.apk should print the same digest. Later releases are signed with this key too, so they install over this one as normal updates.
adb install -r data-usage-reporter-1.3.apk
If you installed the 1.2 APK from 3.1.1, uninstall it first. That build was debug-signed, and Android refuses to update an app signed with a different key. Nothing already uploaded to the dashboard is lost: its first sync after reinstalling re-sends the phone's history, and the dashboard stores the larger reading instead of counting it twice. After reinstalling, enter the address and token again and re-grant usage access.
Data Usage Tracker 3.1.1
A local-only dashboard that keeps Windows' per-app network usage history permanently, plus an Android reporter for phones. Setup is in the README.
This is the first published release. It covers 3.1.0 and 3.1.1.
3.1.1
Changed
- The README's screenshots are whole pages, top bar to footer.
npm run demo:shotsgrows the window to each page's full height. Four images now show more than the previous six viewport crops did.
3.1.0
Added
- The Activity heat map expands to the whole history. Once a device has more than the card's six months of data, an Expand button in the legend row opens
/<platform>/<slug>/activity. It shows every 26-week block stacked vertically, oldest first, all sharing one colour scale and each labelled with its span and total. The page follows the network scope and has its own loading skeleton.
Changed
- Phones get the desktop layout. Pages declare a 1024px viewport, so a phone lays out the desktop page and zooms it to fit, like "desktop site" mode. Pinch-zoom still works, and desktop browsers are unaffected. This also fixes horizontal scrolling on the phone overview at 375px.
- On a phone the sidebar starts collapsed. A stored toggle still wins, and a desktop still starts expanded.
Fixed
- A heat map starting in a month's last week no longer draws two month labels on top of each other ("JunJul").
Android app
This release originally included a debug-signed data-usage-reporter-1.2.apk. It was removed when 3.1.2 started shipping a release-signed APK. Install the APK from 3.1.2 instead. If you installed 1.2, uninstall it first, because Android refuses to update an app signed with a different key.