Repository navigation
fix(metrics): chart histogram metrics as bucket percentiles by default - #116674
Conversation
A histogram's scalar value holds the running sum of observations, so the builder charted an ever-growing total instead of a latency. Add histogram p50/p95/p99 aggregations that map to the API's histogram_quantile, offer them only for histogram metrics, and default a histogram clause without operations to histogram p95. Exponential histograms stay out until the backend reads their lower-edge bucket bounds correctly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 28e82888-d17f-491f-8aa4-4ba0138e92be
|
😎 Merged successfully - details. |
🤖 CI report✅ Trunk lane — non-backend lane (
|
| Function | Location | Complexity | Limit |
|---|---|---|---|
convertMetricsQuery |
products/metrics/frontend/queryLanguages/convert.ts:183 |
22 | 10 |
propertyFilterToMetricFilter |
products/metrics/frontend/components/metricsViewerLogic.tsx:279 |
13 | 10 |
builderEditorLimits |
products/metrics/frontend/queryLanguages/convert.ts:31 |
12 | 10 |
stripParens |
products/metrics/frontend/queryLanguages/convert.ts:108 |
12 | 10 |
<anonymous> |
products/metrics/frontend/components/metricsViewerLogic.tsx:472 |
11 | 10 |
<anonymous> |
products/metrics/frontend/components/metricsViewerLogic.tsx:1013 |
11 | 10 |
✅ Duplication (Python) — clean
New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.
✅ Duplication (TypeScript) — clean
New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.
🚨 Comment density — 7% of added code lines are comments (21 of 305)
This section warns when comments are more than 3% of the code lines a PR adds, and alerts above 6%. Before agent-assisted PRs, the typical share was about 2%. Only full-line comments count. Docstrings, generated files, snapshots, migrations, and workflow files are left out.
Comments that restate the code, record how the change came about, or narrate the next line add noise for the next reader. Keep the comments that explain a reason the code cannot show, and remove the rest. See .agents/skills/writing-code-comments/SKILL.md for the house rules.
Files with the most added comment lines:
| File | Comment lines | Added lines |
|---|---|---|
products/metrics/frontend/components/metricsViewerLogic.tsx |
13 | 114 |
products/metrics/frontend/components/metricsViewerLogic.test.ts |
4 | 98 |
products/metrics/frontend/components/MetricsOperations.tsx |
3 | 42 |
products/metrics/frontend/components/MetricsOperations.test.tsx |
1 | 37 |
This check does not block merging. It updates on every push and clears when the share drops.
⚠️ Bundle size — 🔺 +2.2 KiB (+0.0%)
Uncompressed size of every built .js bundle, compared against the base branch.
Total: 75.88 MiB · 🔺 +2.2 KiB (+0.0%)
| File | Size | Δ vs base |
|---|---|---|
render-query/src/render-query/render-query.js |
24.41 MiB | 🔺 +1.3 KiB (+0.0%) |
Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report
✅ Eager graph — within budget
How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1005.7 KiB · 23 files | 🟢 -52 B (-0.0%) | █████████░ 85.8% of 1.14 MiB |
logged-out boot: index + App + bootApp (preloaded by every page, including /login)src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts |
2.87 MiB · 606 files | 🟢 -52 B (-0.0%) | █████████░ 94.5% of 3.03 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.33 MiB · 2,533 files | 🔺 +4 B (+0.0%) | ██████████ 95.9% of 7.64 MiB |
dashboard scenesrc/scenes/dashboard/Dashboard.tsx |
9.57 MiB · 3,617 files | 🔺 +1.4 KiB (+0.0%) | █████████░ 93.0% of 10.30 MiB |
today home pathsrc/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx |
7.35 MiB · 2,543 files | 🔺 +4 B (+0.0%) | █████████░ 93.2% of 7.89 MiB |
events scenesrc/scenes/activity/explore/EventsScene.tsx |
9.15 MiB · 3,446 files | 🔺 +1.4 KiB (+0.0%) | █████████░ 92.7% of 9.88 MiB |
replay detail scenesrc/scenes/session-recordings/detail/SessionRecordingDetail.tsx |
11.93 MiB · 4,285 files | 🔺 +43 B (+0.0%) | ████████░░ 79.3% of 15.05 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/zod/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/billing/billingLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/ProductEmptyState/productSetupPreloadLogic.ts stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 1.3 KiB | src/index.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 839 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 38.7 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js |
| 33.9 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
| 28.7 KiB | src/scenes/scenes.ts |
| 27.6 KiB | src/lib/constants.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.9 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.9 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 316.0 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.9 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.23 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.23 MiB · 19 files | 🟢 -52 B (-0.0%) | ████░░░░░░ 39.0% of 5.72 MiB |
| Deferred (lazy) | 2.10 MiB · 40 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.2 KiB | no change | █░░░░░░░░░ 6.0% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 874.8 KiB | dist/toolbar/toolbar-app-ZPOT7W43.css |
| 664.0 KiB | dist/toolbar/chunk-chunk-HI6MPXRL.js |
| 257.8 KiB | dist/toolbar/chunk-chunk-IVAG7WAO.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 129.6 KiB | dist/toolbar/chunk-chunk-JLOIU7PO.js |
| 74.7 KiB | dist/toolbar/toolbar-app-KOHPHDJ6.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-6X4NN5IR.js |
| 21.7 KiB | dist/toolbar/chunk-chunk-WHIESAEG.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-DV7IWQNF.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🟢 -64.0 KiB (-0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1009.76 MiB · 🟢 -64.0 KiB (-0.0%)
⚠️ Playwright — 1 flaky
🎭 Playwright report · View test results →
- Logout in another tab results in logout in the current tab too (chromium)
These issues are not necessarily caused by your changes.
Annoyed by this section? Help fix flakies and failures and it will go green!
✅ Hogbox preview — ready, open the preview
▶ Open the preview
| 🔑 Login | test@posthog.com / 12345678 (demo data) |
| 🧩 Running | this PR's backend and frontend, on the PostHog :master base |
| 🔗 Link | stable across rebuilds: a re-push swaps the box underneath, the URL stays |
| 🔒 Access | tailnet only (PostHog VPN) |
| 🛠️ Admin | inspect & debug state in hogland |
| 💤 Idle | sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen |
commit 8157405 · box box-d95ac7d0b1bf · ready in 1247s (push → usable) · build log · rebuilds on every push, torn down on close
| (groupByKeys.length && supportsHistogramQuantile(clause.selectedMetricType) | ||
| ? DEFAULT_HISTOGRAM_AGGREGATION | ||
| : fallbackAggregation(groupByKeys)), |
There was a problem hiding this comment.
P2 · Respect the active range function when defaulting grouped histograms
Selecting rate or increase on an ungrouped histogram clears its percentile aggregation. Adding a group-by then makes setGroupByKeys restore histogram_p95 while retaining the range function. MetricQueryRunner rejects this combination, so the chart fails instead of showing grouped rates. Use the sum fallback when a range function is active.
There was a problem hiding this comment.
Fixed in 318d7a0. A clause with an active range function now never defaults to a histogram percentile: grouping falls back to sum, and metric selection uses the same check. The grouping test has a new rate row that failed before the fix.
|
…s on The backend rejects histogram_quantile together with rate or increase. Adding a group-by to a histogram clause with a range function restored histogram p95 and the query failed. A clause with a range function now never defaults to a histogram percentile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 28e82888-d17f-491f-8aa4-4ba0138e92be
|
Risk: No findings This increment only adjusts the aggregation menu in the Metrics viewer UI so histogram percentile options remain available for clauses whose histogram quantile came from a saved PromQL conversion (no metric type yet), and adds tests. No security-relevant surface is touched: options map to typed constants, reducers keep combinations valid before any request is built, and no auth, tenancy, or injection paths are involved. Sentinel reviewed |
| supportsHistogramQuantile(metricType) | ||
| ? [...HISTOGRAM_AGGREGATION_OPTIONS, ...AGGREGATION_OPTIONS] | ||
| : AGGREGATION_OPTIONS |
There was a problem hiding this comment.
P2 · Keep percentile choices available for converted histogram clauses
Switching a PromQL histogram percentile to Builder produces a clause without metricType, and applyQuery does not backfill it from the loaded picker. aggregationOptionsFor(null) therefore gives the Histogram p95 chip only scalar alternatives, preventing selection of p50 or p99. Include histogram choices when the current aggregation is a histogram percentile.
There was a problem hiding this comment.
Fixed in 8157405. The aggregation chip now offers the histogram percentiles when the current aggregation is a histogram percentile, so a converted clause without a metric type can switch between p50, p95 and p99. New test MetricsOperations.test.tsx: the case with no metric type failed before the fix.
There was a problem hiding this comment.
Not approved — this change needs a human reviewer.
Re-add the stamphog label to request another review once you have addressed this.
@PostHog's current concern about percentile choices remains unaddressed; the older range-function concern is fixed. Update MetricsOperations.tsx to include histogram choices when the active aggregation is a histogram percentile, add a regression test for converted clauses without metricType, and re-request review.
- Author wrote 0% of the modified lines and has 18 merged PRs in these paths (familiarity MODERATE).
- PostHog Review (Standard) reviewed the current head: 1 finding, posted on the PR.
- posthog[bot] reviewed the current head.
- @PostHog on products/metrics/frontend/components/MetricsOperations.tsx: Converted histogram-percentile clauses without metricType still receive only scalar aggregation choices. The menu checks selectedMetricType alone, viewerClauseFromNode leaves missing types null, and applyQuery does not backfill from the already-loaded picker; users cannot switch the percentile to p50 or p99.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 192L, 4F substantive, 320L/6F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1d-complex (320L, 6F, single-area, fix) |
| stamphog 2.5.0 | .stamphog/policy.yml @ 318d7a0 · reviewed head 318d7a0 |
A PromQL histogram percentile switched to the builder has no metric type until the picker loads, so its aggregation chip offered only scalar choices. The chip now also offers p50, p95 and p99 when the current aggregation is a histogram percentile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 28e82888-d17f-491f-8aa4-4ba0138e92be
There was a problem hiding this comment.
Approved.
Contained frontend change using existing backend capabilities, with owning-team authorship and current-head review assurance. Both earlier substantive review concerns are addressed in the current code; no remaining showstoppers were identified.
- Author wrote 0% of the modified lines and has 18 merged PRs in these paths (familiarity MODERATE).
- PostHog Review (Standard) reviewed the current head: no findings.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 196L, 4F substantive, 369L/7F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1d-complex (369L, 7F, single-area, fix) |
| stamphog 2.5.0 | .stamphog/policy.yml @ 8157405 · reviewed head 8157405 |
|
/trunk merge |
Problem
sumof observations in the scalarvaluecolumn. The distribution lives in the bucket columns.valueby default, and its aggregations (sum, avg, p95 across series) all readvaluetoo.histogram_quantile, but the builder cannot express it.Changes
histogram_quantilewith quantile 0.5, 0.95 or 0.99.Note
#113473 removed type-based defaults because remote write can mistype counters and gauges. This PR restores a default for
histogramonly. Ingest writes that type only on rows that carry bucket data.Left out on purpose:
_histogram_quantilereads every bound as an upper edge, so the percentile would be wrong.How did you test this code?
metricsViewerLogic.test.tsandqueryLanguages.test.ts. The new assertions failed before the fix (aggregationnullinstead ofhistogram_p95, and "The builder cannot edit this query").Test rationale: The logic tests catch a histogram clause that falls back to the raw sum, and a saved
histogram_quantilenode that reopens outside the builder. The PromQL round-trip cases catch a lossy conversion. The closest existing tests covered only the cross-seriesp95.Release status
Docs update
None.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: PostHog Slack app (Claude Code), claude-opus-5-5
Created with PostHog from a Slack thread
🤖 Generated with Claude Code