Skip to content

feat(web-analytics): widen warming to min-2 shapes and parallelize the warm pass#73013

Merged
lricoy merged 3 commits into
masterfrom
lricoy/warming-min2-parallel
Jul 23, 2026
Merged

feat(web-analytics): widen warming to min-2 shapes and parallelize the warm pass#73013
lricoy merged 3 commits into
masterfrom
lricoy/warming-min2-parallel

Conversation

@lricoy

@lricoy lricoy commented Jul 22, 2026

Copy link
Copy Markdown
Member

Problem

Two follow-ups to the demand-driven warmer now that #72959 made misses harmless (live serve + warm-behind):

  1. The selection threshold (10 runs in 2 days) warms only ~1.3k shapes across ~214 teams. Measured against production traffic, dropping the floor to 2 runs covers ~29k shapes across ~4k teams — every shape a user actually came back to — and with serve-live-warm-behind the only cost of a broader net is background compute, while every extra warmed shape converts a future live serve into a bucket read.
  2. warm_queries_op processes shapes strictly sequentially. At the widened selection size a cold pass would take hours; the pass is IO-bound, so a small thread pool cuts wall time ~8x.

Changes

  • WEB_ANALYTICS_WARMING_MIN_QUERY_COUNT default 10 → 2 and WEB_ANALYTICS_WARMING_MAX_SHAPES 20000 → 40000 (sized above the ~29k the min-2 selection produces so the cap doesn't silently truncate). Code defaults, not instance-setting flips — both remain tunable via instance settings.
  • warm_queries_op runs shapes through a ThreadPoolExecutor (8 workers, mirroring the eager warmer's pool pattern): teams prefetched in one query, per-shape outcomes aggregated from the pool, close_old_connections() per task.
  • Query tagging moved inside the worker: tags are thread-local, and tagging in the op thread would silently strip the background-warming identity from every replay — breaking both the lazy gate's rollout bypass (buckets stop building for non-enrolled teams) and the selection's self-feedback exclusion. This is the failure mode behind the eager warmer's known sync_execute called with missing query tags warnings.

How did you test this code?

pytest products/web_analytics/dags/tests/test_cache_warming.py (28 passed). New test: worker threads observe is_background_warming_request() == True — catches the thread-local-tags regression above, which no existing test covered (the old sequential op tagged in the op thread and happened to work).

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Claude Code session; Lucas asked for the min-2 default (in code, not instance-setting flips) and the warm-pass parallelization after #72959 removed the inline-build risk. Concurrency of 8 chosen to stay well under the OFFLINE per-user query-slot budget; the eager warmer's ThreadPoolExecutor pattern (contained worker exceptions, connection hygiene) was reused, with the thread-local tagging bug it exhibits fixed here rather than inherited. Commit is unsigned: the GPG signing agent was unavailable in this session.

@lricoy lricoy self-assigned this Jul 22, 2026
@trunk-io

trunk-io Bot commented Jul 22, 2026

Copy link
Copy Markdown

😎 This pull request was merged.

@lricoy
lricoy marked this pull request as ready for review July 22, 2026 21:41
@lricoy
lricoy requested a review from a team July 22, 2026 21:42
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
products/web_analytics/dags/cache_warming.py:356
**Worker Tags Leak Between Shapes**

Executor threads are reused, and `tag_queries()` updates the current tag set rather than replacing it. After one runner adds fields such as its cache key, query name, or execution mode, the next task on that thread retains those fields until it overwrites them, so setup queries for the next shape can be logged with metadata from the previous shape.

### Issue 2 of 3
products/web_analytics/dags/cache_warming.py:382
**Failure Logging Is Concurrent**

When several shapes fail together, multiple workers call the shared Dagster `context.log` concurrently. The sibling eager warmer serializes this logger because it is not guaranteed to be thread-safe; this path can therefore lose failure records or raise another logging error while handling the original exception.

### Issue 3 of 3
products/web_analytics/dags/cache_warming.py:369-378
**Duplicate Cache Keys Warm Concurrently**

The selection groups by raw JSON text, while the runner derives its cache key from parsed query data. If two differently encoded rows normalize to the same team and cache key, separate workers can both observe a missing or stale entry and replay the same query concurrently, wasting ClickHouse capacity and recording duplicate warmed outcomes.

Reviews (1): Last reviewed commit: "feat(web-analytics): widen warming to mi..." | Re-trigger Greptile

Comment thread products/web_analytics/dags/cache_warming.py
Comment thread products/web_analytics/dags/cache_warming.py Outdated
Comment thread products/web_analytics/dags/cache_warming.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 982c67364e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread products/web_analytics/dags/cache_warming.py
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Playwright — all passed

All tests passed.

View test results →

⚠️ Backend snapshots — 11 updated (11 modified, 0 added, 0 deleted)

Query snapshots: Backend query snapshots updated

Changes: 11 snapshots (11 modified, 0 added, 0 deleted)

What this means:

  • Query snapshots have been automatically updated to match current output
  • These changes reflect modifications to database queries or schema

Next steps:

  • Review the query changes to ensure they're intentional
  • If unexpected, investigate what caused the query to change

Review snapshot changes →

@lricoy
lricoy force-pushed the lricoy/warming-min2-parallel branch from d17f1a6 to 7062309 Compare July 23, 2026 00:05
@lricoy
lricoy force-pushed the lricoy/warming-min2-parallel branch from 7062309 to 5a14b48 Compare July 23, 2026 00:06
Comment thread posthog/settings/dynamic_settings.py
@veria-ai

veria-ai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 1 · PR risk: 0/10

@lricoy
lricoy enabled auto-merge (squash) July 23, 2026 00:29
@lricoy lricoy added the stamphog Request AI approval (no full review) label Jul 23, 2026
Comment thread products/web_analytics/dags/cache_warming.py

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This touches background query-warming compute (selection threshold, cache-key dedup, concurrency), but the author owns this code (STRONG familiarity, same-team), and every substantive reviewer concern (tag leak, concurrent logging, amplification risk, duplicate-key replay) is verifiably fixed in the diff and covered by new tests; the one remaining unresolved comment is a metrics double-counting edge case with no runtime or data-safety impact.

  • Author wrote 84% of the modified lines and has 56 merged PRs in these paths (familiarity STRONG).
  • 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
  • Unresolved @graphite-app comment: duplicate-cache-key check runs after the raw-low-demand check, so two duplicate raw-path low-demand shapes both increment skipped_raw_low_demand instead of one being labeled skipped_duplicate — a metrics-accuracy nit only (no query is replayed twice, no data impact), worth a quick follow-up fix.
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 171L, 2F substantive, 304L/3F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1d-complex (304L, 3F, two-areas, feat)
stamphog 2.0.0b3 .stamphog/policy.yml @ cc5cfb1 · reviewed head 4b89f42

@lricoy
lricoy merged commit 0797905 into master Jul 23, 2026
310 of 325 checks passed
@lricoy
lricoy deleted the lricoy/warming-min2-parallel branch July 23, 2026 01:05
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-23 01:36 UTC Run
prod-us ✅ Deployed 2026-07-23 01:54 UTC Run
prod-eu ✅ Deployed 2026-07-23 01:53 UTC Run

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

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant