Skip to main content
Snort 3 is designed for high-throughput environments. This page covers the tools and options available to measure what is happening, identify bottlenecks, and tune your deployment.

Performance monitor

The perf_monitor module captures peg counts from Snort modules at runtime and at regular intervals, without requiring a restart. This is useful for feeding data to external dashboards or spotting issues while Snort is running.

Trackers

perf_monitor includes several independent trackers you can enable in any combination.
Captures running statistics from all Snort modules. Stats cover the interval since the last report and are reset at the start of each interval — the same counts you see at shutdown, broken down by time window.Enable everything:
perf_monitor = { modules = {} }
Enable all counters for a specific module:
perf_monitor =
{
    modules =
    {
        {
            name = 'stream_tcp',
            pegs = [[ ]]
        },
    }
}
Enable specific counters within a module:
perf_monitor =
{
    modules =
    {
        {
            name = 'stream_tcp',
            pegs = [[ overlaps gaps ]]
        },
    }
}
Event statistics from Snort 2’s perfmonitor are now located within base statistics.
Tracks statistics about traffic volume and L3/L4 protocol distributions. Use this to build a traffic profile for inspector tuning and to identify where Snort may be under load.
perf_monitor = { flow = true }
Provides statistics for individual hosts: how much data they generate, how many sessions they open, and typical packet sizes. Useful for identifying unusual communication habits.
perf_monitor = { flow_ip = true }
Monitors CPU time and wall time spent by each processing thread.
perf_monitor = { cpu = true }

Output formats

perf_monitor can produce output in human-readable text (the same format as the shutdown summary), CSV, or JSON. JSON output is well-suited for feeding into external tools.

Profiler module

The profiler module tracks time and memory usage per module and per rule. Its output appears under Summary Statistics at shutdown. Enable module and rule profiling in snort.lua:
profiler =
{
    modules = { show = true },
    rules = { show = true }
}

Reading profiler output

At shutdown, the profiler prints a table sorted by time consumed. Each row shows:
  • Module or rule name
  • Checks — how many times it was invoked
  • Time (usec) — total microseconds spent
  • Avg (usec) — average per invocation
Rules with high check counts but low hit rates are candidates for optimization — either by adding fast patterns or tightening the rule’s match criteria.
Run the profiler on representative traffic before tuning. Profiling adds a small overhead, so disable it in production once you have identified bottlenecks.

Pattern matching

Snort’s fast pattern matching engine determines how quickly rules are evaluated against packet data. The engine is selected via search_engine.search_method in snort.lua.
MethodDescription
ac_bnfaDefault. Aho-Corasick with a compact NFA. Balances speed and memory.
ac_fullFull Aho-Corasick with a full transition table. Faster than ac_bnfa but uses significantly more memory.
hyperscanIntel Hyperscan. Best performance. Requires Snort to be built with Hyperscan support.
Example — switch to ac_full:
search_engine = { search_method = 'ac_full' }
Example — use Hyperscan (if available):
search_engine = { search_method = 'hyperscan' }
Hyperscan is also used by the regex and sd_pattern rule options. Build Snort with --enable-hyperscan and install Hyperscan >= 4.4.0 to enable it.

Multi-threading

Snort 3 can process multiple input sources simultaneously using packet threads. Each thread runs an independent copy of the detection pipeline. Set the maximum number of packet threads with -z or --max-packet-threads:
# Process a pcap directory with up to 8 concurrent threads
snort -c snort.lua --pcap-dir /path/to/pcap/dir \
    --pcap-filter '*.pcap' --max-packet-threads 8

# Monitor two live interfaces, one thread each
snort -c snort.lua -i "eth0 eth1" -z 2 -A cmg
Start with the number of physical cores available for packet processing. Use perf_monitor with the CPU tracker to see if threads are being saturated before adding more.

Thread assignment for pcap files

  • Snort starts up to -z threads to process files.
  • As a thread finishes a file, it picks up the next unprocessed one.
  • If there are fewer files than threads, fewer threads are started.

Thread assignment for live interfaces

  • All threads up to -z are always started.
  • With multiple interface inputs, each thread receives one ordinally, falling back to the first if threads outnumber inputs.

Memory optimization

Snort 3 has a more scalable memory profile than Snort 2. Some knobs that affect memory usage: Session timeout (stream_tcp.session_timeout): Shorter timeouts allow Snort to reclaim session state sooner, reducing memory consumption in high-connection-rate environments.
stream_tcp = { session_timeout = 60 }
Snaplen (daq.snaplen): Reducing the capture length lowers the per-packet buffer size. The default is 1518 bytes.
daq = { snaplen = 1518 }
perf_monitor counters: Enable only the trackers and counters you need. Enabling everything for all modules increases memory overhead.

Reload without restart

You can reload a modified snort.lua without stopping Snort by sending SIGHUP:
# Edit the config, then reload
echo 'suppress = { { gid = 1, sid = 2215 } }' >> snort.lua
kill -hup <pid>

Parameters that require a restart

Some parameters cannot be changed during a reload. If you change any of the following, Snort will reject the reload with reload failed - restart required and continue using the original config.
  • active.attempts
  • active.device
  • alerts.detection_filter_memcap
  • alerts.event_filter_memcap
  • alerts.rate_filter_memcap
  • attribute_table.max_hosts
  • attribute_table.max_services_per_host
  • daq.snaplen
  • file_inspect.max_files_cached
  • process.chroot
  • process.daemon
  • process.set_gid
  • process.set_uid
  • snort.--bpf
  • snort.-l
  • trace.output
  • Enabling file capture for the first time
  • Changing file_inspect.capture_memcap if file capture was previously or currently enabled
  • Changing file_inspect.capture_block_size if file capture was previously or currently enabled
  • Adding or removing stream_* inspectors when stream was already configured

Latency monitoring

The latency module enforces time limits on packet and flow processing. When a limit is exceeded, Snort can drop the packet or disable further inspection on the flow. Enable latency monitoring in snort.lua:
latency =
{
    packet = { max_time = 500, action = 'log' },
    flow = { max_time = 10000, action = 'log' }
}
  • packet.max_time — maximum microseconds allowed to process a single packet
  • flow.max_time — maximum microseconds allowed for flow-level inspection
  • actionlog to record violations, drop to also drop the offending packet
Use action = 'log' first to measure how often limits are exceeded before switching to drop. This helps you choose appropriate thresholds without disrupting traffic.