
Nagios, Zabbix, LibreNMS, Prometheus: choosing an open-source monitor
Every few months somebody asks me which open-source monitoring tool is best. I answer with a question: what do you want it to think a measurement is? That sounds like a dodge. It is the most useful thing I know about the four tools that end up on nearly every shortlist.
Nagios Core, Zabbix, LibreNMS and Prometheus can all tell you that a switch port went down. They disagree about almost everything else: where the data lives, who goes and fetches it, what a "check" even is, and how much of your week the tool will want. Pick one whose model fits your network and the rest is configuration. Pick against the grain and you write workarounds for a year.
Here is how I explain the differences to colleagues on the school district's IT team. Anything version-specific is marked as true at the time of writing.
Four tools, four ideas of a measurement
- Nagios Core thinks in states. A check runs, returns OK, WARNING, CRITICAL or UNKNOWN, and Nagios decides whether that state deserves a human.
- Zabbix thinks in items and triggers. An item is a value collected on a schedule and stored in a SQL database. A trigger is an expression over those values that opens or closes a problem.
- LibreNMS thinks in devices. Give it an address and SNMP credentials and it discovers ports, sensors, neighbors and processors, then graphs all of them.
- Prometheus thinks in time series. Every sample is a number with a timestamp, a metric name and a set of labels. Graphs, alerts and reports are all queries over those series.
Most of the strengths and weak spots below follow from those four sentences.
Nagios Core: the check and its exit code
Nagios Core is a scheduler written in C. It runs small programs called plugins and reads their exit codes: 0 for OK, 1 for WARNING, 2 for CRITICAL, 3 for UNKNOWN. The contract is so simple that thousands of plugins exist, and you can write one in Bash over a coffee. Running a plugin by hand is the best debugging tool Nagios has:
/usr/lib/nagios/plugins/check_ping -H 192.0.2.1 -w 100,20% -c 500,60%
echo $?
Hosts, services, contacts, commands and time periods live in text files as object definitions, with templates to cut repetition. Remote checks on servers usually go through NRPE or SSH. Anything a plugin prints after a pipe character is performance data, which Nagios Core does not graph itself. Add-ons do that.
Where it shines: it is predictable, light on resources and very well understood. The state logic (soft and hard states, retries, flap detection, host dependencies) is mature, and the plugin format has outlived several competitors. Icinga and Checkmk can still run the same plugins.
Where it hurts: no built-in graphs, a classic web interface that shows its age, and a configuration that grows into a large pile of text files unless you generate it. Nagios Core discovers nothing on its own. A 48-port switch is one host plus as many service definitions as you are willing to write.
Who it suits: teams with a list of specific yes-or-no questions (is the web server answering, did last night's backup finish) and someone happy to keep config in Git.
Zabbix: items, triggers and a database
Zabbix is a server written in C, a PHP web front end and a relational database: MySQL, MariaDB or PostgreSQL, with TimescaleDB as an option on PostgreSQL. It collects through its own agents, SNMP, IPMI, JMX, HTTP checks, SSH and scripts, and it can put proxies in branch offices that collect locally and forward. When a graph looks wrong, ask the agent directly:
zabbix_get -s 192.0.2.20 -k 'system.cpu.load[all,avg1]'
Templates do the heavy lifting. Link a Linux template to a host and you get dozens of items, triggers and graphs. Low-level discovery finds file systems, network interfaces and SNMP table rows and creates items for each one. Raw values go into history tables, and hourly minimum, average and maximum go into trends, so you can keep long-range data without keeping every sample.
Where it shines: it really is all-in-one. Collection, storage, graphs, dashboards, maps, alerting, escalations and user permissions arrive in one package, with a web interface for all of it. Windows servers, Linux servers and network gear sit side by side, and the template library covers a lot of hardware.
Where it hurts: the database is the system, and it grows. With many items at short intervals the history tables get large, and the housekeeper that trims them becomes a tuning topic of its own. Most configuration happens in the browser, which is friendly for one admin and harder to review as a team. Licensing changed with Zabbix 7.0 in June 2024, from GPLv2 to AGPLv3. At the time of writing that matters mainly if you modify Zabbix and offer it to others over a network.
Who it suits: mixed shops that want one tool for servers, switches, printers and the odd UPS.
LibreNMS: the device is the unit
LibreNMS is a PHP application built on the Laravel framework, with a MySQL or MariaDB database and RRDtool files for graphs. It was forked in 2013 from the last GPL-licensed Observium code and is licensed under GPLv3. Everything starts from SNMP. Add a device and LibreNMS walks the standard and vendor MIBs, finds every interface, VLAN, sensor, processor, memory pool and neighbor, and polls them, every five minutes by default. Let it, and it will find more of your network through CDP, LLDP, OSPF, BGP and ARP.
Before I add anything SNMP-based, I check from the monitoring server that the device answers, with SNMPv3 rather than a community string:
snmpwalk -v3 -l authPriv -u monitor -a SHA -A 'auth-passphrase' \
-x AES -X 'priv-passphrase' 192.0.2.30 1.3.6.1.2.1.1
If that returns the system group, LibreNMS will be happy too. The differences between SNMP v1, v2c and v3 explain why v3 is worth the extra flags.
Where it shines: nothing else here gets you to useful network graphs faster. Per-port traffic, errors, optic levels, temperatures and neighbor maps appear without writing a single check. It has alert rules, an API, syslog and config-backup integrations, and distributed pollers for bigger networks.
Where it hurts: it is network-first. Server and application monitoring exists but is thinner than in Zabbix or Prometheus. RRD files get a fixed resolution when they are created, so changing the polling interval later is a migration, not a setting. Think about that before you add the first device. The trade-offs are laid out in choosing a polling interval.
Who it suits: networks that are mostly switches, routers, firewalls and access points. Schools, campuses, small ISPs, home labs with a managed switch.
Prometheus and Grafana: everything is a labeled time series
Prometheus is a server written in Go that scrapes HTTP endpoints on a schedule. Each target exposes plain-text metrics, either natively or through an exporter: node_exporter for Linux hosts on port 9100, blackbox_exporter for ping, HTTP and DNS probes, snmp_exporter for network gear. A minimal scrape config:
global:
scrape_interval: 30s
scrape_configs:
- job_name: node
static_configs:
- targets: ['192.0.2.40:9100', '192.0.2.41:9100']
Every series carries labels, and PromQL slices by them. Receive traffic in bits per second on one Linux interface is a single line:
rate(node_network_receive_bytes_total{device="eth0"}[5m]) * 8
Alert rules are PromQL expressions too. Prometheus evaluates them and hands firing alerts to Alertmanager, which groups, de-duplicates, routes and silences them. Grafana sits on top for dashboards.
Where it shines: the label model is the most flexible of the four. Service discovery (Kubernetes, Consul, DNS, plain files) means targets come and go without editing anything. There are exporters for nearly everything, the storage engine is efficient, and the whole stack is text configuration that lives happily in Git.
Where it hurts: local storage is built for weeks, not years. The default retention is 15 days at the time of writing, so long history needs a remote storage system. SNMP works, but you generate the snmp_exporter config from MIBs yourself, and nothing discovers your switch ports the way LibreNMS does. It records numbers, not events or log lines, and labels with too many values (one per user, one per request) quietly eat memory.
Who it suits: teams running containers or services that already expose metrics, and home-lab builders who enjoy assembling the stack piece by piece. On network-heavy sites it works best next to an SNMP-first tool rather than instead of one.
Side notes: Icinga, Checkmk and Cacti
Icinga began in 2009 as a fork of Nagios and was later rewritten as Icinga 2, with its own configuration language, a REST API and built-in support for distributed setups. If you like the Nagios model but want a modern core and web interface, start there. Your plugins come with you.
Checkmk started as an add-on that fed Nagios and grew into a full distribution. Its agent sends one large block of data per host, the server splits it into services, and automatic service discovery does most of the setup. The open-source edition (called Raw at the time of writing) is capable, though some features are kept for the paid editions.
Cacti is a PHP front end to RRDtool that has drawn SNMP graphs since 2001. It is still a very good grapher, but alerting comes from plugins and it does not try to be a full monitoring system. It belongs to a generation of PHP network tools that also included JFFNMS, an older GPL system that combined SNMP polling with syslog and event handling. The downloads directory lists more of that family.
Side by side
| Nagios Core | Zabbix | LibreNMS | Prometheus + Grafana | |
|---|---|---|---|---|
| Core idea | check states | items and triggers | discovered devices | labeled time series |
| How data arrives | plugins run by the scheduler | agents, SNMP, proxies, scripts | SNMP polling, 5 min by default | HTTP scrape of exporters |
| Storage | state only, graphs via add-ons | SQL database, history and trends | MySQL plus RRD files | local TSDB, remote storage for long term |
| Network gear | one check at a time | templates and discovery | strongest of the four | snmp_exporter, manual setup |
| Servers and apps | through plugins | strong | basic | strong |
| Graphs | add-on | built in | built in | Grafana |
| Alerting | mature state logic | triggers, actions, escalations | rule builder | PromQL rules, Alertmanager |
| Configuration | text files | web UI and API | web UI and CLI | YAML in Git |
| License (at the time of writing) | GPLv2 | AGPLv3 from 7.0 | GPLv3 | Apache 2.0, Grafana AGPLv3 |
| Learning curve | easy start, grows | medium | low | medium to high |
How I would choose
What is most of your estate? If it is network gear, start with LibreNMS. If it is servers and services, start with Zabbix or Prometheus. If it is a short list of things that must answer, Nagios or Icinga will do the job with very little overhead.
How does your team like to work? People who keep everything in Git and review each other's changes tend to be happier with Prometheus or a generated Nagios config. A lone admin who wants to manage everything from a browser is usually happier with Zabbix or LibreNMS.
Who gets paged? Every one of these tools can send an email at 3 a.m. Whether that email is worth waking up for depends on rules you write, not on the tool. Read up on alerts people still read before you switch notifications on.
Mixing is normal. LibreNMS for switches plus Prometheus for Linux hosts is a pairing I see often.
A two-week trial beats any comparison
- Pick ten devices that represent your network: a core switch, two access switches, a router or firewall, three Linux servers, one Windows server, and the one thing that always breaks.
- Build two candidates on separate small VMs. Two vCPUs and 4 GB of RAM is usually plenty at this size, and a Raspberry Pi can host the lighter ones; the Pi home-lab build shows how far one board goes.
- Give both the same credentials and the same polling interval.
- Write three alerts in each: device down, interface errors rising, disk filling.
- Pull a cable, fill a disk, reboot a switch. Note which tool told you first and most clearly.
- On the last day, ask the person who will maintain it which one they would rather open on a Monday morning.
That last answer usually decides it, and it should. The best monitor is the one somebody is still tuning a year from now.
