# Cacti [![Cacti Commit Audit](https://github.com/Cacti/cacti/actions/workflows/syntax.yml/badge.svg)](https://github.com/Cacti/cacti/actions/workflows/syntax.yml) [![Project Status](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) [![Translation Status](https://translate.cacti.net/widgets/cacti/-/core/svg-badge.svg)](https://translate.cacti.net) [![Average issue resolution time](https://isitmaintained.com/badge/resolution/cacti/cacti.svg)](https://isitmaintained.com/project/cacti/cacti) [![Open issues](https://isitmaintained.com/badge/open/cacti/cacti.svg)](https://isitmaintained.com/project/cacti/cacti) --- ## Overview Cacti is an open-source network monitoring and graphing platform built on RRDtool. It provides a scalable framework to collect, store, and visualize time-series data from network devices, servers, and applications. Core capabilities include: - Automated device discovery - Local and remote data collection - Graph, data source, and RRA templating - SNMP polling (v1/v2/v3) and IPv6 support - Role-based access control (RBAC) - Plugin framework - Dynamic graph viewing and export options --- ## Release Branches Cacti maintains two primary branches: | Branch | Purpose | |---|---| | `1.2.x` | Stable long-lived release series | | `develop` | Active development toward Cacti 1.3.x | For the latest published version, see [GitHub Releases](https://github.com/Cacti/cacti/releases). --- ## System Requirements Minimum supported dependencies by branch: | Dependency | Cacti `1.2.x` | Cacti `develop` (1.3.x) | |---|---|---| | MariaDB | 10.5+ | 10.11+ | | MySQL | 8.0+ | 8.4+ | | PHP | 8.2+ | 8.3+ | | RRDtool | 1.7+ | 1.8+ | | Net-SNMP | 5.9+ | 5.9+ | Notes: - RRDtool 1.9+ is recommended for newer dynamic graph features in 1.3.x. - A web server with PHP support is required. - PHP should be available as CLI or CGI for scheduled polling and maintenance scripts. - `php-snmp` is now fully supported. When both `php-snmp` and the Net-SNMP binaries are available, `php-snmp` is used by default; to force the Net-SNMP binaries, set `$php_snmp_support = false;` in `include/config.php`. - Full support for the upcoming PHP 8.6 release is planned, which brings significant performance improvements that speed up data collection in Script and Script Server data input methods. Operating system guidance: - `1.2.x`: RHEL/Rocky/Alma 8+ (or equivalent) is a common baseline. - `1.3.x`: RHEL/Rocky/Alma 9+ or CentOS Stream 9+ is preferred for modern PHP packaging. - Debian and Ubuntu are also well supported. --- ## Installation (Source Checkout) Clone the repository: ```bash git clone https://github.com/Cacti/cacti.git cd cacti ``` Dependency management: - For a source checkout on both `1.2.x` and `develop`, install dependencies with Composer before serving Cacti. Composer-managed packages under `include/vendor` are generated and intentionally not committed; the remaining legacy libraries in that directory are not Composer-managed and remain in the repository. - On `develop`, `composer install` uses the committed lock file resolved against Cacti's PHP 8.3 floor. - Use `composer update` only in an intentional dependency-update change, and commit the resulting `composer.lock` update. - Release packages must build `include/vendor` from the lock with `composer install --no-dev` and verify the real build host with `composer check-platform-reqs --no-dev`. - Tags under `release/*` build a deterministic archive, SHA-256 checksum, CycloneDX SBOM, and GitHub provenance attestation through the release-artifact workflow. Install dependencies: ```bash composer install ``` Windows users may need: ```bash composer install --ignore-platform-req=ext-pcntl --ignore-platform-req=ext-posix ``` For a source checkout, install the locked browser dependencies before configuring the web server. Node.js is required for this build; release archives already contain the generated assets. Run this command as the owner of the Cacti files: ```bash npm ci ``` Then configure your database and web server, and complete setup using the official docs: https://github.com/Cacti/documentation --- ## Database Upgrades and Schema Checks When running from source (especially `develop`), schema updates may be required after pulling changes. Upgrade the database schema: ```bash sudo -u cacti php -q cli/upgrade_database.php --forcever=`cat include/cacti_version` ``` If needed, force a re-upgrade from an earlier version: ```bash php -q cli/upgrade_database.php --forcever= ``` Audit schema consistency: ```bash php cli/audit_database.php --report ``` --- ## Data Collection and Polling Cacti collects data through data sources, which can use: - SNMP - Scripts - Command output - Databases - Custom input methods Polling engines: | Poller | Description | |---|---| | PHP Poller | Built-in polling engine | | Spine | High-performance C-based poller | Spine supports SNMPv1/v2 and SNMPv3 with IPv6, with some advanced protocol support depending on how Net-SNMP is compiled on your platform. --- ## Features - Device discovery and automation workflows - Reusable templates for graphs and data sources - Distributed remote data collectors - Plugin architecture for extensibility - Dynamic graph interactions (time navigation, realtime view, CSV export) - Fine-grained user and group permissions using RBAC - Broad RRDtool graphing support (including VDEFs and stacked lines) --- ## Documentation Official documentation is maintained in a separate repository: https://github.com/Cacti/documentation --- ## Development and Validation Install the locked Composer dependencies before running PHP contracts. From the repository root: ```bash composer install include/vendor/bin/pest --configuration=tests/phpunit.xml --testsuite=Unit,Integration composer run-script phpstan -- --memory-limit=2G ``` Coverage reports for the PRs checked on October 14, 2026 measure changed first-party executable statements. Applicable changes exceed 80%; this is not whole-project coverage. Formatting-only PHP changes are checked for equivalent syntax trees. Documentation, workflow definitions, lockfiles and generated vendor bundles are outside this execution metric. The [validation snapshot](docs/validation/pr-coverage-2026-10-14.json) records the measured counts and scope. Run the disposable browser and SQL/RRD profile with Docker and mise installed: ```bash bash tests/performance/profile.sh ``` The runner selects Node 22 and Python 3.12 through mise and seeds 500 disabled devices and 50 deterministic RRD graphs. It profiles all shipped themes, AJAX navigation, realtime responses, and graph rendering with Boost enabled and disabled. Containers are removed after the run; the printed results directory retains traces, CPU and memory measurements, SQL counts and Callgrind profiles. See [profiling instructions](tests/performance/README.txt) and the [measured rendering change](docs/performance/graph-array-reuse-2026-10-14.json). The October 14 profile found 400 redundant option-array loads across 200 graph renders. Removing those loads reduced median warm PHP CPU use by 70.7% without Boost and 46.6% with Boost in the equally instrumented fixture. Browser profiles still show retained DOM growth and expensive Midwinter styling. Timings include Xdebug overhead and use synthetic data; they do not measure live SNMP, collector throughput or production fleet capacity. The current fixture uses RRDtool 1.7.2 for basic rendering; it does not exercise newer RRDtool features. --- ## Contributing Contributions are welcome. 1. Fork this repository. 2. Create a branch for your change. 3. Submit a pull request. You can also help improve docs in: https://github.com/Cacti/documentation --- ## Community Community support is available on the Cacti forums: https://forums.cacti.net --- ## Contributors Thanks go to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
Ian Berry
Ian Berry

