Graphite is a time-series metrics monitoring system that collects, stores, and visualizes numeric data over time. It consists of three core components – Carbon (a daemon that receives metrics), Whisper (a fixed-size database for time-series data), and Graphite-Web (a Django-based web application for rendering graphs and dashboards). Graphite does not collect metrics itself – it receives data pushed from external tools like collectd, StatsD, or custom scripts through a simple plaintext protocol.
This guide walks through installing Graphite 1.1.10 on Ubuntu 24.04 LTS using the APT packages, configuring Carbon for metric ingestion, setting up Graphite-Web with Apache, and sending your first metrics. We also cover integration with collectd and StatsD for production monitoring.
Prerequisites
Before starting, confirm you have the following ready:
- A server running Ubuntu 24.04 LTS with at least 2GB RAM
- Root or sudo access
- A fully qualified domain name or IP address for accessing the web interface
- Ports 2003 (Carbon plaintext), 2004 (Carbon pickle), and 8080 (web UI) available
Step 1: Install Graphite Dependencies on Ubuntu 24.04
Update your package index and install the required system packages. Graphite needs Python 3, Cairo for graph rendering, and several development libraries.
sudo apt update && sudo apt upgrade -y
Install the dependencies needed by Graphite and its web interface:
sudo apt install -y python3 python3-dev python3-pip libcairo2-dev libffi-dev build-essential fontconfig
Step 2: Install Graphite Components
Ubuntu 24.04 provides Graphite packages in its repositories. Install both the Carbon metric receiver and the Graphite web application:
sudo apt install -y graphite-carbon graphite-web
This installs Carbon (metric collection daemon), Whisper (time-series database library), and Graphite-Web (the Django-based dashboard). The packages pull in all required Python dependencies including Django 4.2.
Fix Python 3.12 Compatibility Issue
Ubuntu 24.04 ships Python 3.12, which removed the deprecated imp module. Carbon’s router module still references it, so you need a quick fix before Carbon will start. Edit the routers file:
sudo vi /usr/lib/python3/dist-packages/carbon/routers.py
Find the line that reads import imp (near the top of the file) and replace the import section with:
import importlib
import importlib.machinery
import importlib.util
Next, find the loadRelayRules function (around line 130). Replace the two lines that reference imp:
# Old lines (remove these):
# description = ('.py', 'U', imp.PY_SOURCE)
# handler = imp.load_module('rules', open(path), path, description)
# Replace with:
spec = importlib.util.spec_from_file_location('rules', path)
handler = importlib.util.module_from_spec(spec)
spec.loader.exec_module(handler)
Save and close the file.
Step 3: Configure Carbon
Carbon handles receiving and storing metrics. Its main configuration lives in /etc/carbon/carbon.conf and storage schemas are defined in /etc/carbon/storage-schemas.conf.
Configure carbon.conf
Open the main Carbon configuration file:
sudo vi /etc/carbon/carbon.conf
Verify or set the following values under the [cache] section:
[cache]
# Store data in Whisper format
DATABASE = whisper
# Enable the plaintext listener on port 2003
ENABLE_LOGROTATION = True
USER = _graphite
LINE_RECEIVER_INTERFACE = 0.0.0.0
LINE_RECEIVER_PORT = 2003
PICKLE_RECEIVER_INTERFACE = 0.0.0.0
PICKLE_RECEIVER_PORT = 2004
CACHE_QUERY_INTERFACE = 0.0.0.0
CACHE_QUERY_PORT = 7002
# Maximum data points per metric cached in memory before flushing
MAX_CACHE_SIZE = inf
MAX_UPDATES_PER_SECOND = 500
MAX_CREATES_PER_MINUTE = 50
# Whisper storage path
LOCAL_DATA_DIR = /var/lib/graphite/whisper/
The plaintext listener on port 2003 is what receives metrics from external tools. The pickle listener on port 2004 is used for inter-Carbon communication in clustered setups.
Configure Storage Schemas
Storage schemas define how long Graphite retains data and at what resolution. Open the schemas file:
sudo vi /etc/carbon/storage-schemas.conf
Add or update the following retention policies:
[carbon]
pattern = ^carbon\.
retentions = 60:90d
[default_1min_for_1day]
pattern = .*
retentions = 60s:1d,5m:30d,15m:1y
This configuration means: for the default rule, store 1-minute resolution data for 1 day, 5-minute resolution for 30 days, and 15-minute resolution for 1 year. The [carbon] section handles Graphite’s own internal metrics at 60-second intervals retained for 90 days.
Enable Carbon to start at boot:
sudo systemctl enable carbon-cache
Step 4: Configure Graphite-Web
Graphite-Web is the Django application that renders graphs and provides the dashboard. Its settings live in /etc/graphite/local_settings.py.
Set the Secret Key and Database
Open the local settings file:
sudo vi /etc/graphite/local_settings.py
Uncomment and set the following values. Generate a random secret key for Django:
SECRET_KEY = 'your-unique-random-string-here'
# Time zone - set to your server's timezone
TIME_ZONE = 'UTC'
# Whisper data directory
WHISPER_DIR = '/var/lib/graphite/whisper'
# Database configuration (default SQLite)
DATABASES = {
'default': {
'NAME': '/var/lib/graphite/graphite.db',
'ENGINE': 'django.db.backends.sqlite3',
}
}
Replace your-unique-random-string-here with an actual random string. You can generate one with:
python3 -c "import secrets; print(secrets.token_hex(32))"
Initialize the Database
Run Django migrations to create the Graphite-Web database schema:
sudo PYTHONPATH=/usr/share/graphite-web django-admin migrate --settings=graphite.settings
If the migration succeeds, you should see output listing each applied migration:
Operations to perform:
Apply all migrations: account, admin, auth, contenttypes, dashboard, events, sessions, tagging, tags, url_shortener
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
...
Applying sessions.0001_initial... OK
Set the correct ownership on the database file so the web server can write to it:
sudo chown _graphite:_graphite /var/lib/graphite/graphite.db
Create a superuser account for the Graphite-Web admin interface:
sudo PYTHONPATH=/usr/share/graphite-web django-admin createsuperuser --settings=graphite.settings
Enter a username, email, and password when prompted. This account is used to log into the Graphite dashboard and save graphs.
Step 5: Configure Apache for Graphite-Web
Graphite-Web ships with an Apache configuration. Install Apache and the WSGI module:
sudo apt install -y apache2 libapache2-mod-wsgi-py3
Enable the Graphite virtual host and disable the default site:
sudo a2ensite apache2-graphite
sudo a2dissite 000-default
If you want Graphite-Web to listen on port 8080 instead of the default 80, edit the Apache ports configuration:
sudo vi /etc/apache2/ports.conf
Change the Listen directive:
Listen 8080
Then update the virtual host file to match:
sudo vi /etc/apache2/sites-available/apache2-graphite.conf
Change the VirtualHost line from *:80 to *:8080:
<VirtualHost *:8080>
Collect the static files (CSS, JavaScript) that Graphite-Web needs:
sudo PYTHONPATH=/usr/share/graphite-web django-admin collectstatic --noinput --settings=graphite.settings
Step 6: Start Carbon and Graphite-Web
Start the Carbon cache daemon and Apache to bring both the metric receiver and web interface online.
sudo systemctl start carbon-cache
sudo systemctl restart apache2
Verify that Carbon is running and listening on port 2003:
sudo systemctl status carbon-cache
The service should show active (running):
● carbon-cache.service - Graphite Carbon Cache
Loaded: loaded (/lib/systemd/system/carbon-cache.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-03-22 10:00:00 UTC; 5s ago
Main PID: 12345 (carbon-cache)
Confirm Carbon is listening on the expected ports:
ss -tlnp | grep -E '2003|2004|7002'
You should see Carbon bound to ports 2003 (plaintext), 2004 (pickle), and 7002 (cache query):
LISTEN 0 128 0.0.0.0:2003 0.0.0.0:* users:(("carbon-cache",pid=12345,fd=7))
LISTEN 0 128 0.0.0.0:2004 0.0.0.0:* users:(("carbon-cache",pid=12345,fd=8))
LISTEN 0 128 0.0.0.0:7002 0.0.0.0:* users:(("carbon-cache",pid=12345,fd=9))
Check that Apache is serving Graphite-Web:
sudo systemctl status apache2
Open your browser and navigate to http://your-server-ip:8080. You should see the Graphite-Web dashboard with a tree menu on the left side for browsing metrics.
Step 7: Send Test Metrics Using the Plaintext Protocol
Graphite’s Carbon daemon accepts metrics through a simple plaintext protocol on port 2003. The format is: metric.name value timestamp. Send a few test data points to verify the pipeline works end to end.
echo "test.cpu.load 0.75 $(date +%s)" | nc -q0 localhost 2003
echo "test.memory.used 4096 $(date +%s)" | nc -q0 localhost 2003
echo "test.disk.free 50000 $(date +%s)" | nc -q0 localhost 2003
Install netcat if it is not already available:
sudo apt install -y netcat-openbsd
After sending metrics, verify that Whisper database files were created:
find /var/lib/graphite/whisper/test -name "*.wsp"
You should see the Whisper files matching the metrics you sent:
/var/lib/graphite/whisper/test/cpu/load.wsp
/var/lib/graphite/whisper/test/memory/used.wsp
/var/lib/graphite/whisper/test/disk/free.wsp
You can also read a Whisper file directly to confirm data is stored:
whisper-fetch /var/lib/graphite/whisper/test/cpu/load.wsp | tail -5
Now go to the Graphite-Web dashboard in your browser. Expand the tree menu on the left: Graphite > test > cpu and click load. You should see your test data point plotted on the graph.
Step 8: Create Dashboards in Graphite
Graphite-Web includes a built-in dashboard feature. Click Dashboard in the top menu to open the dashboard editor. From here you can create graphs by typing metric paths directly or dragging metrics from the tree browser.
To create a graph via the Graphite render API, use a URL like this:
http://your-server-ip:8080/render?target=test.cpu.load&from=-1hours&format=png
The render API supports several useful functions for aggregating and transforming data:
sumSeries()– sum multiple metrics togetheraverageSeries()– average across multiple metricsmovingAverage(metric, 10)– smooth noisy data with a rolling averagescale(metric, 0.001)– convert units (e.g., bytes to kilobytes)alias(metric, "CPU Load")– rename metrics in the graph legend
For production dashboards, most teams pair Graphite with Grafana as a frontend. Grafana has native Graphite data source support and provides much richer visualization options, alerts, and team features.
Step 9: Integrate with collectd and StatsD
Graphite shines when paired with metric collection agents that push data automatically. The two most common integrations are collectd for system metrics and StatsD for application metrics.
Configure collectd to Send Metrics to Graphite
Install collectd on each server you want to monitor:
sudo apt install -y collectd
Edit the collectd configuration to enable the write_graphite plugin:
sudo vi /etc/collectd/collectd.conf
Add the following plugin configuration, replacing 10.0.1.50 with your Graphite server’s IP address:
LoadPlugin write_graphite
<Plugin write_graphite>
<Node "graphite">
Host "10.0.1.50"
Port "2003"
Protocol "tcp"
ReconnectInterval 0
LogSendErrors true
Prefix "collectd."
StoreRates true
AlwaysAppendDS false
EscapeCharacter "_"
</Node>
</Plugin>
Also enable the system monitoring plugins you need. Uncomment these lines in the same file:
LoadPlugin cpu
LoadPlugin df
LoadPlugin disk
LoadPlugin interface
LoadPlugin load
LoadPlugin memory
LoadPlugin swap
Restart collectd to apply the configuration:
sudo systemctl restart collectd
sudo systemctl enable collectd
After a minute, check Graphite-Web. You should see a new collectd folder in the metric tree with CPU, memory, disk, and network metrics flowing in automatically.
Configure StatsD for Application Metrics
StatsD is a network daemon that aggregates application metrics and flushes them to Graphite. Install it via Node.js:
sudo apt install -y nodejs npm
sudo npm install -g statsd
Create a StatsD configuration file:
sudo mkdir -p /etc/statsd
sudo vi /etc/statsd/config.js
Add the following configuration, pointing StatsD to your Graphite Carbon instance:
{
graphitePort: 2003,
graphiteHost: "127.0.0.1",
port: 8125,
backends: ["./backends/graphite"],
graphite: {
legacyNamespace: false
}
}
Start StatsD manually to test:
statsd /etc/statsd/config.js &
Send a test counter metric to StatsD using netcat:
echo "app.logins:1|c" | nc -u -q0 localhost 8125
After the StatsD flush interval (default 10 seconds), the metric appears in Graphite under the stats tree. Applications can send counters, gauges, timers, and sets to StatsD over UDP, making it easy to instrument any application without blocking on network I/O.
Step 10: Configure UFW Firewall for Graphite
If UFW firewall is enabled on your server, open the required ports for Carbon and the web interface. Restrict access to trusted networks only – replace 10.0.1.0/24 with your monitoring network CIDR.
sudo ufw allow from 10.0.1.0/24 to any port 2003 proto tcp comment "Carbon plaintext"
sudo ufw allow from 10.0.1.0/24 to any port 2004 proto tcp comment "Carbon pickle"
sudo ufw allow from 10.0.1.0/24 to any port 8080 proto tcp comment "Graphite-Web"
If you are running StatsD, also open its UDP port:
sudo ufw allow from 10.0.1.0/24 to any port 8125 proto udp comment "StatsD"
Verify the firewall rules are active:
sudo ufw status verbose
The output should show your new rules allowing traffic on ports 2003, 2004, 8080, and optionally 8125.
The following table summarizes all ports used by a Graphite deployment:
| Port | Protocol | Service |
|---|---|---|
| 2003 | TCP | Carbon plaintext receiver |
| 2004 | TCP | Carbon pickle receiver |
| 7002 | TCP | Carbon cache query |
| 8080 | TCP | Graphite-Web (Apache) |
| 8125 | UDP | StatsD (optional) |
Conclusion
You now have a working Graphite monitoring stack on Ubuntu 24.04 with Carbon receiving metrics on port 2003, Whisper storing time-series data, and Graphite-Web serving dashboards through Apache. For production deployments, add SSL termination with a reverse proxy, set up Prometheus and Grafana alongside Graphite for alerting, and configure Whisper retention policies based on your actual data volume and query patterns. Consider running multiple Carbon relay instances behind a load balancer if you expect to ingest more than 100,000 metrics per minute.