Install InfluxDB on VPS Time Series Database

Install InfluxDB on VPS - Time Series Database

June 2026 · 10 min read

InfluxDB is a high-performance time series database designed to store massive amounts of timestamped data points — perfect for tracking CPU usage, memory consumption, disk I/O, sensor temperatures, stock prices, IoT metrics, and any data that changes over time with precise timestamps. Unlike relational databases (MySQL, PostgreSQL) that optimize for structured static data, InfluxDB specializes in fast writes and queries of metrics — it compresses data exceptionally well, using only 20-30% of the disk space compared to traditional SQL databases. This guide covers installing InfluxDB 2.x on your VPS, setting up Telegraf agent for automatic metric collection, and visualizing everything in Grafana.

Understanding Time Series Databases

A time series database stores data with associated timestamps — every metric value comes with a precise timestamp, enabling rapid queries and analysis over time. Key components include:

Traditional databases like Elasticsearch or SQL databases perform poorly with this use case — they're slow at time-based queries, aggregation, and analytics. InfluxDB was engineered specifically for reading and writing metrics efficiently while minimizing resource consumption.

Installing InfluxDB 2.x on VPS

# For Ubuntu/Debian
curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key | apt-key add -
echo "deb [signed-by=/usr/share/keyrings/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main" | tee /etc/apt/sources.list.d/influxdata.list

apt update && apt install -y influxdb2 influxdb2-cli

# For CentOS/RHEL
cat > /etc/yum.repos.d/influxdata.repo << 'EOF'
[influxdata]
name = InfluxData Repository
baseurl = https://repos.influxdata.com/rhel/\$releasever/\$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdata-archive.key
EOF

yum install -y influxdb2

# Start and enable the service
systemctl start influxdb
systemctl enable influxdb

Creating Organizations and Buckets

InfluxDB uses the term "bucket" instead of "database" but serves the same purpose — a bucket is a storage space for time series data with its own namespace and retention settings.

# Set environment variables for CLI
export INFLUX_HOST=http://localhost:8086
export INFLUX_ORG=my-org
export INFLUX_BUCKET=metrics

# Initialize InfluxDB (web UI at http://localhost:8086)
influx setup \
  --org my-org \
  --bucket metrics \
  --retention 30d \
  --username admin \
  --password MySecurePass123! \
  --force

# Create an API token for Telegraf/Grafana
influx auth create \
  --org my-org \
  --description "Telegraf token" \
  --read-bucket metrics \
  --write-bucket metrics

Installing Telegraf Agent

Telegraf is a lightweight agent that runs on your VPS and automatically collects system metrics (CPU, memory, disk, network) then ships them to InfluxDB — eliminating the need to manually write data.

# Install Telegraf
apt install -y telegraf

# Create configuration
cat > /etc/telegraf/telegraf.conf << 'EOF'
[global_tags]
  host = "vps-01"
  environment = "production"

