OPNsenseXXXV · Performance and State TableIDS performance impact
IDS performance impact — what Suricata costs and how to keep it from breaking the firewall
What you'll learn
- Describe the Suricata modes on OPNsense and their CPU cost
- Identify the ruleset factors that determine IDS performance
- Tune Suricata for the deployment — alert-only, IPS, hyperscan, threading
- Recognise the symptoms of IDS saturation — packet drops, alert backlog, latency
- Distinguish IDS-saturation symptoms from firewall-rule or state-table symptoms
Prerequisites
Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14
Suricata IDS on OPNsense is the most expensive optional feature. Every packet that traverses the firewall is mirrored to Suricata; Suricata runs a ruleset of tens of thousands of signatures against each packet; matched packets generate alerts or trigger drop actions. The cost can dominate the firewall’s CPU budget, drop packets at high traffic rates, and produce a queue of unprocessed packets that grows until the firewall itself becomes the bottleneck.
This lesson covers the Suricata modes on OPNsense, the ruleset factors that determine performance, the threading model, the symptoms of saturation, and the discipline of running IDS without breaking throughput.
The Suricata modes
OPNsense runs Suricata in three modes:
- IDS mode (alert only). Suricata receives a copy of each packet via netmap, evaluates rules, and logs alerts. The original packet is forwarded by PF normally. The firewall’s throughput is unaffected — but every packet costs Suricata CPU.
- IPS mode (inline). Suricata sits inline in the packet path. PF sends packets to Suricata via netmap; Suricata evaluates rules and decides whether to forward or drop. The firewall’s throughput is capped by Suricata’s packet-rate.
- Legacy netmap IDS. Older configuration mode that uses netmap for packet capture. Largely superseded by the modern IPS/IDS modes.
The most common production setup is IDS mode — alert on suspicious traffic without affecting throughput. The trade-off is that IDS alerts are advisory; the firewall does not block based on them. For blocking traffic, IPS mode is required — but at the cost of throughput.
The ruleset factors
The Suricata ruleset is the dominant performance variable. A deployment with 1,000 enabled rules performs dramatically differently from one with 50,000 rules. The factors:
- Number of rules. Every rule is evaluated per packet (with some short-circuiting when earlier rules match). A rule count of 30,000 to 50,000 is typical for the ETOpen ruleset.
- Rule complexity. Rules with multiple patterns, multiple flags, or content modifiers (e.g.
http_uri,tls_sni) cost more per evaluation than simple IP/port matches. - Flowbits. Rules that set or check flowbits create dependencies between rules. A rule that sets a flowbit that 50 other rules check forces those 50 rules to evaluate even if the flowbit is not set.
- Preprocessor activity. Suricata’s protocol parsers (HTTP, TLS, DNS, SMB, etc.) reconstruct streams and may buffer data. High protocol diversity costs more.
The discipline is to start with a small, focused ruleset and add rules only when the deployment’s threat model requires them. The ETOpen ruleset is a good baseline; the ETPro ruleset is larger and more aggressive; the Proofpoint Emerging Threats ruleset is similar to ETOpen. Operators should review what they enable.
The threading model
Suricata uses multiple threads:
- Management thread. Coordinates configuration, counters.
- Packet acquisition threads. Read packets from netmap (one per interface).
- Worker threads. Run the detection engine — evaluate rules against each packet.
- Flow worker threads. Track flow state across packets.
- Output threads. Write alerts, logs, and stats to disk.
The number of worker threads is configured in suricata.yaml as threading.detect-thread-ratio. The default is typically 1.5 × the number of CPU cores; the operator can tune this up or down.
$ suricata --build-info | grep -E 'Threads|Detect|Netmap|Hyperscan'Threads: yes
Detect thread ratio: 1.5
Hyperscan: yes
Netmap: yes
NFQueue: yesIllustrative output
The discipline:
- Confirm Hyperscan is built in. The
--build-infooutput should showHyperscan: yes. Without Hyperscan, pattern matching is 5-10x slower. - Tune
detect-thread-ratiofor the deployment. A ratio of 1.5 uses 1.5 cores’ worth of worker threads; on a 4-core deployment, that’s 6 worker threads. Tune up for higher packet rates; tune down for lower memory. - Pin threads to cores with
cpusetto avoid contention with PF and other daemons.
Symptoms of IDS saturation
The signatures of Suricata saturation:
- Packet drops reported by Suricata. The
capture.kernel_dropscounter in Suricata’s stats is non-zero. - Alert backlog. The
alert_queueis full; alerts are dropped before being written. - High CPU on Suricata threads. The worker threads are at 100% WCPU in
top. - Latency in PF forwarding. In IPS mode, packets queue while Suricata processes; latency rises.
- Lower-than-expected throughput. In IPS mode, the firewall’s pps is well below the expected rate.
The capture.kernel_drops counter is the canary:
$ curl -s http://127.0.0.1:9911/ 2>/dev/null | grep -E 'capture|kernel_drop|alert_queue' | head -10"capture.kernel_packets": 12345678,
"capture.kernel_drops": 12345,
"capture.kernel_ifdrops": 0,
"alert_queue.maxsize": 65536,
"alert_queue.current": 1234,
"alert_queue.dropped": 0Illustrative output
Tuning for performance
The levers:
- Reduce the ruleset. Disable unused rules. The ETOpen ruleset has categories; the operator should disable categories irrelevant to the deployment.
- Tune
detect-thread-ratio. More threads = more parallelism but more memory. - Use hyperscan. Confirm it is built in. Some custom rules use PCRE; hyperscan does not accelerate PCRE — convert to hyperscan-compatible patterns where possible.
- Reduce logging. Every alert is written to disk; verbose logging on a busy network saturates disk I/O. Tune to log only what the operator will read.
- Use AF_PACKET or netmap efficiently. In OPNsense, netmap is the default; confirm the ring sizes are tuned for the packet rate.
- Tune flow timeouts. Short flow timeouts reduce memory pressure; long timeouts increase state.
Distinguishing from other symptoms
The operator must distinguish IDS saturation from other saturation symptoms:
| Symptom | Cause |
|---|---|
| Suricata kernel_drops rising | IDS saturation |
| Suricata CPU at 100%, PF CPU moderate | IDS saturation |
| PF CPU at 100%, Suricata moderate | Packet-rate saturation on PF |
| All CPU at moderate levels, bps low | Link saturation or upstream issue |
| All CPU moderate, latency high | State table exhaustion or DNS issue |
The cross-reference between Suricata stats and PF performance is the key. A deployment with rising Suricata drops and steady PF performance is IDS-bound; one with rising PF idrops and steady Suricata is PF-bound.
The deployment pattern
A typical production deployment:
- Start with a small ruleset. Enable ETOpen categories relevant to the deployment (e.g. emerging-dos, emerging-web-server, emerging-malware). Disable the rest.
- Run in IDS mode initially. Confirm throughput is acceptable before switching to IPS.
- Monitor the canary metrics. Graph
capture.kernel_drops,alert_queue.dropped, and Suricata CPU. - Tune as the workload grows. Add rules when the threat model requires them; tune threading when packet rate grows.
- Switch to IPS only when blocking is required. Have a rollback plan in case the IPS introduces problems.
Summary
- Suricata IDS runs as a parallel process receiving mirrored packets via netmap; its CPU cost is the dominant performance variable.
- The ruleset (size, complexity, PCRE use) determines per-packet cost.
- Hyperscan accelerates pattern matching 5-10x; confirm it is built in.
- The canary metrics are
capture.kernel_dropsandalert_queue.dropped— non-zero indicates saturation. - IDS mode is the default because a Suricata crash in IDS mode drops alerts only; a crash in IPS mode drops the entire firewall.
- Tune the ruleset, threading, and logging; measure with the actual workload.
Knowledge check · 4 questions
Q1. Suricata is running in IDS mode on an OPNsense firewall. The capture.kernel_drops counter is rising. PF CPU is moderate. What is the most likely diagnosis?
Q2. Running Suricata in IPS mode is safer than IDS mode because it blocks malicious traffic inline.
Q3. Which of the following are tuning levers for Suricata performance? Select all that apply.
Q4. A signature uses PCRE with backreferences. Suricata is built with Hyperscan. What happens?
Passing score: 75%. Answers are checked in this browser.