Skip to content

feat: auto-detect exact hostname filter for faster queries#152

Open
trieloff wants to merge 1 commit intomainfrom
hostname-filter-performance
Open

feat: auto-detect exact hostname filter for faster queries#152
trieloff wants to merge 1 commit intomainfrom
hostname-filter-performance

Conversation

@trieloff
Copy link
Copy Markdown
Contributor

Summary

Auto-detect whether the hostname filter input is a complete hostname (e.g. www.adobe.com) or a partial pattern (e.g. adobe), and use exact = match on request.host instead of LIKE '%…%' when appropriate.

Changes:

  • Added isExactHostname() heuristic in js/time.js — detects valid hostnames (has dot, valid chars, no wildcards)
  • Updated getHostFilter() to use = on request.host for exact matches (primary key benefit), keeping LIKE on x_forwarded_host (comma-separated values)
  • Added hostFilterExact to state and URL serialization (domainExact=1 param)
  • Added visual "exact"/"partial" indicator badge next to the filter input in all 3 dashboards
  • Benchmarked: 0-45% speedup on exact match queries (best on longer time ranges)

Testing Done

  • npm run lint — passes (0 errors)
  • npm test — 785/785 tests pass, 95.82% coverage
  • New tests for isExactHostname() covering edge cases (dots, wildcards, trailing dots, etc.)
  • New tests for exact-mode getHostFilter() SQL generation
  • New tests for domainExact URL param round-trip
  • Benchmarked against live ClickHouse: LIKE vs exact match across 4 query patterns (1h, 1h breakdown, 6h sampled, 24h sampled)

Checklist

  • Tests pass (npm test)
  • Lint passes (npm run lint)
  • Documentation updated (if applicable)

When the host filter input looks like a complete hostname (has a dot,
valid chars, no wildcards), use exact = on request.host instead of
LIKE '%...%'. This leverages the primary key ordering for faster queries.

Keeps LIKE on x_forwarded_host since it stores comma-separated values.
Adds a visual "exact"/"partial" indicator badge next to the filter input.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Lars Trieloff <lars@trieloff.net>
Copilot AI review requested due to automatic review settings March 13, 2026 15:22
@github-actions
Copy link
Copy Markdown

Preview deployment

Preview is live at: https://klickhaus.aemstatus.net/preview/pr-152/dashboard.html

Updated for commit 60cf2a3

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an auto-detected “exact hostname” mode for the host filter to speed up ClickHouse queries by using request.host = '…' when the filter looks like a full hostname, while keeping LIKE matching for partial patterns and x_forwarded_host.

Changes:

  • Introduces isExactHostname() and uses state.hostFilterExact to choose between exact (=) vs partial (LIKE) host filtering.
  • Persists exact-mode via URL state (domainExact=1) and adds hostFilterExact to global state.
  • Adds a small “exact/partial” badge next to the host filter input across dashboards, plus styling.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
js/time.js Adds hostname heuristic and updates SQL generation to use = for exact matches.
js/state.js Adds hostFilterExact to shared state.
js/url-state.js Serializes/deserializes hostFilterExact via domainExact=1 and auto-detects on load.
js/dashboard-init.js Updates UI to show “exact/partial” badge and sets hostFilterExact on user input.
js/time.test.js Adds tests for isExactHostname() and exact-mode SQL generation.
js/url-state.test.js Adds tests for exact detection on URL load and domainExact round-trip.
dashboard.html / delivery.html / lambda.html Adds the badge element next to the host filter input.
css/layout.css Styles the badge and hides it on mobile.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +96 to +109
function updateHostFilterIndicator(value) {
const badge = elements.hostFilterMode;
if (!badge) return;
if (!value) {
badge.textContent = '';
badge.className = 'filter-mode-badge';
return;
}
const exact = isExactHostname(value);
badge.textContent = exact ? 'exact' : 'partial';
badge.className = exact
? 'filter-mode-badge filter-mode-exact'
: 'filter-mode-badge filter-mode-partial';
}
Comment on lines 403 to 409
elements.hostFilterInput.addEventListener('input', (e) => {
updateHostFilterIndicator(e.target.value);
clearTimeout(filterTimeout);
filterTimeout = setTimeout(() => {
state.hostFilter = e.target.value;
state.hostFilterExact = isExactHostname(state.hostFilter);
saveStateToURL();
Comment on lines +124 to +125
state.hostFilterExact = params.get('domainExact') === '1'
|| isExactHostname(state.hostFilter);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants