Skip to content

feat!: report template insights session usage per app - #29796

Merged
EhabY merged 3 commits into
mainfrom
ehab/client-642-per-app-template-insights
Oct 19, 2026
Merged

EhabY merged 3 commits into
mainfrom
ehab/client-642-per-app-template-insights

Conversation

@EhabY

@EhabY EhabY commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Report template insights session usage per app instead of five fixed family rows. Apps with usage use registry names and icons (VS Code, Cursor, GoLand, Zed, etc.). Rows carry no app family. Template-defined workspace apps retain their existing accounting and report method: workspace_app.

The API adds usage_total_seconds, counting each user's active minutes once. UI bars use that total rather than summed app time, so overlapping apps can add up to more than 100%. Missing icons have a fallback; accounting rows have explanatory tooltips.

Implements the API/UI portion of the Completing Scalable IDE Session Tracking RFC. No migrations or ingestion changes. Prometheus metrics are handled separately in #29906. Targets main; #30497 is merged. Part of CLIENT-642.

Breaking changes

For GET /api/v2/insights/templates (report.apps_usage):

  • Built-in rows identify individual reported apps, not families; unused apps are omitted. Display names and icons come from the registry.
  • type (builtin/app) is replaced by method (connection_log_method values): ssh, reconnecting_pty, or port_forwarding for session apps, workspace_app for template apps. Session methods are derived from the app name until Record the connection method for session app usage #31012 stores them.
  • Template apps sharing a slug merge into one row across templates, shown with the newest app's display name and icon. Previously, differing names or icons split them.
  • Web Terminal's slug changes from reconnecting-pty to reconnecting_pty.
  • Accounting rows may appear as unknown or overflow ("Other apps").
  • The Go SDK removes the unused codersdk.UnionByFamily helper.

Consumers relying on the fixed five rows, family slugs, or previous display names must update.

Before/after JSON example

Same usage in both responses: one user is active for 10 minutes, using VS Code for 10 minutes, Cursor for 5 minutes, and Web Terminal for 1 minute. Cursor and Web Terminal overlap with VS Code. These are response excerpts; unchanged report/app metadata and interval reports are omitted.

Before: Cursor is included in the VS Code family total, and unused built-ins are still returned.

{
  "report": {
    "active_users": 1,
    "apps_usage": [
      { "slug": "vscode", "display_name": "Visual Studio Code", "seconds": 900 },
      { "slug": "jetbrains", "display_name": "JetBrains", "seconds": 0 },
      { "slug": "reconnecting-pty", "display_name": "Web Terminal", "seconds": 60 },
      { "slug": "ssh", "display_name": "SSH", "seconds": 0 },
      { "slug": "sftp", "display_name": "SFTP", "seconds": 0 }
    ]
  }
}

After: Each used app has its own row; the active-time total remains 600 seconds despite overlapping app usage.

{
  "report": {
    "active_users": 1,
    "usage_total_seconds": 600,
    "apps_usage": [
      { "slug": "cursor", "method": "ssh", "display_name": "Cursor", "seconds": 300 },
      { "slug": "reconnecting_pty", "method": "reconnecting_pty", "display_name": "Web Terminal", "seconds": 60 },
      { "slug": "vscode", "method": "ssh", "display_name": "VS Code", "seconds": 600 }
    ]
  }
}

Response cap

Registered apps with usage and accounting rows are exempt from the response limit. The 64 busiest unregistered names are listed individually; the rest fold into "Other apps". Folded minutes are summed per user and half hour, then capped at that user's active minutes. Because app overlap is not stored, folded overflow sets seconds_is_upper_bound and the UI labels it "Up to". Stored overflow remains exact when no apps fold. The cap shapes only the response, not storage or scans.

Refactoring plan and verification evidence

The approved cleanup preserves behavior and the optimized single-/multi-template aggregation:

  1. Select excess apps directly with deterministic ordering and consolidate seconds/template-ID response assembly, keeping overflow accounting and the no-fold fast path.
  2. Use explicit registry, accounting-label, and fallback presentation paths in Go; shorten comments while retaining non-obvious rationale.
  3. Flatten frontend accounting descriptions and prepare labels before JSX; preserve keys, icons, tooltips, and the active-time denominator.
  4. Preserve regression coverage and add cap-boundary, filtered-template, normalized-name, and irregular-bucket cases.
  5. Regenerate affected SQL, SDK, API-reference, and TypeScript outputs.

