I've run Zabbix 7.0.32 against my lab routers for the whole Zabbix series. LibreNMS keeps coming up as the "just point it at the subnet" alternative, so I put LibreNMS 26.10.2 next to it and monitored the same three devices with the same SNMPv3 user: two Cisco IOS XE 17.18.2 WAN routers and an IOS XE 17.18.2 access switch, built in my home lab.
This post covers discovery, graphs, a BGP alert and the memory each one used. It doesn't pick a winner. The two tools are good at different jobs, and the lab shows where each one fits.


Setup and versions
- LibreNMS 26.10.2 (GPL-3.0), the official
librenms/librenmscontainer with MariaDB 11.4, Redis 7.2 and a separate dispatcher container that runs the pollers. - Zabbix 7.0.32 LTS with MySQL, as built in the earlier posts.
- Devices: wan-rtr1 (AS65001), wan-rtr2 (AS65002) and acc-sw1. SNMPv3 user
zbxmonis authPriv (SHA/AES) on the routers and authNoPriv (SHA) on the switch. I kept the switch that way on purpose, so both tools had to handle two security levels.
One gotcha cost me twenty minutes. The routers only accept SNMP from a short ACL, and the dispatcher container polled from its own IP, so every poll timed out and LibreNMS marked the devices down. Running the dispatcher in the web container's network namespace (network_mode: "service:librenms") made both poll from the one allowed address. If your devices filter SNMP by source, check where the pollers actually live.
Autodiscovery
LibreNMS stores SNMPv3 credentials as an ordered list and tries each one. I added the authPriv entry first and the authNoPriv entry second, then set the subnet and turned on CDP/LLDP discovery:
lnms config:set nets.+ 10.66.20.0/24
lnms config:set snmp.version v3
lnms config:set snmp.v3.0 '{"authlevel":"authPriv","authname":"zbxmon","authpass":"<AUTH>","authalgo":"SHA","cryptopass":"<PRIV>","cryptoalgo":"AES"}'
lnms config:set snmp.v3.1 '{"authlevel":"authNoPriv","authname":"zbxmon","authpass":"<AUTH>","authalgo":"SHA"}'
lnms config:set autodiscovery.xdp trueThen one scan of the management subnet, run as the librenms user in /opt/librenms:
$ ./snmp-scan.py 10.66.20.0/24
Scanned 254 IPs: 0 known devices, added 3 devices, failed to add 5 devices
Runtime: 30.13 secondsThe five failures are Linux hosts on that subnet with no SNMP agent, which is what you want. LibreNMS named the devices from reverse DNS, so give your devices proper PTR records (or host entries) before the first scan. Renaming later works, but deleting and rescanning was faster for me.
In Zabbix the same job is a discovery rule plus an action, or the API, as in the auto-discovery and API onboarding post. That takes longer to set up, but you control exactly which template, host group and tags each device gets. LibreNMS picks the OS module for you and starts graphing everything it finds.
What you get with no templates
Each device page has ports, processors, memory, BGP, OSPF, CEF, VRFs and CDP neighbours, all from SNMP, without me choosing a template. The ports view picks up interface descriptions, IPs, VRF and the neighbour on each link:


Zabbix gets the same data through the Cisco IOS SNMP template, but you decide what's collected, how often, and what's a trigger. That's more work up front and much more control later. I relied on that control in the trigger dependencies post, and LibreNMS has nothing quite like it.
A BGP alert in both
LibreNMS ships with no alert rules enabled out of the box. I made two through the API: "Port down (admin up)" and "BGP session down", which fires when bgpPeerState isn't established and bgpPeerAdminStatus is start. No transport is set up, so the alerts only appear in the web UI.
The test: shut the eBGP neighbour on wan-rtr2 and watch wan-rtr1's view of it.
wan-rtr2(config)# router bgp 65002
wan-rtr2(config-router)# neighbor 10.0.12.1 shutdown
| Time (PST) | Event |
|---|---|
| 9:14:02 AM | Neighbour shut on wan-rtr2 |
| 9:15:01 AM | Zabbix problem: BGP peer 10.0.12.2 (AS 65002) not established on wan-rtr1 |
| 9:19:36 AM | LibreNMS alert: BGP session down on wan-rtr1.lab |
| 9:20:44 AM | Neighbour re-enabled |
| 9:24:36 AM | LibreNMS alert cleared |

Don't read the gap as a benchmark. My dispatcher problem was still being fixed during this test, so LibreNMS lost a poll. The real difference is the polling model. LibreNMS polls every device every five minutes by default, so a BGP drop shows up somewhere between a few seconds and five minutes later. In Zabbix, each item has its own interval, and my BGP state item raised the problem 59 seconds after the shutdown. You can shorten LibreNMS polling, but it applies to the whole device and needs RRD changes, so most people leave it alone. If minute-level alerting on a few key items matters, Zabbix does that better. For "graph everything and tell me when something breaks", five minutes is usually fine.

Memory, measured
Both stacks were idle with the same three devices, measured with docker stats:
| Stack | Containers | Memory |
|---|---|---|
| LibreNMS 26.10.2 | web 130 MiB, MariaDB 143 MiB, dispatcher 58 MiB, Redis 7 MiB | about 338 MiB |
| Zabbix 7.0.32 | MySQL 605 MiB, server 193 MiB, web 48 MiB, agent 15 MiB, SNMP traps 13 MiB | about 873 MiB |
That's not quite like for like. My Zabbix has been running for weeks with more hosts, history and a bigger InnoDB buffer pool. On a fresh install with three devices, the gap would be smaller. What it does show is that LibreNMS is light enough to run next to everything else on a small box.
Side by side
| LibreNMS 26.10.2 | Zabbix 7.0.32 | |
|---|---|---|
| First device graphed | Minutes: set credentials, scan the subnet | Longer: hosts, templates, macros, or a discovery action |
| SNMPv3 with mixed levels | Ordered credential list, tried in turn | Per-host or per-macro credentials |
| Polling | Every device every 5 min by default | Per item, set as short as you need |
| Alerts | Rule builder on collected data, none enabled by default | Triggers with dependencies, hysteresis and escalations |
| Network views | Ports, BGP, OSPF, CDP neighbours, maps built in | Whatever the templates collect, plus your own maps |
| Beyond the network | Mostly network devices | Servers, apps and agents as well |
Where LibreNMS is better: getting from nothing to graphs for a pile of network gear, and having routing and neighbour views ready without any template work. Where Zabbix is better: tuning alerts so they don't spam, fast checks on the few items that matter, and monitoring servers and applications from the same place. In a real network I'd happily run LibreNMS as the network team's discovery-and-graphs tool and keep Zabbix for alerting that pages people.
Caveats
- Three devices and twenty minutes of data is enough to judge setup and alerting, but not how either one scales.
- LibreNMS alerting needs a transport (email, Slack, webhook) before it tells anyone anything. Mine only shows in the UI.
- Name your devices in DNS first, because LibreNMS takes the reverse lookup as the hostname.
Related posts
- Add Cisco IOS XE Routers and Switches to Zabbix over SNMPv3
- Zabbix Email Alerts with Escalation, Tested Against a Real Failure
- Prometheus and snmp_exporter for Cisco IOS XE
- Previous: One Change, Every Tool: NetBox, Batfish, Ansible, Oxidized, Zabbix, Loki and Akvorado
Now live: Netdisco on Cisco IOS XE, CDP topology plus MAC and ARP search on the same lab.