Skip to main content

Features

Compare views and save the ones you reuse

Use comparison mode only when both sides are coverage-safe, and save a dashboard view as a name plus the six canonical filter params.

By Novus Stream Solutions Editorial Team. Last reviewed Sun Aug 09 2026 00:00:00 GMT+0000 (Coordinated Universal Time).

The dashboard is a filtered slice of your imports: a range, a provider set, a project set, and an optional model substring. Two features exist to stop you from reconstructing that slice by hand every time, and to stop you from subtracting two slices that were not recorded the same way.

Neither feature invents metrics. Comparison will often look empty on a mixed ChatGPT / Claude / Gemini account. That is the honest result. Unavailable is not zero.

Open comparison from the dashboard you already have

On /app/dashboard, use Compare. The link is built from the view on screen (comparisonHrefFromView), so side A opens already seeded with your current range and filters. Side B is left at its defaults on purpose. Seeding both sides with the same slice would open the page on a comparison of a view with itself and teach you, in one screen, that the feature is broken.

All twelve parameters live in the URL, namespaced aRange / bRange and so on. A comparison you can read is a comparison you can bookmark or send to yourself. Nothing in that query string is a session title, a prompt, or a transcript.

When a row may print a delta

buildComparisonReport does not reimplement a comparison rule. It calls the same function the period-over-period narrative uses, and a difference is printed only when both sides were fully covered and every contributing session shared the same adapter version, normalization version, quality, source, and calculation.

Where it refuses, the row keeps its place and names the gate:

  • A side has no sessions — there is nothing to compare.
  • A side has no value — you get the capability-matrix reason, for example that the Claude export format does not contain tokens.
  • A side is only partly covered — the missing sessions are missing by export format, not at random.
  • Signatures differ — the two sides recorded the metric differently, so subtracting them would compare two methods.

Blocked rows are kept, not filtered out. A tidy table of only the comparable metrics answers a different question from the one you asked, and you would have no way to see which rows were removed. On a mixed-provider account most of this table will read "Not comparable." Read the capability matrix and /methodology if you want the underlying grades.

Composition aligns providers, models, and project groups across both sides. A key present on one side only keeps its row and reads Not in this view on the other — that asymmetry is usually the finding.

Save a view as a name and a query string

A saved view is not a snapshot of numbers. It is a name plus the six dashboard filter params: range, custom from, custom to, providers, projects, and model substring. They live in the dashboard_view table (migration 0007), unique on (userId, name). Saving under an existing name updates it.

Two rules carry the feature:

  1. Only those six params are ever stored. The serializer rebuilds the string from an allow-list rather than trusting a hidden field, and the reader re-canonicalises again on load. A crafted post cannot persist redirect= or a userId under your account and get it rendered back as a link you are invited to click.
  2. Canonical ordering. Multi-values are de-duplicated and sorted, so the same view saved from two different orderings of the provider multi-select is one string. That is what makes "this is the view on screen now" answerable.

The limit is 20. It is a cap, not a queue: nothing is silently evicted, because you cannot see an eviction happen.

The save form sits outside the GET filter form. A <form> inside a <form> is invalid HTML; browsers resolve it by dropping one of the two, which disables either the filters or the save button depending on the browser.

Saved views do not store session ids, titles, or transcripts. Parsing remains in the browser. See privacy and sharing for what an account export contains.

Suggested uses

  • This week versus last week, same providers. Seed A from the dashboard, set B to the previous equivalent window, and expect several token/cost rows to refuse if Claude or Gemini web is in the mix.
  • Codex-only cost. Filter both sides to Codex before comparing cost. That is one of the few token comparisons the formats can actually support.
  • A project you keep returning to. Save the project id plus all-time, then reopen it from the saved-views section instead of hunting through the filter bar.

Step-by-step click path: Compare two slices of your AI work. The Novus hub at novusstreamsolutions.com (opens in a new tab) lists the other apps if you came here from the catalog; AI Stats comparison does not deep-link into them, because they do not share this metric model.

Was this page helpful?

Your answer stays in this browser. It is not sent anywhere, and no account or cookie is involved.