Skip to content

Reconciliation

How the bouncer ensures address lists are perfectly synchronized with CrowdSec decisions.

When the bouncer starts (or restarts), the MikroTik address list may be out of sync with CrowdSec’s active decisions:

  • IPs may have been added to CrowdSec while the bouncer was offline
  • IPs may have expired in CrowdSec but still be in the MikroTik list
  • Previous bouncer entries may still exist from a prior run
  1. Collect

    Fetch all active decisions from CrowdSec and all address list entries from MikroTik.

  2. Diff

    Compare the two sets to determine which IPs need to be added and which removed.

  3. Apply

    Execute additions (via bulk scripts, 100 IPs/batch) and deletions (via parallel API calls with 4-connection pool).

  4. Verify

    Log final counts and comparison to confirm address list matches CrowdSec exactly.

Measured on a MikroTik hAP ax³ (ARM64, 1 GHz quad-core, 1 GB RAM):

MetricLocal-only (~1,500 IPs)Full CAPI (~25,000 IPs)
Reconciliation time~9 s~2 min 50 s
CPU peak~14%~23%
IPs/second (add)~166~147
IPs/second (delete)~168~168

Instead of individual API calls (~97× slower), the bouncer generates RouterOS scripts:

/system/script/run [find name="cs-bulk-add-0"]

Each script adds up to 100 IPs using :do { ... } on-error={} to handle duplicates gracefully.

Deletions use a 4-connection pool with concurrent API calls, achieving ~168 IPs/second throughput via the generic ParallelExec helper.

During initial decision collection, if a ban and corresponding unban are received for the same IP, the unban pre-filters the ban out of the pending set. This avoids adding and immediately removing the same IP.