Skip to content

feat(hogql): staff switch for the native events table - #122489

Merged
trunk-io[bot] merged 21 commits into
masterfrom
aspicer/events-cluster-route
Oct 26, 2026
Merged

trunk-io[bot] merged 21 commits into
masterfrom
aspicer/events-cluster-route

Conversation

@aspicer

@aspicer aspicer commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Staff can switch their own browser to the native JSON events table, and every app surface follows that choice without switching the project for teammates. This folds in #122894 and removes the events cluster route from #115591, which the main cluster upgrade made unnecessary.

Problem

Staff testing native events cannot use the app the way customers do. Per-query modifiers do not follow navigation through insights and dashboards, so trying native meant switching the project for every teammate.

#115591 started native queries on the events cluster because the main cluster's older ClickHouse failed on common native query shapes. The main cluster moved to the same 26.9 build on Oct 25 (thread). The route now only adds a second connection path and breaks cancellation for native reads.

Changes

A staff browser with the cookie ph_new_events_schema=1 reads events_json on every request, impersonated sessions included. Non-staff requests ignore it. A query modifier beats the cookie, the cookie beats the project list in CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA_TEAMS, and that beats the global setting. Stored project modifiers no longer switch the table, and the instance settings API now validates the project list.

Queries resolve their table before caching or queueing, so native and legacy results never share a cache key, precompute job or revalidation slot. Nested reads inherit the running query's table. Streamed dashboards copy the request context, because their tiles run after the middleware returns. A read of events_json skips the preaggregated web tables, because those are built from the legacy events table.

The useNewEventsCluster modifier, the NEW_EVENTS_CLUSTER workload and its pool, and CLICKHOUSE_NATIVE_EVENTS_HOST are gone. Native reads start on the main cluster and reach events_json through its Distributed table, so cancellation works again. Nothing here enables a project. Schema regeneration and setting descriptions are mechanical.

How did you test this code?

Test rationale: API tests cover staff, non-staff, impersonation, a legacy override and a streamed dashboard. The nested-read matrix covers inheritance and explicit overrides. Queue-boundary tests check one rebuild per table and that serialization keeps the choice. Precompute tests check that a switched build gets its own job and prints the table its identity names.

The database-free tests and repo-wide mypy ran locally; database-backed suites run on CI. A query shape that failed on the old main cluster, a constant IN over a property in the select list, ran from the main cluster against events_json on Oct 26.

Release status

  • No feature flag controls this change

Docs update

The web analytics query-serving guide describes table selection across precompute jobs and revalidation queues. The ClickHouse workload reference no longer lists the events cluster workload.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Fable 5.1 and Claude Opus 5.5; Codex, GPT-6.

Skills: /writing-tests, /writing-code-comments, /improving-drf-endpoints, /writing-dataclasses, /writing-user-facing-copy, /writing-pr-descriptions, /writing-clickhouse-queries, /authenticating-to-clickhouse, /running-ci-preflight, /stacking-prs, /merging-prs. This PR first routed every native read to the events cluster. After the main cluster upgrade, the route and its host setting were removed, and #122894 was merged into this branch so both changes ship together. No customer material was added.

🤖 Generated with Claude Code

A query whose printed SQL reads events_json runs on the events cluster
when CLICKHOUSE_NATIVE_EVENTS_HOST is set and the project is in
CLICKHOUSE_NATIVE_EVENTS_TEAMS. The project's stored table setting is
the switch, so insights, SQL, async and child queries, all-time lookups,
cohort recalculation and precompute builds follow without a per-query
opt-in. The useNewEventsCluster modifier and everything that gated it
are removed.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@aspicer aspicer self-assigned this Oct 23, 2026
@trunk-io

trunk-io Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

😎 Stack merged successfully - details.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

✅ Complexity (TypeScript) — clean

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

⚠️ Duplication (Python) — 1 new duplicated block (worst 153 tokens)

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.

