Skip to main content
Security Engine version:
Version: v1.8

Log Processor Benchmark

How fast a Log Processor handles different kinds of log.

Figures cover the whole pipeline, net of the fixed ~2.7 s startup cost. To measure your own:

SH
crowdsec -c config.yaml -no-api -dsn file:///path/to/corpus.log -type nginx
Test bed
InstanceAWS c6i.4xlarge — 16 vCPU (8 physical cores + SMT), 30.8 GiB
CPUXeon Platinum 8375C @ 2.90 GHz
Versionv1.8.2, official release binary
Hublinux, nginx, sshd, base-http-scenarios, http-cve, both appsec collections — 56 scenarios
CorpusTypeContentParsed
nginx.lognginx200 000 lines combined format, 50 000 source IPs, 45% static, 45% dynamic, 7% errors, 3% scanner paths100%
syslog-noise.logsyslog1 000 000 lines of kernel, auditd, systemd, cron and snapd, with 3% sshd auth failures3%

A fully parsed source: nginx​

RoutinesLines/svs 1 routineCPU per linePeak RSS
13 6121.00x732 µs1.4 GB
25 6711.57x792 µs1.9 GB
48 4802.35x965 µs2.5 GB
89 1302.53x1 086 µs2.8 GB
1610 6692.95x1 133 µs3.2 GB

Past four routines, scaling is less efficient.

A mostly unparsed source: kernel and auditd over syslog​

An edge case: it applies to a catch-all syslog socket or a kernel/auditd stream, not to a host whose logs you have parsers for. Skip this section if that is not you.

RoutinesLines/svs 1 routineCPU per lineSystem CPU
116 6501.00x117 µs22 s
216 0490.96x169 µs54 s
415 4650.93x240 µs108 s
813 9920.84x287 µs147 s
1612 7240.76x364 µs207 s

Adding routines makes it slower here. Cause and fix: the grok backend.

Trading memory for throughput​

Past the routines inflection point, pacing the collector more loosely is more efficient than adding routines:

GOGC at 8 routinesLines/svs defaultUser CPUPeak RSS
100 (default)9 133-179 s2.9 GB
2009 764+7%150 s4.0 GB
40010 974+20%136 s5.9 GB
80010 609+16%126 s7.6 GB
tip

GOGC is a Go runtime environment variable, not a CrowdSec setting. Set it in the unit file (Environment=GOGC=400) or the container environment, and watch memory.

The gain is close to flat at every routine count:

RoutinesGOGC=100GOGC=400GainPeak RSS
48 53310 109+18%2.5 -> 4.9 GB
89 13310 974+20%2.8 -> 5.8 GB
1610 12712 744+26%3.3 -> 5.9 GB

GOGC=400 at 4 routines matches the default at 16: twice the memory instead of four times the goroutines.

The grok backend on mostly-unparsed sources​

Since 1.8, grok patterns are matched with the C++ re2 library by default on Linux. That suits logs that parse and hurts logs that do not. The re2_disable_grok_support feature flag restores scaling here:

RoutinesDefault (re2)re2 disabledChangeSystem CPU, default
116 69721 359+28%22 s
216 61930 362+83%51 s
416 71947 215+182%99 s
815 01872 360+382%137 s
1613 04898 138+652%199 s

When to disable it​

Compare cs_parser_hits_ok_total against cs_parser_hits_ko_total in the metrics.

  • Mostly lines that parse (a web server log): leave the default. Turning it off costs 12-30% on the nginx corpus.
  • Mostly lines that nothing parses (kernel, auditd, a catch-all syslog socket): set it, and expect the gain to grow with your routine count.

Add to feature.yaml next to config.yaml:

YAML
- re2_disable_grok_support

Or set CROWDSEC_FEATURE_RE2_DISABLE_GROK_SUPPORT=true in the environment.

Sizing guidance​

  1. Count the lines per second you need to parse, per source.

  2. Multiply by CPU per line for the closest corpus and round up. At 732 µs/line, 1 000 nginx lines/s needs three quarters of a core; unparsed syslog, a tenth.

  3. Add memory for buckets, roughly proportional to distinct active source IPs over a bucket window, not to the log rate: 2 000 IPs instead of 50 000 cut peak memory 39% at the same throughput.

  4. Set the three routine counts to 4 and stop. Never more than your core count.

    YAML
    crowdsec_service:
    pipeline:
    parser: { routines: 4 }
    bucket: { routines: 4 }
    output: { routines: 4 }

    The flat parser_routines, buckets_routines and output_routines keys still work, but pipeline wins wherever both are set.

  5. If 4 is not enough, raise GOGC before the routine counts: ~20% for double the memory, at any routine count.

  6. Budget the Local API separately. Under heavy alert volume (8 700 alerts per 200 000 lines) it costs about two thirds of a core; the database behind it does not change parsing throughput.

If a Log Processor cannot keep up, compare cs_parser_hits_total against the lines your acquisition read, and watch cs_bucket_pour_seconds and cs_postoverflow_queue_depth. See prometheus and pprof.

Reproducing​

Harness, seeded corpus generator and raw per-run CSVs: crowdsec-benchmark.

CrowdSec Docs
We use cookies

This site uses cookies to help us improve your experience. You can accept or decline below.