πŸ’»πŸ›‘οΈπŸ“–πŸŽ¨
Reinhard Scheck
Reinhard Scheck

πŸ’»πŸ›‘οΈπŸ“–
Tony Roman
Tony Roman

πŸ’»πŸ›‘οΈπŸ“–πŸŒβš οΈπŸŽ¨
Andy Blyler
Andy Blyler

πŸ’»
Larry Adams
Larry Adams

πŸ’»πŸ›‘οΈπŸ“–πŸš‡πŸŒβš οΈπŸŽ¨πŸš§πŸ‘€
Mark Brugnoli-Vinten
Mark Brugnoli-Vinten

πŸ’»πŸ›‘οΈπŸ“–πŸš‡πŸŒβš οΈπŸŽ¨πŸš§πŸ‘€
Jimmy Conner
Jimmy Conner

πŸ’»πŸ›‘οΈπŸ“–πŸš‡πŸŒβš οΈπŸŽ¨πŸš§πŸ‘€
Petr Macek
Petr Macek

πŸ’»πŸ›‘οΈπŸ“–βš οΈπŸ‘€
Andreas Braun
Andreas Braun

πŸ’»πŸ“–πŸŒπŸŽ¨πŸ‘€
Jing Chen
Jing Chen

πŸ’»πŸ›‘οΈπŸ“–πŸ‘€
Thomas Vincent
Thomas Vincent

πŸ’»πŸ›‘οΈπŸ“–πŸš‡πŸŒβš οΈπŸš§πŸ‘€
Sean Mancini
Sean Mancini

πŸ’»πŸ“–πŸš‡βš οΈπŸ‘€
J.P. Pasnak, CD
J.P. Pasnak, CD