First copy Second copy Lines Tokens
products/analytics_platform/backend/lazy_computation/tests/test_lazy_computation_executor.py:1113 products/analytics_platform/backend/lazy_computation/tests/test_lazy_computation_executor.py:3969 24 153
✅ 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 — 6% of added code lines are comments (29 of 480)

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/analytics_platform/backend/lazy_computation/lazy_computation_executor.py 5 27
posthog/api/team/query_modifiers.py 3 4
posthog/hogql/modifiers.py 3 6
posthog/models/event/new_events_schema.py 3 30
products/analytics_platform/backend/lazy_computation/tests/test_lazy_computation_executor.py 3 68
posthog/hogql/test/test_new_events_schema_routing.py 2 101
posthog/hogql_queries/utils/timestamp_utils.py 2 5
products/dashboards/backend/api/dashboard.py 2 11

This check does not block merging. It updates on every push and clears when the share drops.

⚠️ Bundle size — 🔺 +20.8 KiB (+0.0%)

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 76.88 MiB · 🔺 +20.8 KiB (+0.0%)

File Size Δ vs base
render-query/src/render-query/render-query.js 24.88 MiB 🔺 +12.4 KiB (+0.0%)
posthog-app/_parent/products/apm/frontend/ApplicationObservabilityScene.js 11.8 KiB 🔺 +11.8 KiB (new)
posthog-app/_parent/products/tracing/frontend/TracingScene.js 161.8 KiB 🟢 -10.0 KiB (-5.8%)
posthog-app/_parent/products/signals/frontend/inbox/InboxScene.js 512.0 KiB 🔺 +5.3 KiB (+1.0%)
posthog-app/_parent/products/ai_observability/frontend/offline-evaluations/OfflineScorerHistoryScene.js 19.5 KiB 🔺 +1.3 KiB (+7.2%)
posthog-app/_parent/products/ai_observability/frontend/evaluations/EvaluationsScene.js 84.9 KiB 🟢 -1008 B (-1.1%)

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
1022.4 KiB · 24 files 🔺 +730 B (+0.1%) █████████░ 87.2% 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.96 MiB · 620 files 🔺 +1.8 KiB (+0.1%) ██████████ 97.7% of 3.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.47 MiB · 2,557 files 🔺 +19.7 KiB (+0.3%) ██████████ 99.7% of 7.50 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
9.92 MiB · 3,725 files 🔺 +2.4 KiB (+0.0%) ██████████ 99.1% of 10.01 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
7.65 MiB · 2,649 files 🔺 +19.7 KiB (+0.3%) ██████████ 98.8% of 7.74 MiB
AI-first home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
7.89 MiB · 2,641 files 🔺 +19.7 KiB (+0.2%) ██████████ 99.8% of 7.91 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
9.37 MiB · 3,508 files 🔺 +2.4 KiB (+0.0%) ██████████ 97.7% of 9.59 MiB
web analytics scene
src/scenes/web-analytics/WebAnalyticsScene.tsx
10.30 MiB · 3,755 files 🔺 +2.4 KiB (+0.0%) ██████████ 95.1% of 10.83 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
8.40 MiB · 3,086 files 🔺 +2.3 KiB (+0.0%) █████████░ 88.7% of 9.47 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
🟢 products/wizard/frontend/runs/WizardRunDetailsDrawer.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayShell.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayContextPanelFloating.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodaySidePanel.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayTopBar.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/todayRailItems.tsx 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/queries/validators.js 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
🟢 packages/quill/packages/charts/ stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/RecordingsWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/api/primitives.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/scenes/notebooks/Notebook/notebookLogic.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.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
🟢 src/queries/validators.js stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/LiveMetricsDashboard/LiveWebAnalyticsMetrics.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 products/product_analytics/frontend/insights/trends/WorldMap/countryVectors.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/scenes/settings/SettingsMap.tsx stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 @jspm/core/nodelibs/browser/fs stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/[email protected]/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/[email protected]/node_modules/react/cjs/react.production.min.js
4.7 KiB ../node_modules/.pnpm/@[email protected]/node_modules/@jspm/core/nodelibs/browser/process.js
4.0 KiB ../node_modules/.pnpm/[email protected]/node_modules/scheduler/cjs/scheduler.production.min.js
1.7 KiB ../node_modules/.pnpm/[email protected]/node_modules/base64-js/index.js
1.6 KiB src/lib/utils/bootTiming.ts
1.6 KiB src/index.tsx
1.2 KiB src/RootErrorBoundary.tsx
949 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
86.1 KiB src/lib/api.ts
68.2 KiB src/lib/lemon-ui/icons/icons.tsx
41.9 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/[email protected]_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
27.0 KiB ../node_modules/.pnpm/[email protected]/node_modules/tailwind-merge/dist/bundle-mjs.mjs
24.6 KiB ../node_modules/.pnpm/[email protected]/node_modules/buffer/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/[email protected]/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/[email protected]/node_modules/prosemirror-view/dist/index.js
86.1 KiB src/lib/api.ts
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/[email protected]/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/[email protected]/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
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/[email protected]/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/[email protected]/node_modules/prosemirror-view/dist/index.js
86.1 KiB src/lib/api.ts
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
Size File
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/[email protected]/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/[email protected]/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/[email protected]/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/[email protected]/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
Size File
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
182.9 KiB src/queries/validators.js
153.8 KiB ../node_modules/.pnpm/[email protected]/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
322.9 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/module.mjs
316.1 KiB ../node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/posthog-js/dist/rrweb.js
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/[email protected]/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/[email protected]/node_modules/prosemirror-view/dist/index.js

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.29 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.29 MiB · 18 files 🔺 +1016 B (+0.0%) ████░░░░░░ 40.1% of 5.72 MiB
Deferred (lazy) 2.11 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
904.9 KiB dist/toolbar/toolbar-app-PJL3ZOG5.css
694.7 KiB dist/toolbar/chunk-chunk-S67E62V7.js
259.9 KiB dist/toolbar/chunk-chunk-LBUEMA4R.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
130.4 KiB dist/toolbar/chunk-chunk-RZCYPLTY.js
74.8 KiB dist/toolbar/toolbar-app-U2PZEED2.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-3Y7AY6NT.js
21.7 KiB dist/toolbar/chunk-chunk-WUPVVGIN.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 — 🔺 +649.1 KiB (+0.1%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 968.91 MiB · 🔺 +649.1 KiB (+0.1%)

ℹ️ MCP UI apps size — 34 app(s), 27969.1 KB JS

Built size of each MCP UI app (main.js + styles.css).

App JS CSS
debug 844.3 KB 209.1 KB
action 767.7 KB 209.1 KB
action-list 835.3 KB 209.1 KB
cohort 766.7 KB 209.1 KB
cohort-list 834.3 KB 209.1 KB
email-template 766.6 KB 209.1 KB
error-details 771.6 KB 209.1 KB
error-issue 768.9 KB 209.1 KB
error-issue-list 836.7 KB 209.1 KB
experiment 832.4 KB 209.1 KB
experiment-list 836.1 KB 209.1 KB
experiment-results 834.9 KB 209.1 KB
feature-flag 834.7 KB 209.1 KB
feature-flag-list 838.4 KB 209.1 KB
feature-flag-testing 770.0 KB 209.1 KB
inline-scan 767.2 KB 209.1 KB
insight-actors 833.8 KB 209.1 KB
llm-costs 831.1 KB 209.1 KB
session-recording 768.9 KB 209.1 KB
survey 768.3 KB 209.1 KB
survey-global-stats 831.1 KB 209.1 KB
survey-list 836.0 KB 209.1 KB
survey-stats 831.1 KB 209.1 KB
trace-span 767.1 KB 209.1 KB
trace-span-list 835.2 KB 209.1 KB
vision-observation-list 834.4 KB 209.1 KB
workflow 767.0 KB 209.1 KB
workflow-list 834.7 KB 209.1 KB
workflow-setup-status 766.7 KB 209.1 KB
query-results 1086.5 KB 209.1 KB
render-ui 1162.4 KB 209.1 KB
visual-review-snapshots 771.6 KB 209.1 KB
workflow-data-suggestions 769.4 KB 209.1 KB
workflow-sending-rules 768.0 KB 209.1 KB
ℹ️ MCP agent API — agent-facing tool changes

What this PR changes for agents, from the tool schema snapshots and tool definitions.

Tools changed (4):

Tool Params Scopes Annotations Schema chars
batch-export-create 28,053 -> 27,660
batch-export-update 27,812 -> 27,419
file-download-batch-exports-count-rows-create 12,599 -> 12,206
file-download-batch-exports-create 19,115 -> 18,722
✅ Playwright — all passed

All tests passed.

View test results →

⚠️ Backend coverage — 99.0% of changed backend lines covered — 2 uncovered

🧪 Backend test coverage

Patch coverage — changed backend lines (products + core): ████████████████████ 99.0% (260 / 262)

File Patch Uncovered changed lines
products/dashboards/backend/api/dashboard.py 33.3% 538, 3338

🤖 Agents: add a test only if an uncovered line exposes a realistic regression that existing tests miss. Otherwise explain why no new test is needed under "How did you test this code?". Gap list: the patch-coverage artifact on this run (gh run download 498361585049949 -n patch-coverage), or the coverage-data block at the end of this comment.

Per-product line coverage (touched products)
Product Coverage Lines
platform_features ██░░░░░░░░░░░░░░░░░░ 12.1% 7 / 58
demo ███████████░░░░░░░░░ 56.3% 1,540 / 2,736
data_tools ████████████░░░░░░░░ 60.9% 95 / 156
warehouse_sources_queue █████████████░░░░░░░ 65.2% 2,157 / 3,306
authorization ████████████████░░░░ 79.7% 181 / 227
batch_exports ████████████████░░░░ 81.6% 22,899 / 28,059
engineering_analytics █████████████████░░░ 85.0% 11,463 / 13,482
commands █████████████████░░░ 85.5% 1,618 / 1,893
mcp_analytics █████████████████░░░ 86.2% 5,720 / 6,638
ml_inference █████████████████░░░ 86.3% 524 / 607
apm █████████████████░░░ 86.6% 1,616 / 1,866
posthog_ai ██████████████████░░ 87.9% 4,296 / 4,886
notebooks ██████████████████░░ 88.5% 15,330 / 17,321
dashboards ██████████████████░░ 88.6% 7,785 / 8,785
warehouse_suggestions ██████████████████░░ 88.6% 3,047 / 3,438
mcp_registry ██████████████████░░ 89.0% 1,596 / 1,794
webmcp ██████████████████░░ 89.3% 292 / 327
cohorts ██████████████████░░ 89.6% 8,568 / 9,559
product_tours ██████████████████░░ 89.7% 1,355 / 1,510
signals ██████████████████░░ 90.0% 87,883 / 97,690
visual_review ██████████████████░░ 90.6% 9,858 / 10,875
tasks ██████████████████░░ 90.7% 80,960 / 89,233
managed_warehouse ██████████████████░░ 91.0% 12,234 / 13,441
data_warehouse ██████████████████░░ 91.1% 15,325 / 16,821
canvas ██████████████████░░ 91.2% 8,189 / 8,980
aeo ██████████████████░░ 91.2% 1,602 / 1,756
data_modeling ██████████████████░░ 91.4% 10,729 / 11,735
autoresearch ██████████████████░░ 91.4% 11,618 / 12,705
cdp ██████████████████░░ 91.5% 10,282 / 11,238
today ██████████████████░░ 91.6% 3,976 / 4,341
business_knowledge ██████████████████░░ 91.6% 10,017 / 10,934
metrics ██████████████████░░ 91.7% 10,627 / 11,590
slack_app ██████████████████░░ 91.7% 21,497 / 23,439
wizard ██████████████████░░ 91.7% 6,870 / 7,490
streamlit_apps ██████████████████░░ 91.9% 3,139 / 3,415
error_tracking ██████████████████░░ 92.0% 18,957 / 20,595
review_hog ██████████████████░░ 92.2% 17,745 / 19,240
conversations ██████████████████░░ 92.2% 30,449 / 33,008
stamphog ███████████████████░ 92.6% 8,869 / 9,579
early_access_features ███████████████████░ 92.6% 1,339 / 1,446
managed_migrations ███████████████████░ 92.6% 1,630 / 1,760
alerts_platform ███████████████████░ 92.8% 7,619 / 8,211
notifications ███████████████████░ 92.8% 1,216 / 1,310
web_analytics ███████████████████░ 93.3% 26,068 / 27,943
ai_training ███████████████████░ 93.3% 598 / 641
alerts ███████████████████░ 93.3% 9,488 / 10,167
cross_project_dashboards ███████████████████░ 93.4% 880 / 942
surveys ███████████████████░ 93.4% 6,941 / 7,429
exports ███████████████████░ 93.6% 4,166 / 4,452
ai_gateway ███████████████████░ 93.6% 787 / 841
approvals ███████████████████░ 93.7% 4,994 / 5,331
billing_alerts ███████████████████░ 93.7% 2,093 / 2,233
context_layer ███████████████████░ 93.8% 3,981 / 4,244
mcp_store ███████████████████░ 93.9% 9,183 / 9,779
marketing_analytics ███████████████████░ 93.9% 21,234 / 22,605
ai_observability ███████████████████░ 94.0% 29,256 / 31,128
messaging ███████████████████░ 94.0% 4,794 / 5,098
customer_analytics ███████████████████░ 94.1% 27,892 / 29,651
replay_vision ███████████████████░ 94.3% 32,958 / 34,956
workflows ███████████████████░ 94.3% 24,527 / 26,012
legal_documents ███████████████████░ 94.4% 2,313 / 2,451
logs ███████████████████░ 94.4% 19,281 / 20,429
actions ███████████████████░ 94.7% 1,004 / 1,060
reminders ███████████████████░ 94.8% 760 / 802
endpoints ███████████████████░ 94.9% 9,351 / 9,858
growth ███████████████████░ 94.9% 11,347 / 11,959
annotations ███████████████████░ 95.1% 1,095 / 1,151
skills ███████████████████░ 95.2% 7,630 / 8,015
uptime_monitoring ███████████████████░ 95.3% 306 / 321
experiments ███████████████████░ 95.4% 39,504 / 41,411
access_control ███████████████████░ 95.5% 8,105 / 8,491
subscriptions ███████████████████░ 95.6% 13,601 / 14,228
data_catalog ███████████████████░ 95.7% 4,608 / 4,817
product_analytics ███████████████████░ 95.8% 29,875 / 31,195
feature_flags ███████████████████░ 95.8% 28,497 / 29,737
revenue_analytics ███████████████████░ 95.9% 1,877 / 1,958
data_quality ███████████████████░ 96.0% 8,561 / 8,915
tracing ███████████████████░ 96.4% 4,360 / 4,524
warehouse_sources ███████████████████░ 96.5% 478,272 / 495,634
security ███████████████████░ 96.7% 1,549 / 1,602
account_audits ███████████████████░ 96.7% 770 / 796
pulse ███████████████████░ 97.1% 2,023 / 2,083
analytics_platform ████████████████████ 98.0% 2,828 / 2,885
groups ████████████████████ 98.2% 1,838 / 1,871
field_notes ████████████████████ 99.4% 172 / 173

Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit ddc98c5.

aspicer and others added 2 commits October 22, 2026 23:27
The query task rewrote every workload but logs to online or offline,
which sent a routed async query back to the main cluster. Cohort
inserts through the Distributed table wait for the rows to land before
the size is read back. A project that still stores the removed cluster
modifier keeps saving its settings. The core routing test no longer
drives a product query runner.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@trunk-io

trunk-io Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

Failed Test Failure Summary Logs
Scenes-App/Experiments ExperimentWithHealthFindings play-test The Storybook test could not find the text "Why?" because the scene remained on its loading spinner. Logs ↗︎

View Full Report ↗︎ ⋅ Docs

@aspicer
aspicer marked this pull request as ready for review October 23, 2026 08:29
@aspicer
aspicer requested a review from a team as a code owner October 23, 2026 08:29
@parameterai

parameterai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Risk: No findings

This increment adds only test coverage: a routing test pinning that events_json reads skip the preaggregated web tables, and a settings override pinning the preaggregated transformation suite to the legacy events table. No production code changed, so no new security surface is introduced.

Sentinel reviewed ddc98c5 · Review settings

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested review from a team October 23, 2026 08:30
@pr-assigner-resolver-posthog

Copy link
Copy Markdown

👀 Auto-assigned reviewers

These soft owners were skipped because their changes are minor, or the reviewer list was getting long. Nothing blocks merge, so self-assign if you'd like a look:

  • @PostHog/batch-exports (products/batch_exports/product.yaml)
  • @PostHog/team-product-analytics (products/product_analytics/product.yaml)

Soft owners come from each directory's owners.yaml and each product's product.yaml (resolved nearest-file-wins). For a skipped owner, the locator is the file that decided it. Generated files and lockfiles are ignored when deciding ownership.

@vdekrijger vdekrijger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Inline review comments.

Comment thread posthog/api/team/query_modifiers.py Resolved
Comment thread posthog/clickhouse/client/execute.py Resolved

@vdekrijger vdekrijger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

Nice solution 😄 ! Learned some more about the whole query routing flow 🙌 !

@github-project-automation github-project-automation Bot moved this from In Review to Approved in Feature Flags Oct 23, 2026
aspicer and others added 4 commits October 23, 2026 02:09
The cluster check reads CLICKHOUSE_NATIVE_EVENTS_HOST on every query run. The test
base clears the instance setting cache before each test, so the cold read landed
inside assertNumQueries blocks whenever no earlier test had read it within 60s.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
… cluster

Warehouse view refreshes, batch export backfills and HogQL models, and notebook
SQL frames read ClickHouse through an HTTP client that takes a URL, so the
events cluster rule did not reach them. They now get the events cluster's URL,
built from the main cluster's HTTP URL and the host instance setting, whenever
the SQL they printed reads events_json for a listed project.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
The executor prints on its own copy of the shared context, so the flag the
printer sets when it prints events_json never reached the caller's context and
every frame stayed on the offline pool.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
…d modifier

Review follow-ups: the async query task's two overrides read a PINNED_CLUSTER_WORKLOADS
tuple instead of listing LOGS and NEW_EVENTS_CLUSTER twice, and the project settings
validator no longer strips useNewEventsCluster, which no project has stored.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

@sakce sakce left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

all good from data modeling/endpoints pov. lacking context on what this whole thing is - but give me a shout if I can anyhow help to make this work better for Endpoints/Modeling in any way 🙏

The revalidation now pins the events table the stale read resolved into the
query it rebuilds, so on the native table its debounce key carries
useNewEventsSchema. The tests built the key from the unpinned query and
looked up a slot that was never written. The pin and the compare strip now
live in one helper that the enqueue and the tests both call.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk cancel

@aspicer aspicer changed the title feat(hogql): run reads of events_json on the events cluster feat(hogql): staff native-events switch routed to the events cluster Oct 26, 2026
@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk cancel

@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk cancel

The main cluster now runs the same ClickHouse build as the events cluster, so a
query started there reads events_json through its Distributed table without the
version mismatch that made the events cluster route necessary. The route, the
NEW_EVENTS_CLUSTER workload and its pool, and CLICKHOUSE_NATIVE_EVENTS_HOST go.
Cancellation reaches native reads again.

The staff switch, the per-table cache keys and precompute identities, and the
revalidation pins stay. A read of events_json still skips the preaggregated web
tables, because those are built from the legacy events table.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@aspicer aspicer changed the title feat(hogql): staff native-events switch routed to the events cluster feat(hogql): staff switch for the native events table Oct 26, 2026
@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

…s table

A read of events_json now skips the preaggregated web tables, so on the
native-schema CI lane these tests saw the untransformed query. They exercise
the transform, so they read the legacy table in every lane, and the routing
tests check that only a legacy read uses those tables.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@aspicer

aspicer commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

@trunk-io

trunk-io Bot commented Oct 26, 2026

Copy link
Copy Markdown

This PR is already queued as a stacked merge. Cancel it first to re-submit.

@trunk-io
trunk-io Bot merged commit d282569 into master Oct 26, 2026
315 checks passed
@trunk-io
trunk-io Bot deleted the aspicer/events-cluster-route branch October 26, 2026 20:02
@github-project-automation github-project-automation Bot moved this from Approved to Done in Feature Flags Oct 26, 2026
@deployment-status-posthog

deployment-status-posthog Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-10-26 20:33 UTC Run
prod-us ✅ Deployed 2026-10-26 20:51 UTC Run
prod-eu ✅ Deployed 2026-10-26 20:51 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants