
Promql Cli
- 2k installs
- 178 repo stars
- Updated August 1, 2026
- samber/cc-skills
promql-cli is an agent skill that CLI for querying Prometheus and PromQL-compatible engines (Thanos, Cortex, VictoriaMetrics, Grafana Mimir, Grafana Tempo.
About
promql cli Prometheus Query CLI Skill promql cli github com nalbury promql cli is a Go CLI for querying analyzing and visualizing Prometheus metrics plus PromQL fundamentals Read the relevant reference file s before executing tasks File When to read references installation md User needs to install promql cli or set up configuration hosts auth token password multi host references usage md User wants to discover metrics exporters labels run queries or choose output formats references graphing md User wants to visualize Prometheus data as an ASCII chart in the terminal references debugging md User is investigating a performance issue latency errors or saturation references promql reference md User needs help writing PromQL understanding metric types functions or aggregations For most tasks read references usage md For PromQL help read references promql reference md When debugging read both references debugging md and references promql reference md
- description: CLI for querying Prometheus and PromQL-compatible engines (Thanos, Cortex, VictoriaMetrics, Grafana Mimir,
- compatibility: Requires promql-cli and jq
- homepage: https://github.com/samber/cc-skills
- Follow promql-cli SKILL.md steps and documented constraints.
- Follow promql-cli SKILL.md steps and documented constraints.
Promql Cli by the numbers
- 1,962 all-time installs (skills.sh)
- +17 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #112 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
promql-cli capabilities & compatibility
- Capabilities
- description: cli for querying prometheus and pro · compatibility: requires promql cli and jq · homepage: https://github.com/samber/cc skills · follow promql cli skill.md steps and documented
- Use cases
- orchestration
What promql-cli says it does
description: CLI for querying Prometheus and PromQL-compatible engines (Thanos, Cortex, VictoriaMetrics, Grafana Mimir, Grafana Tempo...) — instant queries, range queries, metric discovery (metrics/la
compatibility: Requires promql-cli and jq
homepage: https://github.com/samber/cc-skills
npx skills add https://github.com/samber/cc-skills --skill promql-cliAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2k |
|---|---|
| repo stars | ★ 178 |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 1, 2026 |
| Repository | samber/cc-skills ↗ |
When should an agent use promql-cli and what problem does it solve?
CLI for querying Prometheus and PromQL-compatible engines (Thanos, Cortex, VictoriaMetrics, Grafana Mimir, Grafana Tempo...) — instant queries, range queries, metric discovery (metrics/labels/meta sub
Who is it for?
Developers invoking promql-cli as documented in the skill source.
Skip if: Skip when requirements fall outside promql-cli documented scope.
When should I use this skill?
CLI for querying Prometheus and PromQL-compatible engines (Thanos, Cortex, VictoriaMetrics, Grafana Mimir, Grafana Tempo...) — instant queries, range queries, metric discovery (metrics/labels/meta sub
What you get
Outputs aligned with the promql-cli SKILL.md workflow and stated deliverables.
- PromQL query results
- Metric and label discovery output
By the numbers
- Skill version 1.1.3 from samber/cc-skills
- Supports 6 PromQL-compatible backends including Prometheus and Grafana Mimir
- Offers 4 output formats: table, CSV, JSON, and graph
Files
promql-cli — Prometheus Query CLI Skill
promql-cli (github.com/nalbury/promql-cli) is a Go CLI for querying, analyzing, and visualizing Prometheus metrics, plus PromQL fundamentals.
Reference Files
Read the relevant reference file(s) before executing tasks:
| File | When to read |
|---|---|
references/installation.md | User needs to install promql-cli or set up configuration (hosts, auth, token, password, multi-host) |
references/usage.md | User wants to discover metrics/exporters/labels, run queries, or choose output formats |
references/graphing.md | User wants to visualize Prometheus data as an ASCII chart in the terminal |
references/debugging.md | User is investigating a performance issue, latency, errors, or saturation |
references/promql-reference.md | User needs help writing PromQL, understanding metric types, functions, or aggregations |
For most tasks, read references/usage.md. For PromQL help, read references/promql-reference.md. When debugging, read both references/debugging.md and references/promql-reference.md.
Setup Check
Before running any query, verify that a host is configured:
promql 'up' # succeeds if host is reachable; fails with connection error if not configured
# or
promql --host xxx 'up'Recognize these errors as a configuration/auth problem and refer to references/installation.md:
| Error | Cause |
|---|---|
dial tcp ... connection refused | No host running at the configured address |
dial tcp ... no such host | Hostname not resolved — wrong host in config |
error querying prometheus: ...401... | Bearer token missing or invalid |
error querying prometheus: ...403... | Token valid but insufficient permissions |
please specify an authentication type | Auth flags partially set — use config file instead |
If any of these appear, do not create config files on behalf of the user — config files may contain credentials (tokens, passwords) that must never pass through an LLM. Instead, guide the user to set it up themselves:
"Please create~/.promql-cli.yamlmanually with your Prometheus host (and credentials if needed). Seereferences/installation.mdfor the exact format. Let me know once it's ready."
Only after the user confirms the config is in place should you proceed with queries.
Quick Command Reference
promql 'up' # instant query
promql 'rate(http_requests_total[5m])' --start 1h # range query (ASCII graph)
promql 'up' --output csv # CSV output
promql 'up' --output json # JSON output
promql metrics # list all metric names
promql labels <metric> # list labels for a metric
promql meta <metric> # show metric type and help
promql --config ~/.promql-cli-prod.yaml 'up' # target a specific hostKey Principles
1. Use `rate()` on counters, never raw values — raw counters only ever increase; the absolute value is meaningless. rate() gives the per-second change rate, which is what you actually care about. 2. When debugging, isolate a single instance — aggregating across replicas masks per-instance anomalies. A single overloaded pod hidden behind healthy peers won't show up in averages. 3. Filter early with label matchers in the innermost selector — Prometheus evaluates selectors before functions, so filtering late means scanning all time series. Early filters reduce data scanned and query latency. 4. For histograms, keep `le` in the `by` clause before histogram_quantile() — the function needs all le buckets to interpolate percentiles; dropping le early produces NaN or wrong results. 5. Prefer `--output graph` for range queries — ASCII sparklines convey trend direction (rising, falling, spiking) in a compact format that LLMs parse well; raw timestamp tables require mental modeling. 6. Store credentials in `~/.promql-cli.yaml` and `~/.promql_token`, chmod 600 — passing tokens as CLI args exposes them in shell history and process listings.
This skill is not exhaustive. Please refer to the official promql-cli documentation and examples for up-to-date information. Context7 can help as a discoverability platform.
If you encounter a bug or unexpected behavior in promql-cli itself, open an issue at https://github.com/nalbury/promql-cli/issues.
{
"skill_name": "promql-cli",
"evals": [
{
"id": 1,
"prompt": "Show me the current request count for my web API using promql-cli.",
"expected_output": "Should use rate() with a time window, not raw counter. Should explain why raw counters are meaningless.",
"files": [],
"assertions": [
{
"id": "1.1",
"description": "uses rate() function — does NOT suggest querying raw counter like 'http_requests_total' without rate()"
},
{
"id": "1.2",
"description": "includes a time window in rate() e.g. [5m] or [1m]"
},
{
"id": "1.3",
"description": "explains why raw counter values are not meaningful (they only ever increase)"
}
]
},
{
"id": 2,
"prompt": "Some pods in my Kubernetes cluster seem slower than others. How do I debug which pod is causing high latency?",
"expected_output": "Should recommend isolating by pod/instance label, not aggregating across all pods. Should not suggest avg across fleet.",
"files": [],
"assertions": [
{
"id": "2.1",
"description": "recommends filtering/isolating by pod or instance label to identify the specific slow pod"
},
{
"id": "2.2",
"description": "does NOT suggest using avg() or sum() across all pods as the first debugging step"
},
{
"id": "2.3",
"description": "suggests using histogram or rate-based latency metrics (not raw values)"
},
{
"id": "2.4",
"description": "includes label matcher syntax to filter by specific pod or instance"
}
]
},
{
"id": 3,
"prompt": "I think I'm querying a metric that doesn't exist or has unexpected labels. How can I check what time series are currently active for 'http_request_duration_seconds' in promql-cli?",
"trap": "Without the skill, the model suggests a raw PromQL query like `{__name__=\"http_request_duration_seconds\"}` or `promql metrics` (for listing all metric names). Neither is the right tool for inspecting active series with their label sets — promql-cli has a dedicated `promql series` subcommand for this.",
"expected_output": "Use `promql series 'http_request_duration_seconds'` — the CLI subcommand for finding active time series matching a selector, showing their label sets. Not a raw PromQL query, not `promql metrics`.",
"files": [],
"assertions": [
{
"id": "3.1",
"description": "suggests the 'promql series' subcommand"
},
{
"id": "3.2",
"description": "does NOT suggest a raw PromQL query like `{__name__=~\"...\"}` or `{__name__=\"...\"}` as the primary approach for inspecting active series"
},
{
"id": "3.3",
"description": "does NOT confuse 'promql series' with 'promql metrics' (which lists metric names, not active time series with label sets)"
},
{
"id": "3.4",
"description": "shows correct CLI syntax with a selector argument (e.g., `promql series 'http_request_duration_seconds'`)"
}
]
},
{
"id": 4,
"prompt": "I want to see the error rate trend for my API over the last 2 hours.",
"expected_output": "Range query with --start 2h, --output graph recommended, rate() on error counter.",
"files": [],
"assertions": [
{
"id": "4.1",
"description": "uses --start 2h (or equivalent range query flag)"
},
{
"id": "4.2",
"description": "recommends --output graph for visualizing the trend"
},
{
"id": "4.3",
"description": "uses rate() on the error counter metric"
},
{
"id": "4.4",
"description": "does NOT just suggest a plain instant query without a time range"
}
]
},
{
"id": 5,
"prompt": "How do I configure promql-cli to connect to my Prometheus? My bearer token is: eyJhbGciOiJSUzI1NiJ9.secret123",
"expected_output": "Should NOT write config file content with the token. Should guide user to create the config manually. Mentions chmod 600.",
"files": [],
"assertions": [
{
"id": "5.1",
"description": "does NOT write out config file content containing the token value"
},
{
"id": "5.2",
"description": "instructs user to create the config file manually themselves"
},
{
"id": "5.3",
"description": "mentions chmod 600 to protect the credentials file"
},
{
"id": "5.4",
"description": "does NOT suggest passing the token as a CLI flag (which would expose it in shell history)"
}
]
},
{
"id": 6,
"prompt": "I have a PromQL query for request rate across all services: `rate(http_requests_total[5m])`. I want to filter to only show results for service='payment'. I've been adding the filter like this:\n\n`rate(http_requests_total[5m]) and on(service) up{service=\"payment\"}`\n\nIs this the right approach?",
"trap": "Without the skill, the model says 'yes that works' or suggests minor syntax variations without flagging the underlying issue. The correct fix is to put label matchers in the innermost metric selector — `rate(http_requests_total{service=\"payment\"}[5m])`. The AND approach scans all time series before filtering and may produce incorrect results.",
"expected_output": "`rate(http_requests_total{service=\"payment\"}[5m])` — label matchers belong in the metric selector. The AND on(service) approach scans everything before filtering; inner-selector placement is evaluated at ingest and is both correct and more efficient.",
"files": [],
"assertions": [
{
"id": "6.1",
"description": "recommends putting the label filter inside the metric selector: `http_requests_total{service=\"payment\"}`"
},
{
"id": "6.2",
"description": "does NOT endorse the `AND on(service) up{...}` pattern as correct or equivalent"
},
{
"id": "6.3",
"description": "explains WHY inner-selector filtering is preferable (scans less data, correct cardinality)"
},
{
"id": "6.4",
"description": "provides the corrected query with labels in the innermost selector"
}
]
},
{
"id": 7,
"prompt": "I installed promql-cli and set PROMETHEUS_HOST=localhost:9090 in my shell. When I run `promql 'up'` I get:\n\n'Error: failed to query: Get \"http://localhost:9090/api/v1/query\": dial tcp 127.0.0.1:9090: connect: connection refused'\n\nWhat should I do?",
"trap": "Without the skill, the model focuses on whether Prometheus is actually running at that address, suggesting 'check if Prometheus is up' or 'verify the port'. It misses that promql-cli reads configuration from a config file that may override the env var, and that the user should verify which host the tool is actually connecting to — not create a new config file on their behalf.",
"expected_output": "Identify as a configuration/connectivity problem. Guide the user to verify their promql-cli configuration (config file takes precedence over env vars). Do NOT write a config file on behalf of the user. Do NOT suggest modifying the query.",
"files": [],
"assertions": [
{
"id": "7.1",
"description": "identifies this as a host configuration/connectivity problem (not a query syntax error)"
},
{
"id": "7.2",
"description": "guides the user to verify their promql-cli configuration — config file and env var precedence"
},
{
"id": "7.3",
"description": "does NOT write a promql-cli config file on behalf of the user"
},
{
"id": "7.4",
"description": "does NOT suggest modifying the PromQL query `'up'` to resolve the connection error"
}
]
},
{
"id": 8,
"prompt": "How do I list all the available metrics in my Prometheus using promql-cli?",
"expected_output": "Uses 'promql metrics' subcommand, not a raw PromQL query.",
"files": [],
"assertions": [
{
"id": "8.1",
"description": "suggests the 'promql metrics' subcommand"
},
{
"id": "8.2",
"description": "does NOT suggest a PromQL query like `{__name__=~\".+\"}` as the primary approach"
},
{
"id": "8.3",
"description": "shows correct CLI syntax for the metrics subcommand"
}
]
},
{
"id": 9,
"prompt": "What is the current number of active HTTP connections to my server? Can you show me the raw value?",
"expected_output": "Distinguishes between gauge (raw value OK) and counter (needs rate()). Explains the difference.",
"files": [],
"assertions": [
{
"id": "9.1",
"description": "distinguishes between gauge metrics (raw value meaningful) and counter metrics (need rate())"
},
{
"id": "9.2",
"description": "if the metric is a gauge: confirms raw value is appropriate for active connections"
},
{
"id": "9.3",
"description": "suggests checking metric type with 'promql meta <metric>' if type is unknown"
}
]
},
{
"id": 10,
"prompt": "I deployed a new version yesterday at 3pm. Can you help me compare the API performance before and after the deploy?",
"expected_output": "Range query with --start spanning the deploy time, --output graph for trend, rate() on request/error metrics.",
"files": [],
"assertions": [
{
"id": "10.1",
"description": "uses a range query with --start flag to span a time window around the deploy"
},
{
"id": "10.2",
"description": "recommends --output graph to visualize the performance trend"
},
{
"id": "10.3",
"description": "uses rate() for request/error rate metrics in the comparison"
},
{
"id": "10.4",
"description": "does NOT just suggest a single instant query without time context"
}
]
}
]
}
promql-cli — Debugging Methodology
Core Rule: Isolate Before Aggregating
The most common debugging mistake is starting with aggregated metrics. Aggregation masks individual bad actors — a single overloaded pod looks fine when its metrics are averaged with 9 healthy ones. Always start by narrowing to a single instance, then broaden once you understand what's happening.
USE Method (Utilization, Saturation, Errors)
For infrastructure components (CPU, memory, disk, network):
# Utilization — how busy is the resource?
promql 'avg by(instance)(rate(node_cpu_seconds_total{mode!="idle"}[5m]))' --start 1h --output graph
# Saturation — is the resource overloaded? (queue depth, wait time)
promql 'node_load1 / on(instance) count by(instance)(node_cpu_seconds_total{mode="idle"})' --start 1h
# Errors — are requests failing?
promql 'rate(node_disk_io_time_seconds_total[5m])' --start 1h --output graphRED Method (Rate, Errors, Duration)
For services and HTTP endpoints:
# Rate — requests per second
promql 'sum by(job)(rate(http_requests_total[5m]))' --start 1h --output graph
# Errors — error ratio
promql 'sum by(job)(rate(http_requests_total{status=~"5.."}[5m])) / sum by(job)(rate(http_requests_total[5m]))' --start 1h
# Duration — latency (requires histogram metric)
promql 'histogram_quantile(0.99, sum by(le, job)(rate(http_request_duration_seconds_bucket[5m])))' --start 1h --output graphStep-by-Step: Investigating a Latency Spike
1. Identify the time window
promql 'histogram_quantile(0.99, sum by(le)(rate(http_request_duration_seconds_bucket[5m])))' --start 6h --output graph2. Isolate by instance — don't aggregate yet
# Remove the sum(), keep instance labels
promql 'histogram_quantile(0.99, rate(http_request_duration_seconds_bucket{job="api"}[5m]))' --start 2h --output graph3. Check resource pressure on the worst instance
promql 'rate(node_cpu_seconds_total{mode!="idle", instance="bad-host:9100"}[5m])' --start 2h --output graph
promql 'node_memory_MemAvailable_bytes{instance="bad-host:9100"}' --start 2h --output graph4. Correlate with upstream dependencies
promql 'rate(db_query_duration_seconds_sum{instance="bad-host:5432"}[5m]) / rate(db_query_duration_seconds_count{instance="bad-host:5432"}[5m])' --start 2h --output graphStep-by-Step: Investigating an Error Rate Spike
1. Get the overall error rate
promql 'sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))' --start 3h --output graph2. Break down by endpoint
promql 'sum by(handler)(rate(http_requests_total{status=~"5.."}[5m]))' --start 1h --output csv | sort -t, -k2 -rn | head -103. Check for upstream failures (dependency error rates)
promql 'rate(grpc_client_handled_total{grpc_code!="OK"}[5m])' --start 1h --output graphDiagnose: Useful Checks
Diagnose: 1- promql 'up' --output table — check which scrape targets are down; a missing instance explains missing metrics 2- promql metrics | grep <service> — discover what metrics a service actually exposes before querying 3- promql meta <metric> — confirm the metric type (counter vs gauge) before applying rate() or increase()
Finding the Right Metrics
When you don't know which metrics or thresholds are meaningful for a given component, start with promql metrics and promql meta to discover what your Prometheus instance exposes. For reference, the Awesome Prometheus Alerts project (samber/awesome-prometheus-alerts) maintains a curated collection of battle-tested PromQL alert rules organized by exporter, covering:
| Domain | Exporters covered |
|---|---|
| Infrastructure | node-exporter, cAdvisor, blackbox, IPMI, Windows, Proxmox |
| Databases | MySQL, PostgreSQL, Redis, MongoDB, Elasticsearch, Cassandra, Clickhouse, and more |
| Message brokers | Kafka, RabbitMQ, Pulsar, NATS, Zookeeper |
| Proxies & mesh | Nginx, HAProxy, Traefik, Envoy, Istio, Linkerd |
| Runtimes | JVM, Golang, PHP-FPM, Ruby, Python |
| Orchestrators | Kubernetes, Nomad, Consul, Etcd |
| Storage | Ceph, MinIO, ZFS, OpenEBS |
| Observability | Thanos, Loki, Grafana Mimir, OpenTelemetry Collector |
| Cloud | AWS CloudWatch, GCP Stackdriver, Azure, DigitalOcean |
Standard alert expressions are valid PromQL — you can use similar patterns with promql-cli to inspect current values. Example workflow:
# 1. Discover relevant metrics in your Prometheus instance
# 2. Write a PromQL expression based on common alerting patterns
# 3. Run it to see the current value
promql 'node_filesystem_avail_bytes{fstype!="tmpfs"} / node_filesystem_size_bytes{fstype!="tmpfs"} * 100' --output table
# 4. Run as a range query to see the trend
promql 'node_filesystem_avail_bytes{fstype!="tmpfs"} / node_filesystem_size_bytes{fstype!="tmpfs"} * 100' --start 6h --output graphExporter documentation — when alert rules aren't enough, check the official exporter docs for the full list of exposed metrics and their semantics. Each exporter's README lists all metric names and labels.
Listing Available Metrics
Use promql metrics to discover what's actually exposed in your Prometheus instance. On large production setups this can return thousands of metric names — always filter immediately or the output becomes unmanageable.
# ✗ Bad — dumps every metric name, potentially thousands of lines
promql metrics
# ✓ Good — filter by exporter prefix or keyword
promql metrics | grep '^node_' # node-exporter metrics
promql metrics | grep '^container_' # cAdvisor / Kubernetes metrics
promql metrics | grep '^pg_' # PostgreSQL exporter
promql metrics | grep '^redis_' # Redis exporter
promql metrics | grep '^kafka_' # Kafka exporter
promql metrics | grep http # any metric mentioning httpOnce you have a metric name, drill into its labels and type:
promql labels <metric> # list all label names
promql labels <metric> job # list all values for a specific label
promql meta <metric> # show metric type (counter/gauge/histogram) and help textLabel values help you understand the cardinality before running a query — a metric with hundreds of instance values will return a large result set unless filtered:
# Check how many instances exist before querying
promql labels http_requests_total instance
# Then filter down to the relevant one
promql 'rate(http_requests_total{instance="api-1:8080"}[5m])' --output tablepromql-cli — ASCII Graphs
Use --output graph for an in-terminal ASCII sparkline of range queries. No external dependencies required.
promql 'rate(http_requests_total[5m])' --start 1h --output graph
promql 'node_memory_MemAvailable_bytes' --start 6h --step 5m --output graphPromQL aggregations return multiple series — each becomes a separate line in the chart:
# One line per job
promql 'sum by(job)(rate(http_requests_total[5m]))' --start 1h --output graph
# One line per instance
promql 'rate(http_requests_total{job="api"}[5m])' --start 1h --output graphSave to file by redirecting stdout:
promql 'node_load1' --start 6h --output graph > load_trend.txt--output graph is the default for range queries (when --start is set) — omitting --output has the same effect.
promql-cli — Installation
Latest release: v0.3.0 — macOS and Linux only (no official Windows binary). Please check the releases to find the latest version.
macOS
Pre-built binary (recommended)
# Intel (x86_64)
curl -L https://github.com/nalbury/promql-cli/releases/download/v0.3.0/promql-v0.3.0-darwin-amd64.tar.gz | tar xz
sudo mv promql /usr/local/bin/
# Apple Silicon (M1/M2/M3/M4/M+)
curl -L https://github.com/nalbury/promql-cli/releases/download/v0.3.0/promql-v0.3.0-darwin-arm64.tar.gz | tar xz
sudo mv promql /usr/local/bin/Build from source (requires Go 1.13+)
git clone https://github.com/nalbury/promql-cli.git
cd promql-cli
OS=darwin ARCH=amd64 INSTALL_PATH=/usr/local/bin make install # Intel
OS=darwin ARCH=arm64 INSTALL_PATH=/usr/local/bin make install # Apple Silicongo install
go install github.com/nalbury/promql-cli@latest
# Binary lands in $(go env GOPATH)/bin — ensure that's on your PATHLinux
Pre-built binary (recommended)
# x86_64 (amd64)
curl -L https://github.com/nalbury/promql-cli/releases/download/v0.3.0/promql-v0.3.0-linux-amd64.tar.gz | tar xz
sudo mv promql /usr/local/bin/
# ARM64 (Raspberry Pi 4+, AWS Graviton, etc.)
curl -L https://github.com/nalbury/promql-cli/releases/download/v0.3.0/promql-v0.3.0-linux-arm64.tar.gz | tar xz
sudo mv promql /usr/local/bin/Build from source (requires Go 1.13+)
git clone https://github.com/nalbury/promql-cli.git
cd promql-cli
OS=linux ARCH=amd64 INSTALL_PATH=/usr/local/bin make install # x86_64
OS=linux ARCH=arm64 INSTALL_PATH=/usr/local/bin make install # ARM64go install
go install github.com/nalbury/promql-cli@latestWindows
No official Windows binary is provided. Options:
WSL2 (recommended): Install the Linux binary inside your WSL2 environment — full feature support.
Build from source:
git clone https://github.com/nalbury/promql-cli.git
cd promql-cli
$env:GOOS="windows"; $env:GOARCH="amd64"; go build -o promql.exe ./
# Move promql.exe to a directory on your PATHVerify Installation
Test against your local Prometheus instance (default: http://localhost:9090):
promql --version
promql 'up' --host http://localhost:9090
promql metrics --host http://localhost:9090 | head -20Configuration
By default promql-cli connects to http://localhost:9090. Override with --host or a config file:
# ~/.promql-cli.yaml
host: http://prometheus.acme.org:9090
timeout: 30schmod 600 ~/.promql-cli.yaml # file may contain tokens — restrict accessMulti-Host Setup
Use separate config files per environment, switch with --config:
# ~/.promql-cli-prod.yaml
host: https://prometheus-prod.acme.org:9090
# ~/.promql-cli-staging.yaml
host: https://prometheus-staging.acme.org:9090promql --config ~/.promql-cli-prod.yaml 'up'
promql --config ~/.promql-cli-staging.yaml 'up'Authentication
Never pass tokens or passwords as CLI arguments — they appear in shell history (~/.bash_history, ~/.zsh_history), in process listings (ps aux) and are sent to an LLM. Always store secrets in files under $HOME with restricted permissions.
Bearer token:
echo "your-token" > ~/.promql_token
chmod 600 ~/.promql_token# ~/.promql-cli.yaml (chmod 600)
host: https://prometheus.acme.org:9090
token-file: ~/.promql_token # ✓ path to file — token never appears in CLI argsBasic auth:
echo "your-password" > ~/.promql_password
chmod 600 ~/.promql_password# ~/.promql-cli.yaml (chmod 600)
host: https://prometheus.acme.org:9090
username: admin
password-file: ~/.promql_password # ✓ path to file — password never appears in CLI argsTLS / mTLS:
host: https://prometheus.acme.org:9090
ca-cert: /path/to/ca.crt
client-cert: /path/to/client.crt # only for mTLS
client-key: /path/to/client.key # only for mTLS
insecure-skip-verify: falsePromQL Reference
Metric Types
| Type | Description | Correct function |
|---|---|---|
| Counter | Monotonically increasing, resets on restart | rate(), increase() |
| Gauge | Arbitrary value that goes up and down | Direct use, avg(), max() |
| Histogram | Cumulative buckets (_bucket, _sum, _count) | histogram_quantile() |
| Summary | Pre-computed quantiles (less flexible than histogram) | Direct use |
Using rate() on a gauge produces meaningless results. Using raw counter values ignores resets and gives absolute counts rather than rates — always check the metric type with promql meta <metric> before querying.
Key Functions
rate() and irate()
rate(http_requests_total[5m]) # average per-second rate over 5m window (smoothed)
irate(http_requests_total[5m]) # instantaneous rate (last 2 samples) — spiky, reactiveUse rate() for dashboards and alerts. Use irate() only when you need to detect very short spikes.
increase()
increase(http_requests_total[1h]) # total increase over 1h (extrapolated)increase() is rate() * duration — useful for "how many requests in the last hour?" rather than per-second rates.
histogram_quantile()
# p99 latency across all instances
histogram_quantile(0.99, sum by(le)(rate(http_request_duration_seconds_bucket[5m])))
# p99 per job — keep job and le in by()
histogram_quantile(0.99, sum by(le, job)(rate(http_request_duration_seconds_bucket[5m])))The le label must stay in the by() clause — it identifies the buckets that histogram_quantile() needs to interpolate percentiles. Dropping it produces NaN.
Aggregation Operators
sum by(job)(rate(http_requests_total[5m])) # sum, grouped by job
avg without(instance)(node_memory_MemFree_bytes) # avg, dropping instance label
max by(instance)(node_load1) # max per instance
min(node_memory_MemAvailable_bytes) # global min
count by(job)(up) # count of series
topk(5, rate(http_requests_total[5m])) # top 5 series by value
bottomk(3, node_memory_MemAvailable_bytes) # bottom 3Label Matchers
http_requests_total{job="api"} # exact match
http_requests_total{job!="api"} # not equal
http_requests_total{status=~"5.."} # regex match (RE2)
http_requests_total{status!~"2.."} # regex not-match
http_requests_total{job="api", status=~"5.."} # multiple matchers (AND)Filter as early as possible — put matchers in the innermost vector selector, not after functions. This reduces the number of time series Prometheus evaluates.
Binary Operators
# Error ratio
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])
# CPU usage ratio
1 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))
# Matching labels across metrics (one-to-one)
http_requests_total / on(instance, job) http_request_duration_seconds_sumoffset
rate(http_requests_total[5m]) offset 1h # same query, 1 hour ago (for comparison)Common Pitfalls
| Mistake | Consequence | Fix |
|---|---|---|
rate() on a gauge | Meaningless derivative of an arbitrary value | Use the gauge directly |
Raw counter value (no rate()) | Absolute total ignores resets, not a rate | Wrap in rate() or increase() |
Dropping le from by() in histogram_quantile() | Returns NaN or wrong percentile | Keep le in by() |
| Aggregating across instances before isolating | Masks per-instance anomalies | Start with individual instance, then aggregate |
Range vector window too short for rate() | Noisy result if scrape interval is long | Use window ≥ 2× scrape interval |
| Mixing labels across binary operators | "many-to-many not allowed" error | Use on() or ignoring() to match labels |
promql-cli — Usage Reference
Instant Queries
Return a single value at the current time (or a specified time):
promql 'up' # all targets
promql 'up{job="node"}' # filter by label
promql 'up' --time 2024-01-15T10:00:00Z # at a specific time
promql 'rate(http_requests_total[5m])' # computed rateRange Queries
Return a time series over a window. --start accepts durations or RFC3339:
promql 'rate(http_requests_total[5m])' --start 1h # last 1 hour
promql 'up' --start 2h --end 1h # 2h ago to 1h ago
promql 'up' --start 2024-01-15T00:00:00Z --end 2024-01-15T12:00:00Z
promql 'up' --start 1h --step 5m # custom step (default: auto)Output Formats
promql 'up' # default: table (aligned columns)
promql 'up' --output table # explicit table
promql 'up' --output csv # CSV — pipe to files, spreadsheets
promql 'up' --output json # JSON — pipe to jq for processing
promql 'up' --output raw # raw PromQL API response
promql 'rate(http_requests_total[5m])' --start 1h --output graph # ASCII sparkline — preferred for range queriesPrefer `--output graph` for range queries when working with an LLM. ASCII sparklines convey trend direction (rising, falling, spiking, flat) in a compact format that LLMs parse well — far better than a table of raw timestamps and values.
Metric Discovery
promql metrics # list all metric names in Prometheus
promql metrics | grep http # filter metrics by name
promql labels http_requests_total # list all label names for a metric
promql labels http_requests_total job # list values for a specific label
promql meta http_requests_total # show metric type (counter/gauge/etc.) and HELP textTargeting a Specific Host
promql --host http://prometheus.acme.org:9090 'up'
promql --config ~/.promql-cli-prod.yaml 'up'Full Flag Reference
| Flag | Default | Description |
|---|---|---|
--host | http://localhost:9090 | Prometheus URL |
--config | ~/.promql-cli.yaml | Path to config file |
--output | table/graph | Output format: table, csv, json, graph (default: table for instant queries, graph for range queries) |
--start | — | Start time (duration like 1h or RFC3339) |
--end | now | End time |
--step | auto | Query resolution step (e.g. 30s, 5m) |
--time | now | Instant query time |
--no-headers | false | Suppress column headers in table/csv output |
--timeout | 10s | HTTP request timeout |
Combining with Shell Tools
# Find the top 5 jobs by request rate
promql 'sum by(job)(rate(http_requests_total[5m]))' --output csv | sort -t, -k2 -rn | head -5
# Export a time series to a file
promql 'node_cpu_seconds_total' --start 24h --output csv > cpu_export.csv
# Parse JSON with jq
promql 'up' --output json | jq '.data.result[] | {metric: .metric, value: .value[1]}'Related skills
How it compares
Pick promql-cli over Grafana dashboard skills when you need raw PromQL terminal queries and metric discovery without opening a browser UI.
FAQ
What is promql-cli?
CLI for querying Prometheus and PromQL-compatible engines (Thanos, Cortex, VictoriaMetrics, Grafana Mimir, Grafana Tempo...) — instant queries, range queries, metric discovery (met
When should I use promql-cli?
CLI for querying Prometheus and PromQL-compatible engines (Thanos, Cortex, VictoriaMetrics, Grafana Mimir, Grafana Tempo...) — instant queries, range queries, metric discovery (met
Is promql-cli safe to install?
Review the Security Audits panel on this page before production use.