Skip to content
Costa Tsaousis edited this page Apr 4, 2026 · 1 revision

Reduce Prefixes

Merge all inputs, then reduce the number of distinct CIDR prefixes while keeping the matched IP set identical.

Aliases: --ipset-reduce PERCENT, --reduce-factor PERCENT, --ipset-reduce-entries ENTRIES, --reduce-entries ENTRIES

Why

netfilter/iptables hash:net ipsets perform one lookup per distinct prefix length. An ipset using 18 prefixes does 18 lookups per packet. Reducing to 3 prefixes cuts that to 3 lookups — for the exact same set of matched IPs.

The number of entries does not affect ipset lookup performance.

Parameters

Option Default Purpose
--ipset-reduce PERCENT 20 Allow this % increase in entries
--ipset-reduce-entries ENTRIES 16384 Minimum absolute entry cap

Maximum acceptable entries = max(current * (1 + PERCENT/100), ENTRIES).

The algorithm iteratively eliminates the prefix with the smallest cost (fewest new entries added), merging it into the next available prefix. Use -v to see each step.

Example

A file with entries spanning many prefix lengths:

# input
10.0.0.0/24
10.0.1.0/25
10.0.1.128/26
10.0.1.192/27
10.0.1.224/28
10.0.1.240/29
10.0.1.248/30
10.0.1.252/31
10.0.1.254
10.0.1.255
10.0.2.0/24
10.0.3.0/25

Before reduction — 3 prefixes:

$ iprange -v input.txt 2>&1 | grep -E 'prefix|totals'
	- prefix /23 counts 1 entries
	- prefix /24 counts 1 entries
	- prefix /25 counts 1 entries
totals: 12 lines read, 1 distinct IP ranges found, 3 CIDR prefixes, 3 CIDRs printed, 896 unique IPs

After --ipset-reduce 50 — 1 prefix:

$ iprange -v --ipset-reduce 50 input.txt 2>&1 | grep -E 'prefix|totals|Eliminated'
Eliminated 2 out of 3 prefixes (1 remain in the final set).
	- prefix /25 counts 7 entries
totals: 12 lines read, 1 distinct IP ranges found, 1 CIDR prefixes, 7 CIDRs printed, 896 unique IPs

Same 896 unique IPs, expressed as 7 /25 entries instead of a mix of /23, /24, and /25. The kernel now does 1 lookup instead of 3.

Lossless round-trip

The reduction is lossless — piping the reduced output back through iprange produces the original optimized set:

$ iprange --ipset-reduce 100 input.txt | iprange -C
1,896
$ iprange input.txt | iprange -C
1,896

See Optimizing ipsets for iptables for an extended tutorial with real-world country and blocklist examples.

Clone this wiki locally