stromfee.meStartEnergiemonitoringNetzanalyseLastspitzenStromfee.AIBlogÜber unsKontakt
top of page

ClickHouse für Energie-Zeitreihen: Warum wir Milliarden Zeilen darin halten

> **TL;DR:** Für Energie-Zeitreihen im Milliardenbereich – Redispatch-Massnahmen, 15-Minuten-Lastgänge, sekündliche Messwerte aus BGA und BESS – ist ClickHouse der InfluxDB und einem reinen Postgres-Stack meist überlegen. Entscheidend sind Kompressionsraten, spaltenorientierter Aufbau und SQL-Kompatibilität. Wir zeigen Benchmarks, Fallstricke und wann sich die Migration lohnt – und wann nicht.


Wer Energiedaten dauerhaft speichert, stösst schnell an Grenzen. Ein einzelner Janitza UMG 96-EL, der im Sekundentakt misst, produziert rund 2,6 Millionen Zeilen pro Monat. Bei 50 Zählpunkten sind das 130 Millionen Zeilen. Dazu kommen Marktdaten (EPEX Day-Ahead, Intraday), Redispatch-Massnahmen aus der BNetzA-Meldepflicht und Wetterprognosen. Wir halten in unserer Plattform mittlerweile rund **4,4 Millionen Redispatch-Datensätze seit 2013** plus mehrere Milliarden Messwerte – und das in ClickHouse.


Warum nicht in InfluxDB, wie viele Monitoring-Stacks es vorschlagen? Warum nicht in TimescaleDB, dem Postgres-Plugin, das gerad

e im deutschen Mittelstand beliebt ist? Dieser Artikel vergleicht die drei Optionen aus Sicht eines Energie-Praktikers.


## Warum Zeitreihen-Datenbanken sich von klassischen DBMS unterscheiden


Energie-Zeitreihen haben charakteristische Eigenschaften: hohe Schreibrate, append-only, starke zeitliche Lokalität bei Abfragen und hohe Redundanz zwischen benachbarten Werten. Ein dreiphasiger Wirkleistungswert ändert sich selten sprunghaft – das ist ein Geschenk für Kompressionsalgorithmen.


### Zeilen- vs. Spaltenorientierung


Klassisches Postgres ist zeilenorientiert: Ein Datensatz mit Timestamp, Zählpunkt-ID, P_L1, P_L2, P_L3, Q, U, I liegt physisch zusammen auf der Platte. Das ist optimal für OLTP-Workloads, bei denen man einzelne Zeilen liest oder schreibt.


ClickHouse ist spaltenorientiert. Alle P_L1-Werte liegen zusammen, alle Timestamps liegen zusammen. Wenn man "zeige mir den durchschnittlichen Wirkleistungswert eines Zählpunkts über 3 Jahre" fragt, muss ClickHouse nur eine Spalte lesen – nicht die ganze Zeile. Bei 200 Byte pro Zeile und 10 GB Rohdaten bedeutet das im Zweifel, statt 10 GB nur 800 MB zu lesen.


### Kompression als Hauptvorteil


ClickHouse nutzt Codecs wie **Delta + LZ4** oder **DoubleDelta + ZSTD** speziell für Zeitreihen. In unseren Messungen auf Lastgangdaten eines mittelgrossen BGA-Portfolios erreichen wir Kompressionsraten von **8:1 bis 14:1**. InfluxDB kommt mit TSM-Engine auf etwa 6:1 bis 10:1. Postgres mit TimescaleDB und nativer Kompression liegt bei 4:1 bis 8:1 – solide, aber spürbar schlechter.


## Benchmark-Vergleich: ClickHouse vs. InfluxDB vs. TimescaleDB


Wir haben einen internen Benchmark auf einem **synthetischen Datensatz von 2 Milliarden Zeilen** gefahren (Simulation: 200 Zählpunkte, 3 Jahre, 15-Sekunden-Takt). Hardware: Single-Node, 16 vCPU, 64 GB RAM, NVMe.


### Schreibperformance (Bulk-Insert)


| System | Zeilen/Sekunde | Notizen |

|---|---|---|

| ClickHouse 24.x | ~1.200.000 | Native Format, Batch 100k |

| InfluxDB 2.7 | ~450.000 | Line Protocol, Batch 10k |

| TimescaleDB (PG 16) | ~180.000 | COPY, Hypertable partitioniert |