The final query matched the original PR query in 2,412 deterministic/randomized cases. Database/SDK suites passed 2,846 tests; targeted backend suites passed 46 tests. Frontend utility tests, five Storybook stories, generation, repository lint, and type checks passed.

PostgreSQL 18.6 synthetic benchmarks, seven alternating rounds, median EXPLAIN ANALYZE execution time:

Workload Session rows Original PR Refactored Change
Single-template buckets 522,101 551.01 ms 589.83 ms +7.0%
Multi-template, no folding 593,020 827.13 ms 826.98 ms ~0.0%
Multi-template, with folding 599,070 991.80 ms 982.58 ms -0.9%

Scan counts, buffer hits, and spill sizes did not increase; no-fold overflow scans executed zero times. Timing was noisy: the single-template uninstrumented wall-time median was 522.08 → 518.56 ms. These measurements are query benchmarks, not endpoint latency or a production-performance guarantee.

Generated with Coder Agents on behalf of @EhabY.

@github-actions github-actions Bot added the release/breaking This label is applied to PRs to detect breaking changes as part of the release process label Sep 23, 2026
@linear-code

linear-code Bot commented Sep 23, 2026

Copy link
Copy Markdown

CLIENT-642

Base automatically changed from feat/expose-app-session-counts to main September 24, 2026 12:12
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch 3 times, most recently from 9667748 to 362e1f8 Compare September 24, 2026 16:55
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from 362e1f8 to dbeb2fd Compare October 7, 2026 13:51
@EhabY
EhabY added this pull request to stack #30468 October 7, 2026 13:59
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from dbeb2fd to 80e7966 Compare October 7, 2026 17:32
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from 80e7966 to a9361ac Compare October 8, 2026 09:06
@EhabY
EhabY removed this pull request from stack #30468 October 8, 2026 09:15
@EhabY
EhabY changed the base branch from main to fix/insights-family-metrics October 8, 2026 09:16
@EhabY
EhabY added this pull request to stack #30499 October 8, 2026 09:16
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from a9361ac to 75ac922 Compare October 8, 2026 15:45
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from 75ac922 to 29dfcdf Compare October 8, 2026 15:59
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from 29dfcdf to ce68dce Compare October 8, 2026 16:00
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from ce68dce to 13e5b01 Compare October 8, 2026 16:25
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch 2 times, most recently from 9f3ca07 to b46e52a Compare October 12, 2026 13:20
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from b46e52a to 6ced729 Compare October 12, 2026 13:58
Base automatically changed from fix/insights-family-metrics to main October 12, 2026 20:58
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from 6ced729 to f87b2ad Compare October 12, 2026 21:09
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from f87b2ad to 59ed4a3 Compare October 13, 2026 15:59
@EhabY
EhabY marked this pull request as ready for review October 13, 2026 16:02
@EhabY
EhabY requested a review from nickvigilante as a code owner October 13, 2026 16:02
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from 59ed4a3 to 39a27bd Compare October 13, 2026 17:28
@EhabY
EhabY requested a review from code-asher October 14, 2026 21:13

@code-asher code-asher left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Been trying it out and it is looking good!

Comment thread coderd/insights.go Outdated
Comment thread coderd/insights.go Outdated
Comment thread coderd/insights.go Outdated
Comment thread site/src/pages/TemplatePage/TemplateInsightsPage/utils.ts Outdated
Comment thread site/src/pages/TemplatePage/TemplateInsightsPage/utils.ts Outdated
Comment thread site/src/pages/TemplatePage/TemplateInsightsPage/utils.ts Outdated
@EhabY
EhabY requested a review from code-asher October 16, 2026 10:50
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from f8c7ada to 8b72baa Compare October 16, 2026 19:17

@code-asher code-asher left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can think of something to do with type/method (whether here or in a followup) but otherwise looks good to me!

EhabY added 2 commits October 19, 2026 09:38
Remove the family field and AppFamilyWorkspaceApp from TemplateAppUsage,
rename the session and template app variables in
convertTemplateInsightsApps, and simplify the accounting row tooltips.
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch 2 times, most recently from 5a93e5f to 4185c58 Compare October 19, 2026 09:58
@EhabY
EhabY force-pushed the ehab/client-642-per-app-template-insights branch from 4185c58 to 0da5d0b Compare October 19, 2026 10:45
@EhabY
EhabY merged commit f4cd0de into main Oct 19, 2026
36 checks passed
@EhabY
EhabY deleted the ehab/client-642-per-app-template-insights branch October 19, 2026 14:59
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release/breaking This label is applied to PRs to detect breaking changes as part of the release process

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants