Scaling and high availability
pfCentral’s load comes mostly from telemetry, not from people using the UI. Each firewall sends a heartbeat every 5 seconds and a telemetry envelope every 2 seconds, whether anyone is looking or not. Requests from the UI and API are small and only happen when someone clicks or a script runs.
Size your server
Section titled “Size your server”Move the slider to your fleet size. The numbers use an envelope of about 2.9 KB, measured from a firewall with about 20 interfaces. Firewalls with more interfaces, VLANs or tunnels send larger envelopes.
- Messages into NATS
- – telemetry + heartbeats
- Bandwidth into the server
- – port 24222, before TLS overhead
- Telemetry on disk
- – JetStream, 6 h kept
- Per firewall
- – upload from each site
What the numbers mean:
- Messages into NATS. NATS handles hundreds of thousands of messages per second on one core, so this is rarely the limit.
- Bandwidth into the server. What port 24222 receives from all firewalls together.
- Telemetry on disk. The
TELEMETRYstream keeps 6 hours. Put the state volume on a disk with this much free space, plus a margin. - Per firewall. What each site uploads. On a slow or metered link, raise the agent’s
telemetry_interval.
Change the telemetry interval
Section titled “Change the telemetry interval”The interval is set on each agent, in /usr/local/etc/nats-agent/config.yaml:
telemetry_interval: 10sOr with PFCENTRAL_AGENT_TELEMETRY_INTERVAL. The minimum is 1s. A longer interval means less disk and bandwidth, and coarser live charts. Heartbeats stay at 5 seconds, so online detection does not change.
Other limits to know
Section titled “Other limits to know”| Limit | Default | Grows with | Notes |
|---|---|---|---|
| HTTP rate limit | 600 requests/minute | Users, open live pages, scripts | One bucket for the whole server process, per replica. Raise PFCENTRAL_RATELIMIT_GLOBAL_RPM for busy API use. |
| Request timeout | 5 s | Slow firewalls, slow links | Each UI or API action is one request to one firewall. Others are not affected. |
| PostgreSQL | small | Members, devices, audit events, sessions | Device data is not stored here; it stays on the firewalls. |
| Server memory | — | Number of firewalls and open browser tabs | The latest telemetry of each device is kept in memory. |
What happens when pfCentral is down
Section titled “What happens when pfCentral is down”pfCentral is a management plane. The firewalls do not depend on it to pass traffic.
| While the server is down | After it comes back |
|---|---|
| Firewalls keep running with their current configuration. | Agents reconnect on their own, within seconds. |
| Agents retry the connection every 2 seconds, forever. | Telemetry resumes; the gap stays empty in the charts. |
| You cannot make changes from pfCentral. Use each firewall’s own GUI if you must. | Changes you made in the pfSense GUI show up in pfCentral, because lists are read live from the firewalls. |
So for most teams, a single server with good backups is enough. Plan a restore, not a cluster. See Back up and restore.
High availability
Section titled “High availability”If you need pfCentral itself to stay up during a node failure or an upgrade, run several replicas.
| Single server | Several replicas | |
|---|---|---|
| NATS | Embedded (default) | External broker (your NATS cluster or Synadia Cloud) |
| State volume | Holds keys and JetStream data; only one process may use it | Not needed for NATS; keys come from files or Secrets |
| Upgrades | Short outage (stop, start) | Rolling, no outage |
| Online detection | At once on disconnect; 15 s on silent loss | 15 s (no access to broker system events) |
| Setup effort | None | You run and secure the broker and its accounts |
How replicas share the work:
- Sessions live in PostgreSQL, so any replica serves any user.
- The login check (callout) runs on every replica in a NATS queue group, so one replica answers each agent login.
- Telemetry and presence come from the shared stream and buckets on the broker, so every replica shows the whole fleet.
- Migrations take a database lock, so replicas can start together.
PostgreSQL must be highly available too; use a managed database or your usual replication.