πŸ’»πŸ›‘οΈπŸ“–πŸŒβš οΈ
Chris Bell
Chris Bell

πŸ’»
Paul Gevers
Paul Gevers

πŸ’»πŸ“–πŸŒβš οΈ
Morten Stevens
Morten Stevens

πŸ’»
iankberry
iankberry

πŸ’»
ronytomen
ronytomen

πŸ’»πŸ‘€
reboot1983
reboot1983

πŸ’»πŸ‘€
micke2k
micke2k

πŸ’»πŸŽ¨
EkaterinePapava
EkaterinePapava

πŸ’»πŸŒ
hljtql
hljtql

πŸ’»πŸŒ
yeager
yeager

πŸ’»
YongBoLiu
YongBoLiu

πŸ’»πŸ‘€
arjanoosting
arjanoosting

πŸ’»
Coool
Coool

πŸ’»πŸŒ
kim-fitness
kim-fitness

πŸ’»πŸ‘€
earendilfr
earendilfr

πŸ’»πŸ“–
purplegrape
purplegrape

πŸ’»πŸŒ
Π‘Π΅Ρ€Π³Π΅ΠΉ
Π‘Π΅Ρ€Π³Π΅ΠΉ

πŸ’»πŸŒ
DavidLiedke
DavidLiedke

πŸ’»πŸ›‘οΈπŸ“–πŸŒ
MSS970
MSS970

πŸ’»πŸ‘€
SjonHortensius
SjonHortensius

πŸ’»
thurban
thurban

πŸ’»πŸ‘€
riversdev0
riversdev0

πŸ’»πŸ‘€
chilek
chilek

πŸ’»πŸ‘€
MarcBanyard
MarcBanyard

πŸ’»
bernisys
bernisys

πŸ’»
ka1lie
ka1lie

πŸ’»
Dmitry
Dmitry

πŸ’»πŸŒ
sysres-dev
sysres-dev

πŸ’»πŸ‘€
rb83
rb83

πŸ’»πŸ‘€
click0
click0

πŸ’»
smiles1969
smiles1969

πŸ’»
gadzet21
gadzet21

πŸ’»
rlaager
rlaager

πŸ’»
paulcalabro
paulcalabro

πŸ’»
mhoran
mhoran

πŸ’»πŸ‘€
Javier
Javier

πŸ’»πŸ“–πŸŒ
frontierliu
frontierliu

πŸ’»πŸ‘€
xbolshe
xbolshe

πŸ’»
arno-st
arno-st

πŸ’»
c72578
c72578

πŸ’»
C00kiekiller
C00kiekiller

πŸ’»
nuno-silva
nuno-silva

πŸ’»
pautiina
pautiina

πŸ’»πŸ‘€
interduo
interduo

πŸ’»πŸŒ
seanmancini
seanmancini

πŸ’»βš οΈ
jav4
jav4

πŸ’»
fabriciotm
fabriciotm

πŸ’»
eriksejr
eriksejr

πŸ’»
hb9xar
hb9xar

πŸ’»
nightflyza
nightflyza

πŸ’»
nbz6
nbz6

πŸ’»
iaohkut
iaohkut

πŸ’»
Nakayama Kito
Nakayama Kito

πŸ’»πŸŒ
SMark-Black
SMark-Black

πŸ’»
Givo29
Givo29

πŸ’»
GregOriol
GregOriol

πŸ’»
gvde
gvde

πŸ’»πŸ‘€
dallenk
dallenk

πŸ’»πŸ‘€
dvzrv
dvzrv

πŸ’»
ctrowat
ctrowat

πŸ’»
Beuc
Beuc

πŸ’»πŸ›‘οΈ
panlinux
panlinux

πŸ’»
begemoti
begemoti

πŸ’»
dsclassen
dsclassen

πŸ’»
scline
scline

πŸ’»
sky93
sky93

πŸ’»
SergioChan
SergioChan

πŸ’»
ShaunR
ShaunR

πŸ’»
sebastienwarin
sebastienwarin

πŸ’»
tbriceno-hub
tbriceno-hub

πŸ’»
tyearke
tyearke

πŸ’»
Vladyslav78956785786576
Vladyslav78956785786576

πŸ’»
aliuzzz
aliuzzz

πŸ’»
UnAfraid
UnAfraid

πŸ’»
robwdwd
robwdwd

πŸ’»
Poslik
Poslik

πŸ’»
Xake
Xake

πŸ’»
Cosmologist
Cosmologist

πŸ’»
PVi1
PVi1

