Skip to content

perf: CPU optimization for log ingestion pipeline - #3

Merged
rukh-debug merged 5 commits into
mainfrom
optimize/cpu-hotspots
Apr 17, 2026
Merged

perf: CPU optimization for log ingestion pipeline#3
rukh-debug merged 5 commits into
mainfrom
optimize/cpu-hotspots

Conversation

@rukh-debug

@rukh-debug rukh-debug commented Apr 17, 2026

Copy link
Copy Markdown
Owner

Summary

3-phase CPU optimization for the log ingestion pipeline — reduces DB operations by 10-50x during active SSE streaming.

Phase 1: SSE Batching

  • New LogBuffer class accumulates SSE messages, flushes every 2s or 50 logs
  • Profile state updates throttled from per-log to every 10s

Phase 2: Hash & Dedup Cache

  • buildEventHash() uses fast field concatenation instead of JSON.stringify
  • New in-memory DedupCache (10K entries/profile) — O(1) lookup, skips DB dedup queries for known hashes

Phase 3: Batch Device Upserts + Poller Reduction

  • Device updates: single INSERT ... ON CONFLICT UPDATE per batch instead of N individual queries
  • Poller default interval: 30s → 300s (SSE is primary, poller is fallback)

Files Changed

  • src/lib/ingestion/log-buffer.ts (new)
  • src/lib/ingestion/dedup-cache.ts (new)
  • src/lib/ingestion/sse-streamer.ts
  • src/lib/ingestion/log-processor.ts
  • src/lib/ingestion/ingestion-manager.ts
  • CHANGELOG.md (new)

Test Plan

  • TypeScript compiles clean (tsc --noEmit)
  • Deploy and monitor CPU usage under active SSE traffic
  • Verify no log loss or duplicates in production
  • Confirm webhooks still fire for new devices and flagged logs

Phase 1 of CPU optimization. SSE stream previously called processLogBatch
for every single incoming message, causing massive DB overhead. Now:

- New LogBuffer class accumulates SSE messages
- Flushes every 2 seconds or at 50 logs (whichever first)
- Force-flush at 500 logs (overflow protection)
- Profile state updates throttled to 10s intervals
- Removes per-log DB read-then-write for profile state
- Expected 10-50x reduction in DB ops for SSE-sourced logs
Phase 2 of CPU optimization:

- buildEventHash: replace JSON.stringify(fullObject) with fast field
  concatenation using pipe-delimited stable fields — avoids serializing
  the entire log object structure
- New DedupCache: in-memory LRU Set per profile (10K entries)
  - O(1) Set membership check before hitting DB
  - Only queries DB for hashes not in cache (near-zero DB dedup
    queries for active streams)
  - Auto-evicts oldest entries when over capacity
  - Safe: empty cache on restart falls back to DB queries
Phase 3 of CPU optimization:

- Device upserts: replaced per-device individual UPDATE/INSERT loop with
  single batch INSERT ... ON CONFLICT UPDATE using SQL expressions.
  Uses COALESCE(NULLIF(...)) to preserve existing non-null values and
  GREATEST() for lastSeenAt. Reduces N DB queries per batch to 1.
- Poller interval: increased default from 30s to 300s (5 minutes).
  SSE stream now provides real-time data; poller serves as fallback
  safety-net only. Users can override via POLL_INTERVAL_SECONDS env var.
@rukh-debug
rukh-debug merged commit c1abe62 into main Apr 17, 2026
1 check passed
@rukh-debug
rukh-debug deleted the optimize/cpu-hotspots branch April 17, 2026 00:42
github-actions Bot pushed a commit that referenced this pull request Apr 18, 2026
## 1.0.0 (2026-04-18)

### Features

* add activity detection and profile management services ([d9ba5fa](d9ba5fa))
* add alert system with auto-tagging and webhook notifications ([b687b37](b687b37))
* add application layout with sidebar navigation and switchers ([7fabee1](7fabee1))
* add brand logo/favicon and use across sidebar, layout, and README ([97639b2](97639b2))
* add dashboard overview widgets and stat cards ([c2c1470](c2c1470))
* add dashboard pages for all application views ([93ab668](93ab668))
* add database layer with Drizzle ORM and PostgreSQL schema ([7dff5ad](7dff5ad))
* add DNS log ingestion engine with real-time processing ([10f7e97](10f7e97))
* add NextDNS API client, types, and core utilities ([b100338](b100338))
* add REST API routes for all application endpoints ([40e6262](40e6262))
* add reusable chart components for data visualization ([e9c9b82](e9c9b82))
* add root layout and global stylesheet ([2884fc2](2884fc2))
* add semantic-release for automated versioning and changelogs ([3b52bc2](3b52bc2))
* add session-based authentication with login/logout flow ([0b8f826](0b8f826))
* add shadcn/ui component library primitives ([290d9a5](290d9a5))
* add Zustand dashboard store for client-side state ([444021a](444021a))

### Bug Fixes

* add loading states and cursor-pointer to all dashboard pages ([7d0d013](7d0d013))
* address PR review feedback for semantic-release setup ([245628a](245628a))
* **ci:** add Node.js 22 for semantic-release compatibility ([02b21ee](02b21ee))
* correct DATABASE_URL port and host in .env.example ([8677a22](8677a22))
* create .next/cache dir with correct ownership for non-root user ([97a0b16](97a0b16))
* improve UX with cursor pointer on interactive elements and delete loading state ([e1d03fa](e1d03fa))
* point dashboard empty state to /profiles instead of non-existent /settings ([eff8d0c](eff8d0c))
* prevent pino-pretty crash in Docker standalone builds ([d01f5f7](d01f5f7)), closes [#4](#4)
* sync bun.lock with package.json ([f4f0c2a](f4f0c2a))
* trigger docker workflow on semantic-release tags ([d0638af](d0638af))

### Performance Improvements

* CPU optimization for log ingestion pipeline ([#3](#3)) ([c1abe62](c1abe62))
Repository owner deleted a comment from github-actions Bot Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant