Snort sensors lose value when packet drops, slow rule matching, or deep stream queues hide traffic before detection finishes. Performance tuning should start from Snort counters instead of copied settings, because packet source, rule mix, enabled inspectors, and CPU capacity all change where time and memory are spent.

Snort 3 exposes tuning controls as Lua modules and command-line overrides. Operators can benchmark the same controlled pcap or replay traffic twice, test one candidate with --lua, and persist only settings that improve the measured bottleneck without pushing memory beyond the sensor host.

Source-built Snort 3 commonly reads /usr/local/etc/snort/snort.lua. Replace traffic.pcap with the packet capture or replay file used for the baseline, and keep the previous Lua file available so one setting can be rolled back when counters move in the wrong direction.

Steps to tune Snort performance:

  1. Run the baseline traffic without -q.
    $ sudo snort -c /usr/local/etc/snort/snort.lua -r traffic.pcap -k none -A alert_fast
    ##### snipped #####
    search engine (ac_bnfa)
                 memory scale: KB
                 total memory: 71.2812
    ##### snipped #####
    Packet Statistics
    daq
                     received: 4
                     analyzed: 4
    ##### snipped #####
    stream_tcp
                     max_segs: 1
                    max_bytes: 79
    ##### snipped #####
    Summary Statistics
    timing
                      seconds: 0.153688
                     pkts/sec: 26

    Use the same pcap, rule files, alert logger, checksum mode, and DAQ path for later runs. Different inputs make the counters hard to compare.
    Related: How to read Snort run statistics

  2. List the search-engine methods compiled into the sensor.
    $ snort --help-module search_engine
    ##### snipped #####
    dynamic search_engine.search_method = ac_bnfa: set fast pattern algorithm - choose available search engine { ac_bnfa | ac_full }
    dynamic search_engine.offload_search_method: set fast pattern offload algorithm - choose available search engine { ac_bnfa | ac_full }
    ##### snipped #####
    Peg counts:
     
    search_engine.max_queued: maximum fast pattern matches queued for further evaluation (max)
    search_engine.total_overruns: fast pattern matches discarded due to overflow (sum)
    search_engine.qualified_events: total qualified events (sum)
  3. Test one search-engine candidate without editing the persistent file.
    $ sudo snort -c /usr/local/etc/snort/snort.lua -r traffic.pcap -k none -A alert_fast \
        --lua 'search_engine.search_method = "ac_full"'
    ##### snipped #####
    search engine (ac_full)
               storage format: full
                 memory scale: KB
                 total memory: 1018.64
    ##### snipped #####
    Summary Statistics
    timing
                      seconds: 0.032013
                     pkts/sec: 125

    ac_full used substantially more matcher memory than ac_bnfa in the validated fixture. Keep it only when repeated tests on the real rule set improve drops, overruns, or runtime enough to justify the memory cost.

  4. Inspect the stream_tcp queue defaults before raising reassembly memory.
    $ snort --help-config stream_tcp
    ##### snipped #####
    int stream_tcp.queue_limit.max_bytes = 4194304: don't queue more than given bytes per session and direction, 0 = unlimited { 0:max32 }
    int stream_tcp.queue_limit.max_segments = 3072: don't queue more than given segments per session and direction, 0 = unlimited { 0:max32 }
    int stream_tcp.queue_limit.asymmetric_ids_flush_threshold = 3145728: max bytes queued on asymmetric flow before flush in IDS mode { 1:max31 }
    ##### snipped #####
  5. Open the active Snort Lua configuration.
    $ sudoedit /usr/local/etc/snort/snort.lua
  6. Persist the search-engine method that won the repeated test.
    search_engine =
    {
        search_method = 'ac_full'
    }

    Use only a method listed by snort –help-module search_engine on that sensor. A build with different libraries can expose a different method list.

  7. Raise stream_tcp queue limits only when stream counters show queue pressure.
    stream_tcp =
    {
        queue_limit =
        {
            max_bytes = 8388608,
            max_segments = 4096
        }
    }

    If the active stream_tcp block already sets other fields, merge queue_limit into that block instead of replacing the existing policy, timeout, or reassembly settings.

  8. Enable perf_monitor for recurring comparison data.
    perf_monitor =
    {
        packets = 10000,
        seconds = 60,
        output = 'file',
        format = 'csv',
        summary = true,
        modules =
        {
            {
                name = 'search_engine',
                pegs = [[ max_queued total_overruns qualified_events ]]
            },
            {
                name = 'stream_tcp',
                pegs = [[ max_segs max_bytes segs_queued ]]
            }
        }
    }

    Set output to console for a short lab run. Use file with csv or json when a long-running sensor needs interval data that can be graphed later.

  9. Validate the tuned configuration before restarting a sensor or replaying traffic.
    $ sudo snort --warn-all -c /usr/local/etc/snort/snort.lua -T
    WARNING: /usr/local/etc/snort/snort.lua: appid: app_detector_dir not configured; no support for appids in rules.
    ##### snipped #####
    search engine (ac_full)
    appid: MaxRss diff: 2688
    appid: patterns loaded: 300
    ##### snipped #####
    Snort successfully validated the configuration (with 1 warnings).

    Review every warning before applying the change. Do not restart a production sensor when a warning points to a tuned module, missing rule file, unsupported DAQ option, or invalid Lua value.

  10. Rerun the same traffic and compare the tuned counters with the baseline.
    $ sudo snort -c /usr/local/etc/snort/snort.lua -r traffic.pcap -k none -A alert_fast
    ##### snipped #####
    search engine (ac_full)
                 memory scale: KB
                 total memory: 1018.64
    ##### snipped #####
    daq
                     received: 4
                     analyzed: 4
    ##### snipped #####
    perf_monitor
                      packets: 4
    stream_tcp
                     max_segs: 1
                    max_bytes: 79
    ##### snipped #####
    timing
                      seconds: 0.027492
                     pkts/sec: 145

    Keep a change only when repeated runs reduce packet drops, search_engine.total_overruns, stream queue pressure, or runtime for the same traffic. Revert one setting at a time when a counter moves in the wrong direction.