nano SIEM
Settings

Search Concurrency

Configure search query admission control, per-user limits, and ClickHouse resource settings

Search Concurrency

nano includes an admission controller that manages concurrent search queries. This prevents any single analyst from monopolizing ClickHouse resources and ensures detection rules always have priority over ad-hoc searches.

Overview

Without concurrency limits, a single analyst running many heavy threat-hunting queries could starve detection rules and other analysts of resources. The admission controller solves this with:

  • Priority-based scheduling — Detection rules bypass the queue entirely
  • Per-user limits — No single analyst can consume all available query slots
  • Global limits — Total concurrent ad-hoc queries are capped
  • Queue with timeout — When limits are hit, queries wait in a priority queue rather than failing immediately
  • Per-query resource limits — ClickHouse settings (timeout, memory, threads) are applied per priority tier

Priority Levels

Queries are assigned a priority that determines their scheduling behavior:

PriorityLevelQueue BehaviorUse Case
Detection0 (highest)Bypasses queue, always runsScheduled detection rules
Near-Realtime1Bypasses queue, always runsReal-time materialized view rules
Interactive2Subject to limits, queued if fullAnalyst searches in the Search page
Analytics3 (lowest)Subject to limits, queued if fullLong-running threat hunting

Detection and Near-Realtime queries are never queued — they always execute immediately. This guarantees that detection rules are never delayed by analyst activity.

Concurrency Limits

These settings control how many ad-hoc queries (Interactive + Analytics) can run simultaneously:

SettingDefaultRangeDescription
Global ad-hoc limit301–500Maximum concurrent ad-hoc queries across all users
Per-user limit51–50Maximum concurrent queries per individual user
Max queue depth10010–1,000Maximum number of queries waiting in the queue
Queue timeout120s10–600sHow long a query waits before being rejected

When the global limit is reached, new queries enter a priority queue. If the queue is also full, the query is rejected with a QueueFull error. If a queued query waits longer than the timeout, it is rejected with a QueueTimeout error.

How the queue works

  1. A new search request arrives
  2. The admission controller checks the per-user limit — if exceeded, the request is rejected
  3. If the global limit has capacity, the query starts immediately
  4. If the global limit is full, the query enters the priority queue (ordered by priority level, then arrival time)
  5. When a running query completes, the next queued query (highest priority first) is started
  6. If the queue timeout expires before a slot opens, the query is rejected

ClickHouse Resource Settings

Each priority tier has configurable ClickHouse query settings. These are applied per-query via HTTP parameters — no ClickHouse-side profile setup is needed.

SettingDetectionNRTInteractiveAnalyticsDescription
max_execution_time30s30s300s3600sQuery timeout in ClickHouse
max_memory_usage5 GB5 GB20 GB50 GBPer-query memory cap
max_threads881632Parallel execution threads
priority1135ClickHouse scheduler priority (1 = highest)
queue_max_wait_ms5s5s60s120sClickHouse-side queue timeout

The Interactive, Analytics, and Realtime tiers are configurable via Settings > Search Concurrency. Detection and NRT settings use the Realtime tier values.

Configuration

Settings UI

Navigate to Settings > Search Concurrency to adjust limits. Changes take effect immediately — no restart required.

The settings page has two sections:

  1. Concurrency Limits — Global and per-user query limits, queue depth, timeout
  2. ClickHouse Resource Limits — Per-priority-tier execution time and memory caps

Environment Variables

Environment variables serve as startup defaults. Once the system boots, admin settings from the database override these:

VariableDefaultDescription
SEARCH_GLOBAL_ADHOC_LIMIT30Initial global ad-hoc limit
SEARCH_PER_USER_LIMIT5Initial per-user limit
SEARCH_MAX_QUEUE_DEPTH100Initial max queue depth
SEARCH_QUEUE_TIMEOUT_MS120000Initial queue timeout (ms)

Queue Behavior in the UI

When a search is queued, the Search page shows:

  • A clock icon with "Search queued — Position N in queue"
  • An estimated wait time (based on average recent query duration)
  • A cancel button to remove the search from the queue

When the search moves from queued to running, the UI transitions to the standard progress bar with rows scanned.

Active Searches Panel

The Search page includes a collapsible Active Searches panel that shows all your current and recent searches. From this panel you can:

  • See the status of each search (queued, running, completed, failed)
  • Cancel queued or running searches
  • Click completed searches to load their results

Notifications

When an async search completes or fails, you receive a notification in the bell icon:

  • Search completed — Shows result count, click to load results
  • Search failed — Shows error message

Monitoring

The admission controller exposes stats via the search jobs API:

GET /api/search/jobs

Returns your active and recent search jobs with status, queue position, and elapsed time.

  • Query Safety Limits — Per-query OOM protection settings (array aggregation caps, mvexpand limits, cost analysis enforcement)
On this page

On this page