---
title: "Data Center Power Monitoring: The Database Layer"
description: "Data center power monitoring at the database layer: schema and SQL for storing PUE, PDU, and energy telemetry at scale in PostgreSQL. "
section: "Data Center & Infrastructure Telemetry"
---

> **TimescaleDB is now Tiger Data.**

If you are a facilities engineer, data center operations manager, or sustainability lead responsible for energy costs and compliance reporting, this guide is written for you.

If you search "data center power monitoring," the first page is dominated by DCIM software vendors: Sunbird DCIM, Raritan Power IQ, PRTG, Schneider EcoStruxure. That result is accurate for most readers. DCIM platforms are the right answer to the question "what tool should I use to watch my power draw right now?"

This article is about a different question. U.S. data center electricity demand is projected to reach approximately 41 GW in 2026, up from an estimated 31 GW in 2025, driven in large part by AI infrastructure: GPU racks now draw 30 to 100 kW per rack, compared to 5 to 10 kW for traditional compute racks. That density shift is straining both power monitoring infrastructure and the databases behind it. 

Every DCIM tool has a database underneath it. That database stores the measurements your PDUs (Power Distribution Units), UPS units, and facility meters produce around the clock. When your DCIM platform's default retention window closes at 90 days and purges the history, or when you need to produce a 12-month rolling average PUE (Power Usage Effectiveness) for ISO 30134-2 compliance, or when you want to JOIN your rack power data with your workload scheduler to find out which batch jobs are driving energy costs, the DCIM dashboard is not the tool you need.

This guide covers the database layer. Specifically: how to store years of PDU and PUE time-series data in a SQL-queryable database, how to design the schema, how to calculate rolling PUE with `time_bucket()` and window functions, and how to automate the three-tier retention lifecycle that EU and ISO compliance requires. We'll also explain where this approach fits alongside InfluxDB and where it does not, and how data center power management at scale differs from real-time dashboarding.

Tiger Data builds time-series databases on PostgreSQL. That is our position in this stack, and we will be direct about where it adds value.

