perf(db): explicit column list in profile-buffer CH fetch (drop SELECT *) - #377
Open
ayushjhanwar-png wants to merge 3 commits into
Open
perf(db): explicit column list in profile-buffer CH fetch (drop SELECT *)#377ayushjhanwar-png wants to merge 3 commits into
ayushjhanwar-png wants to merge 3 commits into
Conversation
Prevents OOM on Aiven CH (43GB per-query cap) hit by the device_first_seen aggregation + two large anti-joins. Aggregation + sort buffers spill to disk if they exceed limits. Correctness unchanged. Tested against prod CH: 12k candidates in 14s (same as baseline).
07-06 sequential single-INSERT at threads=6 took 7h 17m for a 157M-event day. The old 5h ceiling would abort any full-day run that hits normal load. 10h gives cushion for peak-traffic days while still bounding runaway queries.
…r CH fetch The profile-buffer's fetchFromClickhouse is called per event when Redis cache misses. Under peak load (~25K events/min through /track), a small per-query cost multiplies. SELECT * loaded materialized columns (os, campaign, quotaPlan) that are unused downstream and re-serialized the full row over the wire on every miss. Restricting to the columns actually consumed by mergeProfiles + cache write shaves payload size and skips materialized-column read cost with zero behavior change. No schema change, no flow change, no caller-visible change.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe profile buffer’s ClickHouse query now selects only the profile columns used by the application, replacing ChangesProfile query optimization
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces `SELECT *` with an explicit column list in `profile-buffer.ts` `fetchFromClickhouse`.
Why
This query fires per-event during /track ingestion when the Redis profile cache misses. At ~25K events/min steady load, the per-query cost multiplies.
`SELECT *` currently loads:
The explicit column list keeps everything downstream uses (`id, project_id, first_name, last_name, email, avatar, is_external, properties, created_at`) and drops the materialized-column reads plus their serialization cost.
Context — today's /track 5xx spike (2026-07-16 06:41 UTC)
Post-backfill cluster contention slowed profile queries from ~50ms to 15-20s each. With per-event lookups at 25K/min, concurrent queries ballooned past ClickHouse's `max_concurrent_queries=447` cap on replica -37 → INSERTs rejected with Code 202 → API returned 5xx to /track.
This PR is a small step toward reducing per-query cost. It does NOT fix the underlying architecture (per-event lookup vs batched). Full upstream port to batch fetch is planned as a separate PR.
Follow-ups (separate PRs)
Test plan
Summary by CodeRabbit