ShortIQ

ShortIQ

Deployment

How to Set Up Monitoring with Grafana and Prometheus

A step-by-step guide to setting up application monitoring with Prometheus and Grafana. Covers Prometheus scrape config, Node.js metrics with prom-client, alerting with Alertmanager, Grafana dashboard setup, and Docker Compose deployment.

June 19, 2026ShortIQ Editorial Team

Why Prometheus and Grafana?

Prometheus is the most widely used open-source metrics collection system. It scrapes HTTP endpoints that expose metrics in a text format, stores them as time-series data, and provides PromQL for querying. Grafana is the most widely used open-source dashboard tool. Together they form the de facto monitoring stack for web applications and infrastructure.

This guide sets up the complete monitoring stack: Prometheus to collect metrics, your Node.js application exposing metrics via prom-client, Alertmanager for alert notifications, and Grafana for dashboards. All components run in Docker containers orchestrated with Docker Compose.

Docker Compose Setup

Create a docker-compose.yml that runs Prometheus, Grafana, and Alertmanager together:

yaml
version: '3.8'
services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.retention.time=30d
    ports:
      - '9090:9090'

  grafana:
    image: grafana/grafana:latest
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - '3001:3000'
    depends_on:
      - prometheus

  alertmanager:
    image: prom/alertmanager:latest
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
    ports:
      - '9093:9093'

volumes:
  prometheus_data:
  grafana_data:

Prometheus Configuration

Create prometheus.yml to configure scrape targets. Prometheus will poll the /metrics endpoint of your application every 15 seconds:

yaml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

rule_files:
  - alert_rules.yml

scrape_configs:
  - job_name: 'app'
    static_configs:
      - targets: ['host.docker.internal:3000']
    metrics_path: /metrics

  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

Exposing Metrics from Node.js with prom-client

Install prom-client and add a /metrics endpoint to your Express application:

typescript
import client from 'prom-client';
import express from 'express';

const register = new client.Registry();
client.collectDefaultMetrics({ register });

// Custom counter for HTTP requests
const httpRequestsTotal = new client.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'path', 'status'],
  registers: [register]
});

// Custom histogram for response duration
const httpDurationSeconds = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP request duration in seconds',
  labelNames: ['method', 'path'],
  buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5],
  registers: [register]
});

const app = express();

// Middleware to record metrics for every request
app.use((req, res, next) => {
  const end = httpDurationSeconds.startTimer({ method: req.method, path: req.path });
  res.on('finish', () => {
    end();
    httpRequestsTotal.inc({ method: req.method, path: req.path, status: res.statusCode });
  });
  next();
});

app.get('/metrics', async (req, res) => {
  res.set('Content-Type', register.contentType);
  res.end(await register.metrics());
});

Alert Rules and Grafana Dashboards

Create alert_rules.yml to fire alerts when your application is down or response times are high:

  • Alert: InstanceDown — fires when up == 0 for 1 minute (Prometheus cannot reach the metrics endpoint)
  • Alert: HighErrorRate — fires when the rate of 5xx responses exceeds 5% of all requests over 5 minutes
  • Alert: SlowResponseTime — fires when the 95th percentile response time exceeds 1 second
  • Grafana: import dashboard ID 1860 (Node Exporter Full) from grafana.com for host-level metrics
  • Grafana: add Prometheus as a data source at http://prometheus:9090 and create panels using PromQL queries

FAQ

What is the difference between metrics and logs?

Metrics are numeric measurements over time: request count, error rate, response time, CPU usage, memory. They are efficient to store and query and are ideal for dashboards and alerting. Logs are unstructured or structured text records of individual events: each request, each error, each transaction. Logs give you the details of what happened in a specific event. Use Prometheus and Grafana for metrics-based alerting, and a log aggregation system (Loki, Elasticsearch, Datadog) for log analysis. Both are needed for effective observability.

How do I monitor a Node.js application in production?

Use prom-client to expose default metrics (event loop lag, memory, CPU, active handles, garbage collection) plus custom business metrics (request count by endpoint, error rate, queue depth). Scrape with Prometheus every 15 seconds. Set up Grafana dashboards for the key signals: error rate, p95 response time, and throughput. Configure Alertmanager to send Slack or email notifications when error rate or latency exceeds thresholds. This gives you both proactive alerting and retrospective debugging capability.

What is a good Prometheus retention period?

The default is 15 days. For most applications, 30 days is a good starting point for local storage. Beyond 30 days, Prometheus local storage becomes expensive in disk space. For long-term storage (months or years), use Thanos or Cortex to offload data to object storage (S3 or GCS) while keeping recent data in local Prometheus. Grafana Cloud offers a managed long-term metrics store if you prefer not to self-host Thanos.

Can I use Grafana without Prometheus?

Yes. Grafana supports dozens of data sources including PostgreSQL, MySQL, Elasticsearch, InfluxDB, CloudWatch, and Datadog. You can query your PostgreSQL database directly from Grafana to build dashboards on application data. However, Prometheus is the most natural pairing with Grafana because it provides the pull-based scraping, efficient time-series storage, and PromQL query language that Grafana dashboards are designed to work with. For infrastructure and application monitoring specifically, the Prometheus and Grafana combination is the industry standard.

Related free tools

If you want to turn this topic into action, use one of ShortIQ's free tools for campaign planning, UTM structure, or QR distribution.

Continue Reading

Explore more guides on link shortener SaaS strategy, Bitly alternatives, and white label link management.

Free newsletter

Get new guides in your inbox

We publish practical guides on dev tooling, prompt engineering, marketing workflows, and deployment. No fluff — straight to the point.

No spam. Unsubscribe any time.

Was this article helpful?

Tell us if this guide solved the problem or what was still missing. We use this to improve the blog and only follow up if you explicitly allow it.

We use this to improve tutorials, examples, and technical depth.