ClickHouse ist hier klar im Vorteil – allerdings muss man sagen: Für viele reale BGA-Monitorings reichen auch 180.000 Zeilen pro Sekunde locker aus. Die Schreibperformance ist also selten das entscheidende Argument.


### Aggregationsabfragen


Spannender wird es bei Abfragen wie "SUM(P) pro Stunde über 1 Jahr für 50 Zählpunkte":


| System | Laufzeit | Notizen |

|---|---|---|

| ClickHouse | 0,8 s | MergeTree, sortiert nach (zp_id, ts) |

| InfluxDB | 6,2 s | Flux-Query |

| TimescaleDB | 3,1 s | Continuous Aggregate half |


Ohne vorberechnete Aggregate ist ClickHouse rund **7x schneller als InfluxDB** und **4x schneller als TimescaleDB**. Mit Materialized Views in ClickHouse fallen diese Abfragen auf unter 100 ms.


### Speicherbedarf


Dieselben 2 Milliarden Zeilen:


- **ClickHouse:** 48 GB

- **InfluxDB:** 71 GB

- **TimescaleDB (komprimiert):** 112 GB

- **Postgres ohne Kompression:** 380 GB


Bei 3-Jahres-Aufbewahrungspflicht für Messdaten aus dem Mess- und Eichrecht ist das ein realer Kostenfaktor.


## Wo ClickHouse nicht glänzt


Ich möchte den Eindruck vermeiden, ClickHouse sei für alles die richtige Wahl. Drei Schwächen sollte man kennen:


### Updates und Deletes sind teuer


ClickHouse ist kein OLTP-System. Updates werden als **ALTER TABLE ... UPDATE** ausgeführt und sind asynchron, teuer und blockieren mitunter Merges. Wenn Ihr Use Case regelmässige Korrekturen einzelner Messwerte vorsieht (etwa bei Zählerwechseln mit Rückwirkung), wird das unhandlich. Wir lösen das über ReplacingMergeTree und Versionierung – funktioniert, erfordert aber Disziplin im Datenmodell.


### Transaktionen fehlen weitgehend


Wer Stammdaten, Abrechnungsrelevantes oder User-Management in derselben Datenbank halten will, sollte das nicht in ClickHouse tun. Wir nutzen **Postgres für alle transaktionalen Daten** (Kundenstamm, Assets, Verträge, §14a-Steuerbefehle) und ClickHouse ausschliesslich für Zeitreihen.


### Lernkurve und Operations


ClickHouse hat eigenartige Ecken: Quirks bei Joins, ein anderes Locking-Modell, eigenständige Replikation über ZooKeeper oder ClickHouse Keeper. Für ein kleines Team, das schon Postgres betreibt, ist TimescaleDB vermutlich die pragmatischere Wahl – **bis der Datenbestand so gross wird, dass sich der Aufwand lohnt**. Eine sinnvolle Faustregel: Ab etwa 500 Millionen Zeilen aktiv abgefragter Zeitreihen wird ClickHouse attraktiv.


## Unser Datenmodell für Energie-Zeitreihen in ClickHouse


Für Fachleser der interessanteste Teil: Wie sieht ein brauchbares Schema aus?


### Tabelle für Messwerte


```sql

CREATE TABLE measurements (

ts DateTime64(3, 'Europe/Berlin') CODEC(DoubleDelta, ZSTD(3)),

zp_id UInt32 CODEC(ZSTD(1)),

p_wirk Float32 CODEC(Gorilla, LZ4),

q_blind Float32 CODEC(Gorilla, LZ4),

u_l1 Float32 CODEC(Gorilla, LZ4),

i_l1 Float32 CODEC(Gorilla, LZ4),

quality UInt8 CODEC(ZSTD(1))

) ENGINE = MergeTree()

PARTITION BY toYYYYMM(ts)

ORDER BY (zp_id, ts)

TTL ts + INTERVAL 10 YEAR;

```


Zwei Dinge sind wichtig: Die **Gorilla-Kodierung** für Float-Messwerte ist speziell für Zeitreihen entwickelt (ursprünglich von Facebook) und komprimiert langsam driftende Werte extrem gut. Die **Sortierung nach (zp_id, ts)** sorgt dafür, dass Abfragen für einen einzelnen Zählpunkt nur minimal Daten lesen müssen.


### Materialized Views für Aggregate


Für die Anzeige im [BESS Live-Dashboard auf stromfee.ai](https://stromfee.ai) wollen wir keine Rohdaten aggregieren, wenn ein Kunde drei Jahre Verlauf anschaut. Wir pflegen Materialized Views mit Stunden-, Tages- und Monatsaggregaten:


```sql

CREATE MATERIALIZED VIEW measurements_hourly

ENGINE = SummingMergeTree()

PARTITION BY toYYYYMM(ts_hour)

ORDER BY (zp_id, ts_hour)

AS SELECT

toStartOfHour(ts) AS ts_hour,

zp_id,

avg(p_wirk) AS p_avg,

max(p_wirk) AS p_max,

count() AS n

FROM measurements

GROUP BY zp_id, ts_hour;

```


Damit fallen Dashboard-Abfragen auf Millisekunden, unabhängig vom Rohdatenvolumen.


## Wann lohnt die Migration – und wann nicht


Eine ehrliche Einordnung aus der Praxis:


**Migration lohnt sich, wenn:**

- Sie aktiv mehr als ca. 500 Mio. Zeilen abfragen

- Aggregationsabfragen über grosse Zeiträume häufig sind (Reporting, Forecasting, Anomalieerkennung)

- Speicherkosten ein Thema werden (Cloud-Volumes sind nicht umsonst)

- ML-Pipelines über historische Daten laufen – wir trainieren unser [electricity_price_forecast-Modell](https://stromfee.ai) mit Prophet auf 96 Preissignalen direkt aus ClickHouse


**Migration lohnt sich nicht, wenn:**

- Der Datenbestand unter 100 Mio. Zeilen bleibt – Postgres reicht

- Das Team kein Dev-Ops-Know-how für eine zweite Datenbank hat

- OLTP-Eigenschaften (Updates, Transaktionen) im Vordergrund stehen

- Sie InfluxDB bereits betreiben und keine Skalierungsprobleme haben


Ein 1-MW-BGA-Betrieb in Norddeutschland, den wir beraten haben, ist nach Prüfung bei TimescaleDB geblieben – bei 60 Mio. Zeilen pro Jahr rechnet sich der Wechsel schlicht nicht. Ein mittelständisches Nahwärmenetz mit 400 Zählern und Sekundendaten dagegen hat den Schritt zu ClickHouse gemacht und spart rund 60 % Speicherkosten.


## Integration in bestehende Energie-Stacks


Ein häufiges Missverständnis: Man muss nicht entweder-oder wählen. Unser Setup kombiniert drei Welten:


- **Postgres** für Stammdaten, Benutzer, Verträge, Abrechnung

- **ClickHouse** für alle Zeitreihen (Messwerte, Marktdaten, Redispatch-Historie)

- **Redis** als Cache vor dem Dashboard


Der Datenfluss: MQTT-Broker empfängt Daten von Zählern (z. B. Janitza UMG mit MQTT-Modul), ein kleiner Go-Ingester batcht und schreibt nach ClickHouse. Stammdaten-Joins passieren in der Anwendungsschicht oder über Dictionary-Features von ClickHouse, das Postgres-Tabellen als Dictionaries einbinden kann – damit fallen viele JOINs auf Kosten der Stammdatenbank weg.


Wer sich das in der Praxis anschauen will: Die [Stromfee Academy](https://stromfee.ai) zeigt Simulatoren, die genau auf diesem Stack laufen.


## Fazit


ClickHouse ist kein Allheilmittel, aber für Energie-Zeitreihen jenseits der 500-Mio.-Zeilen-Marke derzeit die technisch überlegene Option. Die Kompression spart Geld, die Abfrageperformance macht Dashboards und ML-Pipelines flüssig, und die SQL-Kompatibilität senkt die Hürde gegenüber Influx-Flux erheblich. Wer jedoch ein kleines Team führt oder OLTP-Eigenschaften braucht, ist mit TimescaleDB oder sogar einem reinen Postgres besser bedient. Wie immer gilt: Die Datenbank muss zum Workload passen, nicht umgekehrt.


Wenn Sie Ihre Zeitreihen-Architektur überdenken oder einen zweiten Blick auf Ihre Monitoring-Pipeline brauchen, [nehmen Sie Kontakt auf](https://stromfee.ai/contact).


## FAQ


**1. Ist ClickHouse für kleine Installationen mit unter 50 Zählpunkten überdimensioniert?**

Ja, in den meisten Fällen. Bei 50 Zählpunkten und 15-Minuten-Werten reden wir über wenige Millionen Zeilen pro Jahr – dafü


[gekürzt]

 
 
 

Kommentare


bottom of page