pfSense Limiters - Per-IP Bandwidth Rate Limiting
Limiters in pfSense are built on the FreeBSD dummynet(4) subsystem and provide a mechanism for enforcing hard bandwidth caps. Unlike ALTQ, Limiters operate independently of network interface card drivers and support rate limiting at the individual IP address and subnet level. The dummynet subsystem was originally designed for testing TCP behavior under congestion, but pfSense leverages it as a full-featured traffic management tool.
Limiters enforce a bandwidth ceiling by delaying or dropping packets to achieve a target line rate. This is fundamentally different from ALTQ, where unused bandwidth can be borrowed between queues. A Limiter does not guarantee minimum bandwidth - it only restricts the maximum.
Limiter Architecture
Pipes and Queues
Limiters are organized in a two-level hierarchy:
- Pipes (root Limiters) - define the upper bandwidth limit and can introduce artificial delay. Each pipe represents a channel with a defined throughput capacity.
- Queues (child Limiters) - created within a pipe and distribute traffic using weights (1-100). Weights determine proportional bandwidth allocation among queues, but child queues cannot exceed the aggregate throughput of their parent pipe.
For typical rate limiting scenarios, root Limiters alone are sufficient. Child queues are used when traffic prioritization within a rate-limited channel is required.
Limiters vs ALTQ
| Feature | Limiters (dummynet) | ALTQ |
|---|---|---|
| Subsystem | dummynet(4) | pf (ALTQ framework) |
| Bandwidth guarantees | No (ceiling only) | Yes (HFSC real-time curve) |
| Per-IP rate limiting | Yes (via masks) | No |
| Per-subnet rate limiting | Yes (via masks) | No |
| Bandwidth borrowing | No | Yes (CBQ, HFSC link share) |
| CoDel/FQ-CoDel | Yes | No |
| NIC driver dependency | No | Yes |
| Wizard-based setup | No | Yes |
Creating a Limiter
Configuration is performed at Firewall > Traffic Shaper > Limiters. A typical rate limiting scenario requires two Limiters: one for inbound traffic (download) and one for outbound traffic (upload).
Root Limiter Parameters
Bandwidth - the numerical throughput value, specified in the selected units.
Bandwidth type - measurement units: Mbit/s, Kbit/s, or Bit/s. Mbit/s is appropriate for most scenarios.
Schedule - an optional parameter that binds bandwidth to a firewall schedule. This is useful when different limits are required during business hours versus off-hours.
Mask - determines how the limit is applied:
- None - a single shared bucket for all traffic. All traffic matching the Limiter shares the defined bandwidth. Appropriate for limiting aggregate subnet throughput.
- Source address - creates a separate bucket for each source IP address. Used for the upload Limiter (outbound traffic).
- Destination address - creates a separate bucket for each destination IP address. Used for the download Limiter (inbound traffic).
Mask bits - defines masking granularity. A value of 32 for IPv4 creates a separate bucket for each individual IP address. A value of 24 groups all addresses within a /24 subnet into a single bucket.
Advanced Parameters
Delay - artificial latency in milliseconds. Used for testing application behavior under high latency. Set to 0 in production configurations.
Packet Loss Rate - packet loss coefficient in decimal format (0.01 = 1%). Used exclusively for testing. Set to 0 in production.
Queue Size - queue depth in slots (default: 50). Slow links (under 10 Mbit/s) may require a larger value to prevent excessive packet drops.
Bucket Size - hash table size for masked buckets. Range: 16 to 65536, default: 64. Increase this value when a large number of concurrent buckets exist (for example, per-IP limiting on a network with 500+ hosts).
Example: 50 Mbit/s Per-IP Download Limiter
- Navigate to Firewall > Traffic Shaper > Limiters
- Click New Limiter
- Configure parameters:
- Name:
Download_50Mbps - Bandwidth:
50 - Bandwidth type:
Mbit/s - Mask:
Destination address - Mask bits:
32
- Name:
- Save the configuration
Example: 25 Mbit/s Per-IP Upload Limiter
- Click New Limiter
- Configure parameters:
- Name:
Upload_25Mbps - Bandwidth:
25 - Bandwidth type:
Mbit/s - Mask:
Source address - Mask bits:
32
- Name:
- Save the configuration
Applying Limiters Through Firewall Rules
Limiters are attached to firewall rules via the In and Out fields in the rule’s Advanced Options section. Understanding the directional perspective is critical: In and Out are defined from the perspective of the firewall itself, not the end user.
Directional Perspective
For a rule on the LAN interface:
- In (traffic entering the firewall from LAN) = user’s upload
- Out (traffic leaving the firewall to LAN) = user’s download
Therefore, in a LAN rule:
- In pipe = Upload Limiter
- Out pipe = Download Limiter
Warning:
The most common Limiter configuration error is swapping the In and Out directions. If a speed test shows the upload being limited instead of the download (or vice versa), swap the Limiters in the rule settings.
Configuring the Firewall Rule
- Navigate to Firewall > Rules > LAN
- Create or edit a Pass rule for the traffic to be limited
- Under Extra Options, expand Display Advanced
- In the In / Out pipe fields, select:
- In:
Upload_25Mbps(upload Limiter) - Out:
Download_50Mbps(download Limiter)
- In:
- Save the rule and apply changes
Rule Ordering
A Limiter applies only to traffic matching the specific firewall rule it is attached to. To limit all subnet traffic, attach the Limiter to the general allow rule. To limit only specific traffic (for example, HTTP/HTTPS), create a dedicated rule with the Limiter attached only to it.
Rules without an attached Limiter pass traffic without speed restrictions. This allows excluding critical services from shaping by placing their allow rules above the Limiter-enabled rule.
Common Scenarios
Guest Wi-Fi Rate Limiting
Goal: limit each guest network user to 10 Mbit/s download and 5 Mbit/s upload.
Limiters:
Guest_Download_10M- Bandwidth: 10 Mbit/s, Mask: Destination address, Bits: 32Guest_Upload_5M- Bandwidth: 5 Mbit/s, Mask: Source address, Bits: 32
Firewall rule: on the GUEST_WIFI interface, create a Pass rule for Source: GUEST_WIFI net, Destination: any. In pipe: Guest_Upload_5M, Out pipe: Guest_Download_10M.
Each user receives an individual 10/5 Mbit/s limit, but the aggregate bandwidth of the entire guest network is unrestricted. To cap aggregate bandwidth as well, create an additional pair of Limiters with Mask: None.
Aggregate Subnet Bandwidth Limiting
Goal: limit all traffic for subnet 192.168.20.0/24 to 100 Mbit/s download and 50 Mbit/s upload (aggregate for the entire subnet, without per-IP limits).
Limiters:
Subnet_Download_100M- Bandwidth: 100 Mbit/s, Mask: NoneSubnet_Upload_50M- Bandwidth: 50 Mbit/s, Mask: None
With Mask: None, all subnet traffic enters a single shared bucket. The 100 Mbit/s is shared among all active hosts in the subnet.
Combined Limiting: Per-IP Within an Aggregate Cap
Implementing a scheme where each user is limited to 20 Mbit/s while the total subnet bandwidth cannot exceed 100 Mbit/s requires two pairs of Limiters and two firewall rules:
- The first rule (higher in the list) with per-IP Limiters (Mask: Source/Destination address) and a 20 Mbit/s limit
- Additionally, Limiters with Mask: None and a 100 Mbit/s limit applied as parent pipes
Warning:
pfSense does not support nested limiting (a per-IP Limiter within a subnet Limiter) as a single construct. Complex hierarchical schemes may require combining Limiters with child queues or using ALTQ instead of Limiters.
Fair Bandwidth Distribution
Goal: a 100 Mbit/s channel should be distributed fairly among all users. With 10 active users, each receives approximately 10 Mbit/s; with 2 active users, each receives 50 Mbit/s.
A per-IP Limiter with a mask set to the full channel speed creates fixed buckets - each IP receives the full Limiter bandwidth, not a proportional share. True fair distribution is achieved through FQ-CoDel (described below).
CoDel and Bufferbloat Mitigation
The Bufferbloat Problem
Bufferbloat is excessive packet buffering in network equipment that causes latency to spike under load. When the connection is saturated (torrents, large downloads), router buffers overflow, and interactive traffic (VoIP, gaming, web browsing) experiences delays of hundreds of milliseconds instead of single-digit values.
CoDel (Controlled Delay)
CoDel is an Active Queue Management (AQM) algorithm that addresses bufferbloat. Instead of simply dropping packets when the queue overflows, CoDel monitors how long packets remain in the queue and begins dropping packets when the sojourn time exceeds an acceptable threshold.
FQ-CoDel (Fair Queuing CoDel)
FQ-CoDel combines CoDel with a Fair Queuing mechanism. Traffic is automatically distributed across multiple internal queues, providing equal bandwidth access for all flows. FQ-CoDel is the recommended algorithm for bufferbloat mitigation in pfSense.
Configuring CoDel in a Limiter
- Navigate to Firewall > Traffic Shaper > Limiters
- Create a new Limiter or edit an existing one
- Set Bandwidth to approximately 85-95% of the actual link speed (measured without load). Setting the value below the real link speed is necessary so that buffering occurs in dummynet rather than in ISP equipment.
- Under Queue Management Algorithm, select CoDel or FQ-CoDel
- Default parameters (target: 5ms, interval: 100ms) are appropriate for most scenarios
- Save and apply
Warning:
For CoDel to function correctly, the Limiter Bandwidth must be set below the actual link throughput. If the Limiter is configured at or above the real link speed, buffering occurs in ISP equipment where CoDel cannot control the queue.
Verifying Effectiveness
After configuring CoDel, run a bufferbloat test using the Waveform Bufferbloat Test ( https://www.waveform.com/tools/bufferbloat ) or a similar tool. The test measures latency under load and assigns a grade from A to F.
Target results:
- Grade A or B (latency under load below 30 ms)
- If grade C or lower, reduce the Limiter Bandwidth by 5-10% and retest
Monitoring Limiters
Active Limiters and their current state are accessible at Diagnostics > Limiter Info. The page displays:
- A list of active pipes and queues
- Current traffic statistics for each Limiter
- For per-IP Limiters (with masks), individual buckets for each IP address with per-bucket statistics
- Dropped packet counters
This information is valuable for troubleshooting and verifying that Limiters are applied correctly.
Troubleshooting
Limiter Not Restricting Speed
- Verify that the Limiter is attached to a firewall rule and that the rule actually matches the target traffic. Check Diagnostics > States for states corresponding to the rule.
- Verify the In/Out directions in the rule. Remember that In and Out are defined from the firewall’s perspective.
- Ensure the traffic is not matching a different rule higher in the list that has no Limiter attached.
- Check Diagnostics > Limiter Info to confirm the Limiter is active and showing traffic.
Speed Test Shows Speed Above the Limit
- Speed tests may use multiple TCP connections, each receiving the full per-IP limit. This is correct behavior when masks are used.
- Verify the speed test is running from a host that falls under the Limiter-enabled rule.
- Check that the units match: the Limiter is configured in Mbit/s, but the speed test may display results in MB/s (1 MB/s = 8 Mbit/s).
Speed Test Shows Speed Well Below the Limit
- Check Queue Size - a small value on slow links may cause excessive packet drops.
- If CoDel/FQ-CoDel is enabled, ensure the Bandwidth is not set too low.
- Check the firewall’s CPU utilization - dummynet adds processing overhead.
IPv6 Traffic Not Being Limited
Limiters for IPv4 and IPv6 operate independently. To limit IPv6 traffic, create separate firewall rules with the same Limiters attached. Mask bits for IPv6 per-IP limiting should be set to 128 (instead of 32 for IPv4).
Migration From Other Platforms
From MikroTik Simple Queues
MikroTik Simple Queues combine upload and download limits in a single rule with a target-address. The pfSense equivalent requires:
- Creating two separate Limiters (upload and download)
- Attaching both Limiters to a firewall rule via In/Out pipes
- Configuring masks for per-IP limiting (Source address for upload, Destination address for download)
MikroTik Queue Tree with PCQ (Per Connection Queue) is analogous to Limiters with masks. PCQ dst-address corresponds to Mask: Destination address; PCQ src-address corresponds to Mask: Source address.
From FortiGate Traffic Shaping
FortiGate uses Traffic Shaping Profiles and Policies. A shared shaper in FortiGate is analogous to a Limiter with Mask: None. A per-IP shaper in FortiGate corresponds to a Limiter with Mask: Source/Destination address. Guaranteed bandwidth in FortiGate has no direct equivalent in Limiters - for guaranteed bandwidth, use ALTQ HFSC instead.
Related Sections
- pfSense Traffic Shaper - overview of bandwidth management mechanisms
- ALTQ Traffic Shaper - wizards and traffic prioritization through ALTQ queues
- Firewall Rules - creating rules through which Limiters are applied