πŸ’»
OhWelp
OhWelp

πŸ’»
TheNetworkIsDown
TheNetworkIsDown

πŸ’»
tersmitten
tersmitten

πŸ’»
F-i-f
F-i-f

πŸ’»
terrellgf
terrellgf

πŸ’»βš οΈ
surfermarty
surfermarty

πŸ’»
aqr199
aqr199

πŸ’»
snsupersharp
snsupersharp

πŸ’»πŸŒ
skyjou
skyjou

πŸ’»
skeletorgithub
skeletorgithub

πŸ’»
richud
richud

πŸ’»
oshiewan
oshiewan

πŸ’»
oderturm
oderturm

πŸ’»
stevenseeley
stevenseeley

πŸ’»
mcnc-clovett
mcnc-clovett

πŸ’»
m8522s
m8522s

πŸ’»
linusat
linusat

πŸ’»
kruegerj
kruegerj

πŸ’»
kotso
kotso

πŸ’»
jsgh
jsgh

πŸ’»
jkbzh
jkbzh

πŸ’»πŸ“–
itaxer
itaxer

πŸ’»
dwpaulx
dwpaulx

πŸ’»
ahouston
ahouston

πŸ’»
xavloose
xavloose

πŸ’»
evansa
evansa

πŸ’»
eduardomozart
eduardomozart

πŸ’»
edewillians10
edewillians10

πŸ’»
dimaslv
dimaslv

πŸ’»πŸ‘€
simfishing
simfishing

πŸ’»
duhow
duhow

πŸ’»
dschall
dschall

πŸ’»
dschultzca
dschultzca

πŸ’»
kripper
kripper

πŸ’»
3bars
3bars

πŸ’»
kornrunner
kornrunner

πŸ’»
carryel
carryel

πŸ’»
dabeani
dabeani

πŸ’»
xubowin
xubowin

πŸ’»
barreljan
barreljan

πŸ’»πŸ‘€
athos-ribeiro
athos-ribeiro

πŸ’»
apinheiro
apinheiro

πŸ’»
sashashura
sashashura

πŸ’»
A200K
A200K

πŸ’»
k0pak4
k0pak4

πŸ’»
TheBlueMatt
TheBlueMatt

πŸ’»
mchorsley
mchorsley

πŸ’»πŸ‘€
luismrsilva
luismrsilva

πŸ’»
daniel-lucio
daniel-lucio

πŸ’»
Luhrel
Luhrel

πŸ’»
stslayer1
stslayer1

πŸ’»
KrisShannon
KrisShannon

πŸ’»
devsibwarra
devsibwarra

πŸ’»πŸ‘€
kersten-lohmeyer
kersten-lohmeyer

πŸ’»
Harry-Junhua-Huang
Harry-Junhua-Huang

πŸ’»
jsoref
jsoref

πŸ’»βš οΈπŸ‘€
JonBogan
JonBogan

πŸ’»πŸ“–
jayaich
jayaich

πŸ’»
jab60
jab60

πŸ’»
jkrinke
jkrinke

πŸ’»
JamesTilt
JamesTilt

πŸ’»
neclimdul
neclimdul

πŸ’»
hmorandell
hmorandell

πŸ’»
gdsotirov
gdsotirov

πŸ’»
inode64
inode64

πŸ’»
00gh
00gh

πŸ‘€
Dmitrii
Dmitrii

πŸ‘€
Patrick
Patrick

πŸ’»πŸ›‘οΈπŸ“–πŸŒ
Daniel Nylander
Daniel Nylander

πŸ’»πŸŒ
Anton Zhuravlev
Anton Zhuravlev

πŸ’»πŸŒ
John Horne
John Horne

πŸ’»πŸŒ
Vladyslav V. Prodan
Vladyslav V. Prodan

πŸ’»πŸŒ
Ronny Preiss
Ronny Preiss

πŸ’»πŸŒ
Rostyslav Haitkulov
Rostyslav Haitkulov

πŸ’»πŸŒ
Nicolas BUTIN
Nicolas BUTIN

πŸ’»πŸŒ
olafhering
olafhering

πŸ’»
Mojo-OG
Mojo-OG

πŸ’»
abdulm5
abdulm5

πŸ’»
darkdi
darkdi

πŸ’»
alcatron
alcatron

πŸ’»
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome. --- ## License Cacti is licensed under the GNU General Public License v2.0. See [LICENSE](./LICENSE) for details. Copyright (c) 2004-2026 The Cacti Group, Inc.