For the broader data center telemetry picture, including server, network, and environmental metrics, see the [<u>data center telemetry database guide</u>](https://www.tigerdata.com/learn/data-center-telemetry-database).

## What Data Center Power Monitoring Actually Generates

Before designing a database, it helps to know what the data actually looks like. Data center power monitoring produces four primary streams:

**PDU readings.** Per-phase current in amps, per-phase voltage, total kW per PDU, per-outlet kW for smart PDUs with individual outlet metering, power factor, and temperature. These readings arrive via SNMP or Modbus at whatever polling interval you configure, typically 30 seconds to 2 minutes for operational use.

**UPS telemetry.** Battery state of charge as a percentage, estimated runtime in minutes, input and output voltage, load percentage, bypass state, and alarm flags. UPS data is structurally different from PDU data: most readings are bounded values (battery percentage runs 0 to 100), alarm codes are sparse (most rows will be null), and the cadence is typically 1 to 5 minutes.

**Utility and facility meter data.** Total facility kWh, demand in kW, power factor at the meter. This is the PUE numerator: total power entering the building. Some facilities break this out by circuit group or building zone. This measurement point is what separates a full ISO-compliant PUE from a partial one.

**Cooling and environmental sensors.** CRAC and CRAH unit supply and return air temperatures, chilled water supply and return temperatures, airflow in CFM, and CRAH compressor draw in kW. Cooling data lives in the same time-series pattern as power data and belongs in the same database.

### The Storage Problem Is Bigger Than It Looks

A facility running 200 intelligent PDUs, each reporting 8 signals at 30-second intervals, generates approximately 3,200 rows per minute, or 4.6 million per day. Scale to 500 PDUs at 1-minute polling - because the schema stores one row per signal - and you are writing about 5.76 million rows per day, around 2.1 billion rows per year. Three years of raw data at that rate is approximately 6.3 billion rows.

The Green Grid requires PUE sampled at intervals of 15 minutes or less and averaged over 12 months for compliant reporting. The EU Energy Efficiency Directive requires annual reporting of PUE and related KPIs to a European database, with supporting data kept available for audit - multi-year needs that a 90-day window cannot meet. Neither requirement is served by a DCIM platform that purges data after 90 days.

### Monitored vs. Managed PDUs

A common question among facilities teams: does the type of PDU affect what data is available?

A monitored PDU reports power draw passively via SNMP or Modbus: current, voltage, total kW, temperature. A managed PDU adds remote outlet switching. For data collection, both types provide the same aggregate telemetry. Per-outlet metering data, where each outlet's draw is measured individually, is only available on managed PDUs equipped with individual outlet sensors. Per-PDU readings are sufficient for rack-level PUE calculation and anomaly detection. Per-outlet data requires a schema extension covered in the next section.

SNMP is the dominant protocol for collecting this data from PDUs and UPS units. Telegraf (via its SNMP input plugin) and Prometheus (via the SNMP Exporter) are the two most common collection agents in production environments.

## Why Power Telemetry Is a Time-Series Problem

Power data has three properties that make it a poor fit for a general-purpose relational database and a strong fit for a time-series store:

**Append-only writes.** Every new PDU reading is a new row with a timestamp. Historical readings are never updated. The access pattern is fundamentally different from transactional data, where rows are read, modified, and written back.

**High write rate with long tails.** The write rate is continuous and sustained. The data must be retained for years, not days. A standard PostgreSQL table without time-based partitioning will accumulate table bloat, suffer slow range scans, and require manual partition maintenance that adds operational complexity without eliminating the underlying problem.

**Time-anchored queries.** Every meaningful question about power data involves a time window: PUE over the last 30 days, power draw during the overnight batch window, anomalous rack load last Tuesday. These queries need efficient range scans over timestamp columns, which is exactly what hypertable-based time partitioning provides.

### Why DCIM Platforms Are Not the Long-Term Answer

DCIM platforms are optimized for what they were designed to do: real-time dashboards, threshold alerting, capacity visualization. Most do not expose a SQL interface to their internal data store. Most have retention windows of 90 days to 12 months before older data is purged or archived in formats that are not queryable. And joining DCIM power data with application workload data from a PostgreSQL operational database is typically not possible within the DCIM tool itself.

This is not a criticism of DCIM platforms. It is a description of their design center. The right architecture keeps DCIM for real-time visibility and alerting, and adds a time-series database for long-term analytical storage and SQL-native queries.

### Where InfluxDB Fits and Where It Does Not

The Telegraf to InfluxDB to Grafana pipeline is common in the wild. Community evidence, including the GitHub project [<u>r4yfx/poweriq-grafana</u>](https://github.com/r4yfx/poweriq-grafana), shows teams pulling data from Power IQ DCIM APIs and writing it to InfluxDB for dashboard visualization. This is a valid architecture for operational monitoring.

The friction surfaces at scale and at query complexity. InfluxDB's Flux query language has a meaningful learning curve for teams accustomed to SQL. The InfluxDB 1.x to 2.x to 3.x migration path has disrupted production deployments more than once - and InfluxDB 3.x deprecated Flux entirely in favor of SQL (via Apache Arrow/DataFusion), meaning teams that invested in Flux-based pipelines cannot upgrade without rewriting their queries. Standard SQL used natively against a PostgreSQL-based time-series store does not carry that migration risk.

[<u>Tiger Cloud</u>](https://www.tigerdata.com/energy-telemetry) (the managed service built on TimescaleDB) provides automatic time-based partitioning on top of standard PostgreSQL, so SQL queries over years of power data remain fast without manual partition management. [<u>Hypercore columnar compression</u>](https://www.tigerdata.com/docs/learn/columnar-storage/compression-methods) handles the slowly-changing values typical of power readings using type-specific encoding - [<u>XOR-based compression</u>](https://www.tigerdata.com/docs/learn/columnar-storage/compression-methods#xor-based-compression) for the floating-point power metrics, achieving compression ratios of 10:1 to 20:1 in practice for stable load profiles.

## Schema Design: Hypertables for PDU, UPS, and Facility Power

The tables below are production-oriented starting points. The DDL uses TimescaleDB’s time-series features - hypertables, the Hypercore columnstore, and continuous aggregates - on top of standard PostgreSQL, and runs on Tiger Cloud or a self-hosted TimescaleDB instance; the plain CREATE TABLE statements are standard Postgres. 

### PDU Readings Table

`CREATE TABLE pdu_readings (
    time              TIMESTAMPTZ       NOT NULL,
    pdu_id            TEXT              NOT NULL,
    location          TEXT,
    phase_a_current_a DOUBLE PRECISION,
    phase_b_current_a DOUBLE PRECISION,
    phase_c_current_a DOUBLE PRECISION,
    total_kw          DOUBLE PRECISION,
    voltage_v         DOUBLE PRECISION,
    power_factor      DOUBLE PRECISION,
    temperature_c     DOUBLE PRECISION
);

SELECT create_hypertable('pdu_readings', by_range('time'));`

The `pdu_id` should be a stable identifier, such as a rack asset tag or DCIM asset ID, so it joins cleanly to a separate `pdus` dimension table storing static metadata: make, model, rated capacity in kW, rack assignment, and zone.

For facilities with per-outlet metering, extend with a separate `pdu_outlet_readings` table that adds an `outlet_id` column. Storing outlet-level data in the same table as PDU totals causes row explosion for large deployments and degrades compression. Keep each table narrow.

### UPS Telemetry Table

`CREATE TABLE ups_telemetry (
    time                 TIMESTAMPTZ       NOT NULL,
    ups_id               TEXT              NOT NULL,
    battery_pct          DOUBLE PRECISION,
    estimated_runtime_min INTEGER,
    load_pct             DOUBLE PRECISION,
    input_voltage_v      DOUBLE PRECISION,
    output_voltage_v     DOUBLE PRECISION,
    bypass_active        BOOLEAN,
    alarm_code           TEXT
);

SELECT create_hypertable('ups_telemetry', by_range('time'));`

UPS alarm events are sparse: most rows will have `alarm_code = NULL`. Hypercore columnar compression handles sparse columns well because null values are represented compactly. There is no need for a separate events table unless you need event-specific indexing for alerting queries.

### Facility Power Table (PUE Source)

`CREATE TABLE facility_power (
    time        TIMESTAMPTZ       NOT NULL,
    meter_id    TEXT              NOT NULL,
    meter_type  TEXT,
    kwh         DOUBLE PRECISION,
    demand_kw   DOUBLE PRECISION
);

SELECT create_hypertable('facility_power', by_range('time'));`

The `meter_type` column is the key to clean PUE queries. Use values like `'it_load'`, `'total_facility'`, `'cooling'`, and `'lighting_misc'`. Separating IT load from total facility power in the same table with a type column enables the JOIN pattern in the next section without complex pivots or separate tables.

For simpler facilities with fixed meter topology, a single row with separate` total_kwh` and `it_kwh` columns works. The type-column approach scales better when meter configurations change over time.

### Compression and Chunk Interval

Power telemetry is among the most compressible workloads for a columnar store. Watt readings change slowly between adjacent samples, which makes XOR-based compression highly effective. Tiger Data's Hypercore (the hybrid row-columnar storage engine in TimescaleDB) applies this automatically once the columnstore is enabled and a columnstore policy converts older chunks.

`ALTER TABLE pdu_readings SET (
    timescaledb.enable_columnstore,
    timescaledb.segmentby = 'pdu_id',
    timescaledb.orderby = 'time DESC'
);

-- Add a policy so older chunks move to the columnstore automatically:
SELECT add_columnstore_policy('pdu_readings', after => INTERVAL '7 days');`

Setting `segmentby = 'pdu_id'` physically co-locates data from the same PDU within columnstore chunks. XOR-based compression then operates on a continuous sequence of readings from a single PDU, where adjacent values differ by small amounts. In practice, PDU power time-series compresses at ratios of 10:1 to 20:1 depending on polling frequency and workload variance. High-frequency polling (30-second intervals) of stable loads compresses better than low-frequency polling of volatile GPU rack power.

Recommended chunk intervals: 1 week for 30-second polling, 2 weeks for 1-minute polling. This keeps individual chunks at a size that benefits from compression without creating overhead at chunk boundaries.

Hypercore columnar compression is available in [<u>Tiger Cloud</u>](https://www.tigerdata.com/cloud) and TimescaleDB OSS. See the [<u>Hypercore columnstore setup documentation</u>](https://www.tigerdata.com/docs/build/columnar-storage/setup-hypercore) for configuration details.

## Querying PUE: From Raw Readings to Compliance Reports

PUE is defined as Total Facility Power divided by IT Equipment Power. The Green Grid recommends reporting PUE as a 12-month rolling average, sampled at intervals of 15 minutes or less. ISO/IEC 30134-2:2026 formalizes this measurement standard. These three SQL queries cover the primary reporting requirements.

### Rolling 30-Day PUE

This query uses `time_bucket()` to aggregate facility power readings into 15-minute intervals, then computes a rolling 30-day average PUE using a window function. See the [<u>time_bucket documentation</u>](https://www.tigerdata.com/docs/learn/data-lifecycle/time-buckets/about-time-buckets) for the full function reference.

`WITH it_load AS (
  SELECT
    time_bucket('15 minutes', time) AS bucket,
    SUM(demand_kw) AS it_kw
  FROM facility_power
  WHERE meter_type = 'it_load'
    AND time >= NOW() - INTERVAL '30 days'
  GROUP BY bucket
),
total_power AS (
  SELECT
    time_bucket('15 minutes', time) AS bucket,
    SUM(demand_kw) AS total_kw
  FROM facility_power
  WHERE meter_type = 'total_facility'
    AND time >= NOW() - INTERVAL '30 days'
  GROUP BY bucket
)
SELECT
  it.bucket,
  ROUND((total.total_kw / NULLIF(it.it_kw, 0))::numeric, 3) AS pue,
  AVG(total.total_kw / NULLIF(it.it_kw, 0))
    OVER (ORDER BY it.bucket ROWS BETWEEN 2879 PRECEDING AND CURRENT ROW)
    AS rolling_30d_avg_pue
FROM it_load it
JOIN total_power total USING (bucket)
ORDER BY it.bucket;`

Two implementation notes worth understanding before deploying this in production:

The `NULLIF(it.it_kw, 0)` guard prevents division by zero during maintenance windows when IT load drops to zero. Without it, the query throws a division-by-zero error on any bucket where all IT load meters read zero.

The window frame `ROWS BETWEEN 2879 PRECEDING AND CURRENT ROW` spans 30 days of 15-minute buckets (30 days * 24 hours * 4 buckets per hour = 2,880 rows; the frame is 2,879 preceding plus the current row). Adjust this frame if you query at different bucket granularities.

### Annual PUE for ISO and EU Compliance Reporting

ISO/IEC 30134-2:2026 requires PUE averaged over a minimum 12-month period. The EU Energy Efficiency Directive requires annual PUE reporting and supports multi-year audit needs. This query produces the ISO-compliant annual average directly from the `facility_power` hypertable:

`SELECT
  DATE_TRUNC('year', time) AS reporting_year,
  AVG(total_kw / NULLIF(it_kw, 0)) AS annual_avg_pue
FROM (
  SELECT
    time_bucket('15 minutes', fp.time) AS time,
    SUM(CASE WHEN meter_type = 'total_facility' THEN demand_kw END) AS total_kw,
    SUM(CASE WHEN meter_type = 'it_load' THEN demand_kw END) AS it_kw
  FROM facility_power fp
  GROUP BY 1
) bucketed
GROUP BY 1
ORDER BY 1;`

This query can be pre-materialized as a continuous aggregate for faster reporting, particularly when the underlying `facility_power` table spans multiple years.

### Per-PDU Anomaly Detection

This query uses a window function to flag PDUs whose current power draw deviates more than 20% from their own 7-day baseline. It runs against the last 24 hours of data.

`SELECT *
FROM (
  SELECT
    time,
    pdu_id,
    total_kw,
    AVG(total_kw) OVER w                        AS baseline_7d_avg_kw,
    total_kw / NULLIF(AVG(total_kw) OVER w, 0)  AS ratio_to_baseline
  FROM pdu_readings
  WHERE time >= NOW() - INTERVAL '7 days'        -- widen so the baseline really spans 7 days
  WINDOW w AS (
    PARTITION BY pdu_id
    ORDER BY time
    ROWS BETWEEN 10079 PRECEDING AND CURRENT ROW
  )
) s
WHERE time >= NOW() - INTERVAL '24 hours'        -- but only report the last 24h
  AND (ratio_to_baseline > 1.2 OR ratio_to_baseline < 0.7)
ORDER BY ratio_to_baseline DESC;`

The frame `ROWS BETWEEN 10079 PRECEDING` covers 7 days of 1-minute readings (7 * 24 * 60 = 10,080 rows; the frame is 10,079 preceding plus the current row). Adjust based on your actual polling interval.

The 1.2 and 0.7 thresholds, meaning 20% above or below the 7-day baseline, are a reasonable starting point. Facilities teams typically tune these based on expected workload variance: a GPU cluster with variable batch jobs will have higher natural variance than a steady-state compute floor.

## Retention, Compression, and Regulatory Compliance

Three years of raw 1-minute PDU readings from 500 intelligent PDUs is approximately 6.3 billion rows (500 PDUs × ~8 signals × 1-minute polling over three years). Without a tiered retention strategy, storage costs grow linearly and query performance over old data degrades.

The recommended approach is a three-tier lifecycle:

**Hot tier (raw, 1-minute resolution, 90 days).** Used for operational alerting, recent trend analysis, and anomaly detection. Recent chunks stay in the rowstore for fast writes; chunks older than the columnstore-policy threshold are compressed in the columnstore. Queryable in real time.

**Warm tier (15-minute averages, 3 years).** Covers the EU and ISO regulatory window for annual PUE audits. Created automatically by a continuous aggregate policy; no ETL pipeline required. The 15-minute granularity satisfies the Green Grid's sampling requirement for PUE reporting.

**Cold tier (hourly or daily summaries, indefinite).** Used for multi-year capacity planning and sustainability reporting. Very low storage footprint; appropriate for board-level sustainability dashboards and long-range benchmarking.

### Continuous Aggregate for the Warm Tier

`CREATE MATERIALIZED VIEW pdu_15min
WITH (timescaledb.continuous) AS
SELECT
  time_bucket('15 minutes', time) AS bucket,
  pdu_id,
  AVG(total_kw)      AS avg_kw,
  MAX(total_kw)      AS peak_kw,
  MIN(total_kw)      AS min_kw,
  AVG(power_factor)  AS avg_pf
FROM pdu_readings
GROUP BY bucket, pdu_id;`

Once the view is created, set up the retention policy on the raw table:

`SELECT add_retention_policy('pdu_readings', INTERVAL '90 days');`

See the [<u>retention policy documentation</u>](https://www.tigerdata.com/docs/reference/timescaledb/data-retention/add_retention_policy) for the full policy API. Raw chunks older than 90 days are dropped automatically. The continuous aggregate preserves the 15-minute summaries independently, so three years of compliance-ready data survives after the raw data is gone.

### EU and ISO Compliance

ISO/IEC 30134-2:2026 requires PUE reported as a 12-month rolling average. The EU Energy Efficiency Directive mandates that data center operators above threshold sizes submit KPIs including PUE to a European database and retain supporting power consumption records for audit.

Three years of 15-minute averages in the warm tier satisfies both requirements. The data is SQL-queryable, not locked in a CSV export or a DCIM platform screenshot. When an auditor asks for the underlying measurement data supporting your annual PUE report, you run a query. You do not export a spreadsheet and hope the formatting survives.

This tiered architecture is also the foundation for broader data center power management: once raw readings, aggregated summaries, and long-term summaries coexist in a SQL-queryable database, capacity planning queries, anomaly trend analysis, and sustainability reporting all run from the same data layer without a separate data warehouse.

[<u>Tiger Cloud</u>](https://www.tigerdata.com/cloud) (and self-hosted TimescaleDB) manages this lifecycle automatically once the retention and continuous aggregate policies are configured: retention drops raw chunks on schedule and the continuous aggregates refresh in the background, with no manual intervention as data ages. This resolution-based rollup is separate from Tiger Cloud’s tiered storage feature, which moves older chunks to low-cost object storage. 

## Integration Patterns: Getting Data Into the Database

The database schema is the design. The integration pattern is how data gets there. Three paths cover most production environments.

### Pattern 1: Telegraf and the SNMP Input Plugin

This is the most direct path for teams collecting data without a DCIM intermediary. Telegraf's SNMP input plugin polls PDUs and UPS units via their vendor MIBs (APC, Vertiv, and Raritan all publish standard or vendor-specific MIBs). The PostgreSQL output plugin writes directly to the pdu_readings hypertable.

Pipeline: PDU or UPS, SNMP, Telegraf, PostgreSQL output plugin, `pdu_readings` hypertable.

The Telegraf `outputs.postgresql` plugin supports tag-to-column mapping, so `pdu_id` and `location` tags from your SNMP scrape map directly to columns in the hypertable without a transformation step.

For UPS units running NUT (Network UPS Tools), Telegraf's `upsd` input plugin reads NUT and outputs to the same destination table using the same pipeline. No separate collection stack is needed.

### Pattern 2: DCIM API Export to TimescaleDB

For facilities already running Sunbird Power IQ, Raritan DCIM, or similar: the DCIM platform remains the authoritative source for real-time dashboards and alerting. TimescaleDB becomes the long-term analytical store.

The pattern documented in the community repository [<u>r4yfx/poweriq-grafana</u>](https://github.com/r4yfx/poweriq-grafana) extracts Power IQ data via REST API and writes to a time-series store. The same pipeline can target TimescaleDB instead of or alongside InfluxDB. Common ETL options for this path include a custom Python script for simple polling workflows, Airbyte for managed data pipelines, or Kafka for high-volume streaming.

One tradeoff to account for: DCIM API polling typically runs at 5 to 15-minute intervals, not real time. This is adequate for long-term trend storage and compliance reporting but is not a substitute for sub-minute operational alerting.

### Pattern 3: Prometheus SNMP Exporter and Remote Write

Teams already running Prometheus to scrape IPMI or SNMP metrics can add PDU targets to the SNMP Exporter configuration and use Prometheus remote write to send data to TimescaleDB.

For teams using Prometheus primarily for infrastructure observability, the [<u>Prometheus long-term storage guide</u>](https://www.tigerdata.com/learn/prometheus-long-term-storage) covers the remote write setup in more detail. For context on Prometheus alternatives and when SQL-native storage makes sense, see the [<u>Prometheus alternatives comparison</u>](https://www.tigerdata.com/learn/prometheus-alternatives).

One limitation worth understanding: Prometheus remote write stores metrics in a Prometheus-native format. Complex analytical joins, such as the PUE calculation joining IT load and total facility power, require writing SQL against the hypertables directly, not through PromQL. This is why a SQL-native store adds analytical value that Prometheus remote write alone does not provide.

## PUE Beyond the Single Metric: WUE, CUE, and Sustainability Reporting

2026 sustainability frameworks have moved beyond PUE as the sole metric. ISO and the EU now expect data center operators to track WUE (Water Usage Effectiveness) and CUE (Carbon Usage Effectiveness) alongside PUE.

**WUE** is Annual Site Water Usage in liters divided by IT Equipment Energy in kWh. The data sources are cooling tower makeup water meters and humidifier consumption meters: the same time-series schema pattern as facility power. Add `meter_type` values such as` 'cooling_water_liters'` to the `facility_power` table and the WUE numerator is queryable with the same patterns shown above.

**CUE** is Total CO2 Equivalent Emissions divided by IT Equipment Energy. The data source is utility grid carbon intensity, typically provided as an hourly factor in gCO2/kWh from the electricity provider or a grid API. Join hourly carbon intensity readings with facility kWh consumption to compute CUE. The same `facility_power` hypertable accommodates this with a `meter_type` value of `'grid_carbon_intensity_gco2_kwh'`.

The schema pattern generalizes without requiring new tables. Building a sustainability dashboard on top of this data is a Grafana or BI layer concern. Tiger Data does not provide built-in WUE or CUE dashboards; it provides the SQL-queryable data layer that any dashboard tool can query.

For context on how this architecture fits into broader operational telemetry, the [<u>SCADA data management guide</u>](https://www.tigerdata.com/learn/scada-data-management-at-scale-architecture-historians-and-the-modern-database) covers related patterns for facilities teams familiar with operational historians. For a broader comparison of time-series databases for this workload, see [<u>the best time-series databases compared</u>](https://www.tigerdata.com/learn/the-best-time-series-databases-compared). For downsampling and tiered retention patterns in more detail, see the [<u>time-series downsampling guide</u>](https://www.tigerdata.com/learn/time-series-downsampling).