How to Install InfluxDB on Ubuntu 24.04 VPS: Time-Series Database for Metrics and IoT
Time-series data breaks general-purpose databases. Server metrics, API latencies, IoT sensor feeds, and application telemetry share a distinctive shape: writes are append-only and relentless, queries always filter by time, and cardinality explodes the moment you add a new label. PostgreSQL or MySQL will ingest it -- right up until the indexes balloon, the vacuum stalls, and your dashboards take 40 seconds to render. InfluxDB was engineered for precisely this workload: columnar storage, time-range-aware compression, and a query language that understands windowing and downsampling as first-class operations.
This guide walks you through installing InfluxDB 2.x OSS on an Ubuntu 24.04 LTS VPS, from the official apt repository to a fully configured Telegraf agent writing metrics into your first bucket, with Grafana dashboards, retention policies, scheduled tasks, a hardened Nginx TLS reverse proxy, and automated backups.
Skip the manual setup? Deploy a pre-configured metrics VPS with InfluxDB, Telegraf, and Grafana ready to go. Launch a CloudCore VPS now and start ingesting metrics in minutes.
Table of Contents
What is InfluxDB?
InfluxDB is an open-source time-series database developed by InfluxData. It is purpose-built to ingest, store, and query timestamped data -- the kind produced by monitoring systems, IoT devices, application performance tools, financial tickers, and industrial sensors. Unlike a row-oriented relational database, InfluxDB organizes data into measurements (roughly analogous to tables), with tags (indexed key-value metadata), fields (the actual numeric or string values being measured), and a timestamp as the primary key.
This guide covers InfluxDB 2.x OSS, the current generation that consolidates the 1.x database-and-retention-policy model into a cleaner abstraction of organizations, buckets, and tokens. Version 2.x ships with a built-in web UI, the Flux query language, a tasks engine for scheduled transformations, and an HTTP API that Telegraf, Grafana, client libraries, and any curl command can speak directly. The 2.x line remains the most widely deployed self-hosted option and is what you get from apt install influxdb2 today.
The database pairs natively with Telegraf, InfluxData's collection agent, which bundles more than 200 input plugins for sources like system metrics, Docker, Kubernetes, Nginx, PostgreSQL, MQTT, SNMP, cloud APIs, and custom exec scripts. Together they form one of the most cost-effective metrics stacks you can self-host, and they slot directly into Grafana for visualization and alerting.
Typical use cases include infrastructure monitoring, application performance monitoring, IoT telemetry collection from thousands of devices, DevOps observability, energy and utility tracking, financial market data, and scientific experiment recording. Anywhere you have a stream of numbers arriving with a timestamp, InfluxDB is a natural fit.
Why Self-Host a Time-Series Database?
Managed time-series platforms (InfluxDB Cloud, Datadog, New Relic, Grafana Cloud) are convenient but expensive once your volume grows past a few servers or a handful of sensors. A self-hosted InfluxDB on a CloudCore VPS offers concrete advantages:
- Flat, predictable cost -- A Starter VPS runs a meaningful metrics pipeline for a few euros per month. Datadog charges per host, per custom metric, and per GB of log retention; costs can exceed EUR 500/month for a team running 20 services.
- Data sovereignty -- Metrics, logs, and traces often contain hostnames, internal IPs, user IDs, request paths, and error payloads. Keeping them on infrastructure you control simplifies GDPR compliance, reduces data residency risk, and keeps security-sensitive telemetry out of third-party systems.
- No cardinality tax -- Managed vendors charge extra for custom metrics and high-cardinality dimensions. Your own InfluxDB lets you tag freely within the bounds of your hardware.
- Unlimited retention -- Set retention to whatever fits your disk. Many managed tiers cap retention at 15 or 30 days without an expensive upgrade.
- Full query power -- Write arbitrary Flux, schedule tasks, join across buckets, and export raw data. You are not limited to a vendor's dashboard DSL.
- Vendor independence -- Your collectors, dashboards, and alerts use open protocols (line protocol, Flux, InfluxQL). Migrating to VictoriaMetrics or Prometheus later is an export, not a rewrite.
- Low latency -- When Telegraf, InfluxDB, and your app run in the same region, ingestion and queries complete in single-digit milliseconds.
Cost Comparison at 10M Points Per Day
| Scenario | Self-Hosted InfluxDB (CloudCore Starter) | InfluxDB Cloud (Usage) | Datadog Infrastructure |
|---|---|---|---|
| Monthly cost | EUR 7.99 | ~USD 90-150 | ~USD 15/host x N hosts |
| Retention | Unlimited (disk-bound) | Tiered (extra cost for >30d) | 15 months (enterprise only) |
| Custom metrics | Unlimited | Usage-based | Per-metric billing |
| Data egress | Included | Extra | Extra |
| Multi-tenancy | You control orgs | Paid plans only | Team seats |
Prerequisites
Before you begin, make sure you have:
- A VPS running Ubuntu 24.04 LTS with root or sudo access
- SSH access to your server
- At least 2 GB of RAM (4 GB recommended) and 20 GB of disk space for the database and Telegraf
- A domain name pointed at your server if you plan to expose the UI over TLS (optional but recommended)
- Ports 8086 (InfluxDB API/UI) and 8125/UDP (Telegraf StatsD, optional) available
Recommended Plan: CloudCore Starter>
For a metrics stack collecting from up to ~50 hosts and IoT devices, we recommend the CloudCore Starter plan:>
- 2 vCPU cores
- 4 GB RAM
- 80 GB NVMe SSD
- Unmetered bandwidth
- EUR 7.99/month>
This covers InfluxDB, Telegraf, and a lightweight Grafana instance on the same box. For larger fleets or longer retention, scale up to CloudCore Professional or run Grafana on a separate VPS.
Connect to your server:
ssh root@your-server-ipStep 1: Update System Packages
Refresh the package index and apply any pending updates:
sudo apt update && sudo apt upgrade -yExpected output (abbreviated):
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Reading package lists... Done
Building dependency tree... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.If the kernel was upgraded, reboot before continuing:
sudo rebootInstall a few helper utilities you will use throughout the guide:
sudo apt install -y curl wget gnupg ca-certificates lsb-release ufwStep 2: Add the InfluxData APT Repository
InfluxData publishes signed packages for Debian and Ubuntu at repos.influxdata.com. Using the official repository gives you automatic updates via apt upgrade and guarantees binary authenticity via GPG.
Import the InfluxData signing key to a dedicated keyring file:
curl -fsSL https://repos.influxdata.com/influxdata-archive.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/influxdata-archive-keyring.gpgVerify the key fingerprint (optional but recommended):
gpg --show-keys /etc/apt/keyrings/influxdata-archive-keyring.gpgThe fingerprint should start with 9D53 9D90 D332 8DC7. Add the repository:
echo "deb [signed-by=/etc/apt/keyrings/influxdata-archive-keyring.gpg] https://repos.influxdata.com/debian stable main" \
| sudo tee /etc/apt/sources.list.d/influxdata.listRefresh the package index so apt sees the new repo:
sudo apt updateYou should see Get:... https://repos.influxdata.com/debian stable InRelease in the output, confirming the repository is reachable.
Step 3: Install InfluxDB and the influx CLI
Install the server and the influx command-line client in one step:
sudo apt install -y influxdb2 influxdb2-cliThe influxdb2 package installs the influxd daemon, a systemd unit at /lib/systemd/system/influxdb.service, and default config at /etc/influxdb/config.toml. The influxdb2-cli package installs the influx CLI binary at /usr/bin/influx. Data is stored under /var/lib/influxdb/ and logs go to journald.
Confirm the versions:
influxd version
influx versionExpected output:
InfluxDB 2.7.11 (git: ...) build_date: ...
Influx CLI 2.7.5 (git: ...) build_date: ...Step 4: Start the InfluxDB Service
Enable the service so it starts on boot, then launch it:
sudo systemctl enable influxdb
sudo systemctl start influxdbCheck status:
sudo systemctl status influxdbExpected output:
● influxdb.service - InfluxDB is an open-source, distributed, time series database
Loaded: loaded (/lib/systemd/system/influxdb.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-04-16 10:00:00 UTC; 3s ago
Docs: https://docs.influxdata.com/influxdb/
Main PID: 2345 (influxd)
Tasks: 9 (limit: 4633)
Memory: 62.3M
CPU: 540ms
CGroup: /system.slice/influxdb.service
└─2345 /usr/bin/influxdInfluxDB listens on 127.0.0.1:8086 by default. Verify the API is alive:
curl -s http://localhost:8086/health | jq .Expected output:
{
"name": "influxdb",
"message": "ready for queries and writes",
"status": "pass",
"version": "2.7.11",
"commit": "..."
}If you do not have jq installed, the raw JSON is still readable. The "status": "pass" field confirms the server is ready for setup.
Step 5: Complete the Initial Setup
On first run, InfluxDB 2 has no users, organizations, or buckets. You can complete setup either through the web UI at http://your-server-ip:8086 (requires opening the firewall temporarily) or via the influx setup CLI command. The CLI is faster and scriptable.
Run the interactive setup:
influx setupYou will be prompted for:
> Welcome to InfluxDB 2!
? Please type your primary username: admin
? Please type your password: **
? Please type your password again: **
? Please type your primary organization name: acme
? Please type your primary bucket name: metrics
? Please type your retention period in hours, or 0 for infinite: 720
? Setup with these parameters?
Username: admin
Organization: acme
Bucket: metrics
Retention Period: 720h
...
> Yes
User Organization Bucket
admin acme metricsWhat each value means:
- Username / password -- The initial admin user, used for web UI login.
- Organization -- A top-level tenant that owns buckets, dashboards, tasks, and tokens. Most single-team deployments use one org.
- Bucket -- Where data is stored. Buckets have a retention period after which points are deleted automatically.
- Retention -- In hours.
720h= 30 days. Use0for infinite retention. You can change this later withinflux bucket update.
~/.influxdbv2/configs. Verify by listing buckets:influx bucket listExpected output:
ID Name Retention Shard group duration Organization ID Schema Type
abc123def456... _monitoring 168h0m0s 24h0m0s xyz789... implicit
def456abc123... _tasks 72h0m0s 24h0m0s xyz789... implicit
987fed654cba... metrics 720h0m0s 168h0m0s xyz789... implicitThe _monitoring and _tasks buckets are system buckets for internal telemetry and task logs.
Retrieve the Operator Token
You will need the operator token for Telegraf, Grafana, backups, and API calls. Display the active token:
influx auth list --user adminExpected output (columns truncated):
ID Description Token User Name User ID Permissions
abc123... admin's Token <long-token-string> admin xyz789... [read:/authorizations ...]Copy the full token string somewhere safe. Anyone with this token has full control over your InfluxDB instance. For services like Telegraf, you should later create scoped tokens with only the permissions each service needs.
Create a Telegraf-Scoped Token
Generate a token that can only write to the metrics bucket:
BUCKET_ID=$(influx bucket list --name metrics --hide-headers | awk '{print $1}')
influx auth create \
--org acme \
--description "telegraf-write" \
--write-bucket "$BUCKET_ID"Save the resulting token as TELEGRAF_TOKEN for the next step.
Step 6: Write and Query Your First Data Points
Before attaching Telegraf, test the write and query path with raw line protocol.
Write a Point
InfluxDB's line protocol format is:
measurement,tag1=value1,tag2=value2 field1=value1,field2=value2 timestampWrite a single CPU temperature reading:
influx write \
--org acme \
--bucket metrics \
--precision s \
"cpu_temp,host=server01,region=eu-central value=42.5 $(date +%s)"No output on success. Write a few more points to have something to query:
for i in 1 2 3 4 5; do
influx write --org acme --bucket metrics --precision s \
"cpu_temp,host=server01,region=eu-central value=$((40 + i)) $(date +%s)"
sleep 1
doneQuery with Flux
Flux is InfluxDB 2.x's native query language. It is a pipeline-style functional language where data flows through transformations separated by |>.
influx query --org acme '
from(bucket: "metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "cpu_temp")
|> filter(fn: (r) => r.host == "server01")
'Expected output:
Result: _result
Table: keys: [_start, _stop, _field, _measurement, host, region]
_start:time _stop:time _field:string _measurement:string host:string region:string _time:time _value:float
------------------------------ ------------------------------ -------------------- ---------------------- -------------------- ------------------- ------------------------------ ----------------------------
2026-04-16T09:55:00.000000000Z 2026-04-16T10:00:00.000000000Z value cpu_temp server01 eu-central 2026-04-16T09:59:55.000000000Z 41
2026-04-16T09:55:00.000000000Z 2026-04-16T10:00:00.000000000Z value cpu_temp server01 eu-central 2026-04-16T09:59:56.000000000Z 42
...Aggregate with Flux
Compute the mean temperature in one-minute windows:
influx query --org acme '
from(bucket: "metrics")
|> range(start: -15m)
|> filter(fn: (r) => r._measurement == "cpu_temp")
|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
|> yield(name: "mean")
'Query with InfluxQL (Compatibility)
If you have legacy tooling that speaks InfluxQL, InfluxDB 2 exposes a /query endpoint that accepts it. First, map your bucket to a DBRP (database-retention-policy) pairing:
influx v1 dbrp create \
--bucket-id "$BUCKET_ID" \
--db metrics \
--rp autogen \
--defaultNow query:
curl -s -G "http://localhost:8086/query" \
--header "Authorization: Token <OPERATOR_TOKEN>" \
--data-urlencode "db=metrics" \
--data-urlencode "q=SELECT mean(\"value\") FROM \"cpu_temp\" WHERE time > now() - 15m GROUP BY time(1m)"Both languages query the same underlying data -- use Flux for new work and InfluxQL only when required.
Step 7: Install and Configure Telegraf
Telegraf is the collection agent that reads from sources (system, Docker, Nginx, MQTT, SNMP, etc.) and writes to destinations (InfluxDB, Kafka, Prometheus, etc.). Install it from the same repo:
sudo apt install -y telegrafThis creates /etc/telegraf/telegraf.conf with sensible defaults and a telegraf user. Configure the InfluxDB v2 output and a few input plugins.
Back up and replace the default config:
sudo mv /etc/telegraf/telegraf.conf /etc/telegraf/telegraf.conf.orig
sudo tee /etc/telegraf/telegraf.conf > /dev/null <<'EOF'
Global Agent Configuration
[agent]
interval = "10s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "0s"
flush_interval = "10s"
flush_jitter = "0s"
precision = ""
hostname = ""
omit_hostname = falseOutput: InfluxDB v2
[[outputs.influxdb_v2]]
urls = ["http://127.0.0.1:8086"]
token = "$INFLUX_TOKEN"
organization = "acme"
bucket = "metrics"Inputs: host metrics
[[inputs.cpu]]
percpu = true
totalcpu = true
collect_cpu_time = false
report_active = false[[inputs.disk]]
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"]
[[inputs.diskio]]
[[inputs.mem]]
[[inputs.net]]
[[inputs.processes]]
[[inputs.swap]]
[[inputs.system]]
[[inputs.kernel]]
Optional: Docker containers
[[inputs.docker]]
endpoint = "unix:///var/run/docker.sock"
Optional: Nginx status
[[inputs.nginx]]
urls = ["http://localhost/nginx_status"]
EOFSet the Telegraf token as an environment variable for the service (safer than embedding it in the config):
sudo mkdir -p /etc/default
sudo tee /etc/default/telegraf > /dev/null <<EOF
INFLUX_TOKEN=<paste-your-telegraf-token-here>
EOF
sudo chmod 600 /etc/default/telegrafThe systemd unit at /lib/systemd/system/telegraf.service loads /etc/default/telegraf automatically, exposing INFLUX_TOKEN to the process so the $INFLUX_TOKEN placeholder in telegraf.conf resolves.
Start and enable Telegraf:
sudo systemctl enable telegraf
sudo systemctl restart telegraf
sudo systemctl status telegrafWithin 10-20 seconds, metrics should appear in the metrics bucket. Verify:
influx query --org acme '
from(bucket: "metrics")
|> range(start: -1m)
|> filter(fn: (r) => r._measurement == "cpu")
|> filter(fn: (r) => r._field == "usage_idle")
|> last()
'You should see one row per CPU core. If nothing appears, check sudo journalctl -u telegraf -f for authentication or network errors.
Step 8: Connect Grafana as a Data Source
Grafana is the standard visualization layer for InfluxDB. If you have not installed it yet, see our dedicated guide: How to Install Grafana on Ubuntu 24.04. The short version:
sudo apt install -y apt-transport-https software-properties-common
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/grafana.gpg
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" \
| sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update && sudo apt install -y grafana
sudo systemctl enable --now grafana-serverOpen Grafana at http://your-server-ip:3000 (default login admin / admin), then:
http://localhost:8086.acme
- Token: paste your operator token (or a Grafana-scoped read token)
- Default Bucket: metrics
datasource is working. 3 buckets found.Create a dashboard and try this panel query:
from(bucket: "metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "cpu" and r._field == "usage_user")
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "mean")For a CPU usage gauge, memory graph, disk space, and network throughput, the Telegraf team publishes a ready-made dashboard JSON (ID 15650) that you can import directly.
Step 9: Retention Policies and Downsampling Tasks
Two features keep your disk footprint bounded: bucket retention (automatic deletion of old data) and tasks (scheduled Flux scripts that downsample raw data into coarser buckets).
Update Bucket Retention
List buckets and their retention:
influx bucket listChange retention on the metrics bucket to 14 days:
BUCKET_ID=$(influx bucket list --name metrics --hide-headers | awk '{print $1}')
influx bucket update --id "$BUCKET_ID" --retention 14dCreate a Long-Retention Bucket for Downsamples
influx bucket create --org acme --name metrics_1h --retention 365dWrite a Downsampling Task
Create a Flux task that, every hour, takes the last hour of raw data and writes 1-minute means into metrics_1h. Save this as /tmp/downsample.flux:
option task = { name: "downsample-cpu-1m", every: 1h, offset: 1m, }
from(bucket: "metrics") |> range(start: -task.every) |> filter(fn: (r) => r._measurement == "cpu") |> aggregateWindow(every: 1m, fn: mean, createEmpty: false) |> set(key: "_measurement", value: "cpu_1m") |> to(bucket: "metrics_1h", org: "acme")
Create the task:
influx task create --org acme --file /tmp/downsample.fluxList tasks:
influx task listThe task now runs hourly. Your dashboards can query raw data for the last 14 days from metrics and a full year of 1-minute aggregates from metrics_1h, keeping disk usage predictable and zoom-out queries fast.
Understanding Cardinality
The single most common cause of InfluxDB disk-space and query-performance problems is unbounded tag cardinality. Each unique combination of tag values creates a new series, and each series consumes memory and disk index space.
Check your current series count:
influx query --org acme '
import "influxdata/influxdb/schema"
schema.measurements(bucket: "metrics")
'For a deeper audit:
from(bucket: "metrics")
|> range(start: -1h)
|> group(columns: ["_measurement"])
|> distinct(column: "host")
|> count()Rules of thumb:
- Tags are for low-cardinality indexed metadata:
host,region,environment,service. - Fields are for values and high-cardinality attributes:
user_id,request_id,trace_id,error_message. - Under 1 million total series per bucket is comfortable on a 4 GB VPS. Over 10 million, consider VictoriaMetrics or sharding.
Step 10: Secure InfluxDB Behind an Nginx TLS Reverse Proxy
By default InfluxDB listens on plain HTTP. For any network access beyond the local host, put it behind Nginx with a Let's Encrypt certificate.
Install Nginx and Certbot
sudo apt install -y nginx certbot python3-certbot-nginxRestrict InfluxDB to Localhost
Edit /etc/influxdb/config.toml and ensure:
http-bind-address = "127.0.0.1:8086"Then restart:
sudo systemctl restart influxdbConfigure Nginx
Create /etc/nginx/sites-available/influxdb:
sudo tee /etc/nginx/sites-available/influxdb > /dev/null <<'EOF' server { listen 80; server_name influx.yourdomain.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; server_name influx.yourdomain.com;
# SSL will be inserted by Certbot
# Security headers add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; add_header X-Content-Type-Options nosniff always; add_header X-Frame-Options SAMEORIGIN always;
# Large write bodies (batched Telegraf payloads) client_max_body_size 50m;
location / { proxy_pass http://127.0.0.1:8086; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
# Long-running Flux queries proxy_read_timeout 600s; proxy_send_timeout 600s; proxy_buffering off; } } EOF sudo ln -s /etc/nginx/sites-available/influxdb /etc/nginx/sites-enabled/
Open the Firewall and Issue a Certificate
sudo ufw allow 'Nginx Full' sudo ufw allow OpenSSH sudo ufw --force enablesudo nginx -t sudo systemctl reload nginx
sudo certbot --nginx -d influx.yourdomain.com
Certbot will automatically insert the ssl_certificate and ssl_certificate_key directives and set up a renewal cron.
Update Telegraf to Use HTTPS (Optional, Remote Agents)
If Telegraf runs on another host, point it at the TLS endpoint:
[[outputs.influxdb_v2]]
urls = ["https://influx.yourdomain.com"]
token = "$INFLUX_TOKEN"
organization = "acme"
bucket = "metrics"Now your web UI, API calls, and remote agents all traverse an encrypted connection.
Step 11: Back Up and Restore InfluxDB
InfluxDB ships a consistent online backup via the influx backup subcommand. It snapshots metadata, buckets, and authorizations without stopping the service.
One-Off Backup
sudo mkdir -p /var/backups/influxdb
sudo influx backup /var/backups/influxdb/$(date +%F) \
--token "<OPERATOR_TOKEN>"Expected output:
2026-04-16T10:30:00Z INFO Backing up TSM for shard (...)
2026-04-16T10:30:01Z INFO Backing up KV snapshot
2026-04-16T10:30:02Z INFO Backup completeAutomate with Cron
Create /usr/local/bin/influxdb-backup.sh:
sudo tee /usr/local/bin/influxdb-backup.sh > /dev/null <<'EOF'
#!/bin/bash
set -euo pipefail
BACKUP_ROOT="/var/backups/influxdb"
DATE=$(date +%F-%H%M)
TOKEN=$(cat /root/.influxdb_operator_token)mkdir -p "$BACKUP_ROOT"
/usr/bin/influx backup "$BACKUP_ROOT/$DATE" --token "$TOKEN"
Retain 14 days
find "$BACKUP_ROOT" -maxdepth 1 -type d -mtime +14 -exec rm -rf {} +
EOF
sudo chmod 700 /usr/local/bin/influxdb-backup.shStore the operator token in a root-only file:
sudo tee /root/.influxdb_operator_token > /dev/null <<< "<OPERATOR_TOKEN>"
sudo chmod 600 /root/.influxdb_operator_tokenSchedule nightly:
( sudo crontab -l 2>/dev/null; echo "15 3 * /usr/local/bin/influxdb-backup.sh >> /var/log/influxdb-backup.log 2>&1" ) | sudo crontab -Offsite with Rclone
Copy backups to S3-compatible storage (optional). See our rclone install guide:
rclone sync /var/backups/influxdb remote:influx-backups --log-file=/var/log/rclone-influx.logRestore
To restore a backup onto a fresh server (or overwrite the current database), stop influxd first:
sudo systemctl stop influxdb
sudo influx restore /var/backups/influxdb/2026-04-16 \
--token "<OPERATOR_TOKEN>" \
--full
sudo systemctl start influxdbThe --full flag restores metadata (users, buckets, tokens) in addition to series data. For a single bucket restore into an existing instance, omit --full and use --bucket flags.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
influxd fails to start, port 8086 in use | Another process bound the port | sudo lsof -i :8086 to identify; stop the conflicting service or change http-bind-address in /etc/influxdb/config.toml. |
Telegraf writes return 401 unauthorized | Wrong token or missing write scope | Recreate the token with influx auth create --write-bucket "$BUCKET_ID" and update /etc/default/telegraf. |
| Queries run out of memory | High cardinality or unbounded range() | Add stricter filters, reduce range() window, or downsample into a coarser bucket via a task. |
bucket not found on Grafana test | Wrong organization or bucket name | Match the values exactly to influx org list and influx bucket list output; copy-paste avoids typos. |
| Disk fills faster than expected | Retention not applied, or cardinality blow-up | Check with influx bucket list; lower retention; run the cardinality audit query in Step 9. |
Nginx returns 502 on /api/v2/write | Body larger than client_max_body_size | Raise to 100m or larger and reload Nginx. |
influx backup fails with permission denied | Destination not writable by the invoking user | Run the backup as root or chown the backup directory to influxdb:influxdb. |
| Web UI loads but login fails | Password mismatch, or you set up via CLI without remembering the password | Reset with influx user password --name admin. |
Useful Log Commands
# Tail influxd logs
sudo journalctl -u influxdb -fTail telegraf logs
sudo journalctl -u telegraf -fLast 200 lines of influxd
sudo journalctl -u influxdb -n 200 --no-pagerFAQ
What is the difference between InfluxDB 1.x, 2.x, and 3.x?
InfluxDB 1.x uses InfluxQL with a database-and-retention-policy model. InfluxDB 2.x OSS introduces organizations, buckets, tokens, the Flux query language, an integrated UI, and a tasks engine, while still accepting InfluxQL through a compatibility endpoint. InfluxDB 3.x is a ground-up rewrite on Apache Arrow and Parquet with SQL-first querying and effectively unlimited cardinality, but the OSS edition has different scope and a narrower feature set than 2.x. For self-hosted metrics collection in 2026, InfluxDB 2.x OSS (this guide) remains the mainstream choice, and is what apt install influxdb2 installs from repos.influxdata.com.
Can I run InfluxDB on a small VPS?
Yes. A CloudCore Starter with 2 vCPU and 4 GB RAM comfortably handles thousands of writes per second from Telegraf agents and a handful of Grafana dashboards. Resource consumption scales with series cardinality (the number of unique tag-value combinations) far more than with raw point volume. A single tag with 1 million unique values will eat more RAM than a billion points across 100 hosts. Design tags conservatively and you can run a surprisingly large fleet on a Starter VPS.
Do I need Telegraf to use InfluxDB?
No. Telegraf is the recommended collection agent because it ships with 200+ input plugins for nearly every common source, but InfluxDB accepts writes from any HTTP client using the line protocol. Official client libraries are available for Go, Python, Node.js, Java, C#, Ruby, PHP, and others. You can also write via curl, from MQTT brokers with an InfluxDB plugin, from Kubernetes with Prometheus remote-write, or from Kafka with the Kafka Connect InfluxDB sink.
Flux or InfluxQL - which query language should I use?
For new projects on InfluxDB 2.x, prefer Flux. It is more expressive for transformations, joins, and cross-bucket queries; it powers tasks; and it is the only supported language for new 2.x features. Use InfluxQL when migrating from 1.x, when an external tool only supports SQL-like syntax, or for quick one-liners where Flux feels verbose. Grafana supports both -- pick per data source.
How do I prevent unbounded cardinality?
Never store high-variability values (user IDs, request IDs, timestamps, full URLs, UUIDs) as tags. Store them as fields. Tags are indexed and multiply series count; fields are not. Monitor cardinality regularly with Flux queries against the _monitoring bucket or schema.tagValues(). If you absolutely must query on high-cardinality attributes, consider a secondary store like VictoriaLogs or ClickHouse for those specific dimensions, and keep InfluxDB for low-cardinality aggregates.
How does InfluxDB compare to Prometheus and VictoriaMetrics?
InfluxDB excels at high-resolution time-series storage with an integrated UI, tasks, and flexible queries -- ideal when you need long-term storage, downsampling, and cross-bucket analytics. Prometheus is a pull-based metrics system optimized for service monitoring with alerting; it uses a simpler model and is the cloud-native standard, but it is not designed for long retention or event data. See our Prometheus install guide for a comparison. VictoriaMetrics is a Prometheus-compatible long-term store with outstanding compression and near-unlimited cardinality headroom -- strong when Prometheus is your ecosystem but retention is blowing up; see our VictoriaMetrics install guide. Many production stacks run Prometheus for scraping and alerting, remote-write to VictoriaMetrics for long retention, and InfluxDB for IoT or application-level telemetry that does not fit the Prometheus model.
How do I monitor InfluxDB itself?
InfluxDB writes its own internal metrics to the _monitoring system bucket, including query counts, write throughput, memory usage, and shard statistics. Build a Grafana dashboard querying _monitoring to watch your InfluxDB watch your servers -- meta-monitoring is non-negotiable in production. InfluxData also publishes an official monitoring template you can import via influx apply.
Next Steps
Now that InfluxDB, Telegraf, and Grafana are running on your VPS, here are recommended directions:
- Add application metrics -- Instrument your Node.js, Python, or Go services with the official InfluxDB client libraries. Send counters, gauges, and histograms directly into your
metricsbucket. - Collect IoT telemetry via MQTT -- Add Telegraf's
mqtt_consumerinput plugin to ingest sensor readings from ESP32, Raspberry Pi, or industrial gateways. - Set up alerts -- Use Grafana's alerting engine (or Flux-based InfluxDB checks via
influx alert) to notify Slack, email, or PagerDuty when metrics cross thresholds. - Explore Kapacitor -- InfluxData's streaming analytics engine for complex event processing that InfluxDB tasks cannot express cleanly.
- Compare with alternatives -- Spin up Prometheus or VictoriaMetrics on a second VPS and benchmark the same workload; pick the winner for your use case.
- Harden further -- Add IP allow-lists to the Nginx site, rotate tokens quarterly, and move backups offsite to a separate region or S3 bucket.
- Read the official docs -- docs.influxdata.com/influxdb/ is comprehensive and covers advanced topics like high availability, sharding, and InfluxDB 3 migrations.
Skip the Manual Install -- Get a Pre-Configured Metrics VPS>
Our CloudCore plans give you a clean Ubuntu 24.04 VPS with unmetered bandwidth, NVMe storage, and enough headroom to run InfluxDB, Telegraf, and Grafana side by side.>
- 2-8 vCPU cores depending on plan
- 4-32 GB RAM
- 80-800 GB NVMe SSD
- Full root access and snapshot backups
- European and global locations>
Deploy a CloudCore VPS Now -- Plans start at EUR 7.99/month.