[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = "ns"
  logfile = ""
  hostname = ""
  omit_hostname = false

[[outputs.influxdb_v2]]
  urls = ["http://localhost:8086"]
  token = "YOUR_INFLUX_TOKEN"
  organization = "my-org"
  bucket = "metrics"

[[inputs.system]]
  # CPU, memory, disk, network metrics

[[inputs.disk]]
  ignore_fs = ["tmpfs", "devtmpfs"]

[[inputs.mem]]

[[inputs.net]]

[[inputs.cpu]]
  collect_cpu_time = true
  report_by_cpu = true

[[inputs.processes]]

[[inputs.docker]]
  endpoint = "unix:///var/run/docker.sock"
  container_names = []
  timeout = "5s"

EOF

# Replace YOUR_INFLUX_TOKEN with the token from the previous step

# Start Telegraf
systemctl start telegraf
systemctl enable telegraf

# Check status
systemctl status telegraf

Setting Retention Policies and Downsampling

Retention policies control how long InfluxDB keeps your data — choosing appropriate retention dramatically reduces disk usage over time.

# Set retention policy for metrics bucket to 30 days
influx bucket update \
  --org my-org \
  --name metrics \
  --retention 720h

# List all buckets
influx bucket list --org my-org

# Downsampling example using Flux: compress data older than 7 days to 1-hour intervals
# Use aggregateWindow() in your Flux queries:
# from(bucket:"metrics")
#   |> range(start: -30d)
#   |> aggregateWindow(every: 1h, fn: mean)
#   |> to(bucket: "metrics-downsampled")

Connecting Grafana to InfluxDB

Grafana uses Flux query language to pull metric data from InfluxDB and create real-time dashboards visualizing your VPS health.

# Assuming Grafana runs at http://localhost:3000
# Log in, then navigate to: Home → Connections → Data sources → Add data source

# Select InfluxDB
# Query language: Flux
# URL: http://localhost:8086
# Organization: my-org
# Token: YOUR_INFLUX_TOKEN
# Bucket: metrics
# Save & test → should see "Successfully queried the InfluxDB API"

# Create a simple dashboard:
# Click + → Panel → Select InfluxDB data source
# Enter this Flux query:
# from(bucket: "metrics")
#   |> range(start: -24h)
#   |> filter(fn: (r) => r._measurement == "cpu")
#   |> filter(fn: (r) => r._field == "usage_system")
#   |> aggregateWindow(every: 1m, fn: mean)

Flux Query Language Basics

Flux is a functional query language designed for InfluxDB — similar to SQL but with more powerful data processing capabilities.

# Read metrics from the last 24 hours
from(bucket: "metrics")
  |> range(start: -24h)

# Filter by measurement type
from(bucket: "metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "cpu")

# Filter by field
from(bucket: "metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "cpu")
  |> filter(fn: (r) => r._field == "usage_system")

# Aggregate to 1-minute intervals
from(bucket: "metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "cpu")
  |> aggregateWindow(every: 1m, fn: mean)

# Group by host
from(bucket: "metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "mem")
  |> group(columns: ["host"])
  |> aggregateWindow(every: 5m, fn: mean)

# Calculate 95th percentile of response times
from(bucket: "metrics")
  |> range(start: -7d)
  |> filter(fn: (r) => r._measurement == "http_request")
  |> filter(fn: (r) => r._field == "response_time_ms")
  |> quantile(q: 0.95)

Setting Up Alerts in InfluxDB

# Create a Notification Endpoint (Email, Slack, Webhook, etc.)
# In Web UI: Alerting → Notification Endpoints → Create

# Create an Alert Rule:
# Alerting → Alert Rules → Create

# Example Flux query for alert when CPU > 80% for 5 minutes:
# option task = {name: "High CPU Alert", every: 5m, offset: 0s}

# from(bucket: "metrics")
#   |> range(start: -5m)
#   |> filter(fn: (r) => r._measurement == "cpu")
#   |> filter(fn: (r) => r._field == "usage_system")
#   |> aggregateWindow(every: 1m, fn: mean)
#   |> map(fn: (r) => ({r with _value: r._value / 100.0}))
#   |> filter(fn: (r) => r._value > 0.8)
#   |> group(columns: ["host"])

# Set threshold: If count() > 0 for 1 minute then Fire
# Then: Send notification to your configured endpoint
Tip: For monitoring multiple VPS servers, use remote write in Telegraf on each instance. Run InfluxDB on your primary server and have all Telegraf instances push metrics to it via HTTP — this centralizes all data for easy analysis and correlation.

Verifying InfluxDB is Working Correctly

# Check InfluxDB API health
curl -s -i http://localhost:8086/health

# Enter InfluxDB shell
influx

# List all buckets
buckets

# Query recent metrics using Flux
from(bucket: "metrics") |> range(start: -1h) |> limit(n: 5)

# List all measurement names in metrics bucket
from(bucket: "metrics") |> range(start: -1h) |> group(columns: ["_measurement"]) |> distinct(column: "_measurement")

# Verify Telegraf is sending data
from(bucket: "metrics") |> range(start: -5m) |> filter(fn: (r) => r._measurement == "cpu")

# Exit the shell
exit
Tip: Use influx query from the command line to run Flux queries without entering interactive mode — for example: influx query 'from(bucket:"metrics") |> range(start: -24h) |> limit(n: 10)' --org my-org

Troubleshooting Common Issues

Error: "bucket not found" when querying

The bucket specified in Telegraf or Grafana configuration doesn't exist or has a different name.

# List available buckets
influx bucket list --org my-org

# If missing, create it
influx bucket create --org my-org --name metrics --retention 720h

# Verify bucket names match exactly in Telegraf and Grafana configs

Telegraf not sending data even though service is running

Token may have expired or configuration is incorrect — check Telegraf logs.

# View Telegraf logs
journalctl -u telegraf -n 50 -f

# If you see "401 Unauthorized", create a new token
influx auth create --org my-org --description "Telegraf" --read-bucket metrics --write-bucket metrics

# Copy the new token into /etc/telegraf/telegraf.conf and reload
systemctl reload telegraf

InfluxDB consuming excessive memory

InfluxDB caches data in memory — reduce cache limits or shorten retention period.

# In /etc/default/influxdb (Debian/Ubuntu):
INFLUXDB_HEAP_SIZE=2gb

# Restart InfluxDB
systemctl restart influxdb

# Check current memory usage:
free -h
systemctl status influxdb | grep Memory

Grafana shows no data despite InfluxDB having metrics

Bucket name in data source may be incorrect or time range doesn't match when data was collected.

# In Grafana: Configuration → Data sources → InfluxDB
# Verify "Bucket" value matches the actual bucket name

# Try selecting "Last 24 hours" instead of "Last 7 days"

# Use the Explore tab to test queries and time ranges directly

Flux queries are slow or timing out

Queries touching too much data need optimization — use aggregation and limiting.

# Use aggregateWindow() to reduce resolution
from(bucket: "metrics")
  |> range(start: -30d)
  |> filter(fn: (r) => r._measurement == "cpu")
  |> aggregateWindow(every: 1h, fn: mean)

# Use limit() to reduce record count
from(bucket: "metrics")
  |> range(start: -24h)
  |> limit(n: 1000)

# Use sample() for statistical sampling
from(bucket: "metrics")
  |> range(start: -7d)
  |> sample(n: 100)

Frequently Asked Questions

How does InfluxDB differ from Prometheus?

Prometheus uses a pull model — the Prometheus server pulls metrics from exporters (like node_exporter). InfluxDB uses a push model — Telegraf or your application pushes metrics to InfluxDB. Prometheus excels at alerting and short-term metrics (default 15-day retention). InfluxDB excels at long-term storage and historical analysis thanks to superior compression. Both work great with Grafana for visualization.

Can InfluxDB do clustering and replication?

The open source InfluxDB doesn't include built-in clustering — clustering requires InfluxDB Enterprise (paid). For basic high availability on a single VPS, use regular backups with influx backup or set up dual writes where Telegraf sends data to both primary and secondary InfluxDB instances.

What data does InfluxDB accept (tags vs fields vs timestamps)?

InfluxDB requires: measurement (name), timestamp (time), fields (numeric values). Tags are optional but indexed metadata as strings — too many unique tag values (high cardinality) increases memory usage. Fields are numerical values meant for aggregation (mean, sum, max) and aren't indexed — using fields instead of tags reduces memory pressure. Design your schema carefully to avoid high cardinality tags.