Posisi Prometheus

Kapan stack metrik berbasis pull merupakan jawabannya, dan kapan basis data time-series tetap cocok.

Daftar isi

Prometheus adalah basis data time-series yang dirancang untuk pemantauan sistem dengan model pengambilan data secara pull dan retensi jangka pendek. Topik ini memetakan posisi Prometheus terhadap TimescaleDB dan InfluxDB 3.x, terutama pada tiga aspek, yaitu model pull versus push, retensi jangka pendek versus panjang, serta PromQL versus SQL. Setelah membaca topik ini, keputusan untuk menggunakan Prometheus murni atau memadukannya dengan basis data time-series eksternal dapat diambil berdasarkan kebutuhan retensi dan kompleksitas analisis.

Model pull Prometheus#

Prometheus bekerja dengan model pull, yaitu server Prometheus yang aktif mengambil metrik dari target pada interval tetap, biasanya 15 detik. Setiap target menyajikan metrik pada endpoint HTTP /metrics dalam format eksposur yang ringkas. node_exporter adalah kolektor standar untuk metrik host, sedangkan postgres_exporter, redis_exporter, dan sejenisnya melayani aplikasi populer. Model pull memberi Prometheus kontrol penuh atas laju pengambilan, sehingga beban jaringan dan parser dapat diatur sesuai kapasitas server Prometheus.

Model pull berbeda dari arsitektur push yang digunakan Telegraf atau StatsD, di mana kolektor yang menulis ke basis data. Pada model push, kolektor menentukan kapan dan seberapa cepat data dikirim, sehingga server penerima harus siap menampung lonjakan. Pada model pull, server Prometheus menjadi sumber kebenaran tentang laju ingest, dan target yang tidak merespons dapat dideteksi langsung sebagai up == 0. Konsekuensi utama model pull adalah Prometheus harus memiliki akses jaringan langsung ke setiap target, sehingga lingkungan dengan target di balik NAT atau firewall memerlukan Pushgateway sebagai perantara.

Diagram berikut membandingkan kedua model pada satu pandangan. Pada model pull, tiga panah keluar dari Prometheus menuju tiga node. Pada model push, tiga Telegraf di setiap node menulis ke TimescaleDB atau InfluxDB 3.x.

Pull (Prometheus)Prometheusscrape /metricsnode-01node-02node-03Push (Telegraf ke TSDB)Telegraf node-01Telegraf node-02Telegraf node-03TimescaleDB / InfluxDB
Perbandingan model pull Prometheus dan model push Telegraf ke basis data time-series

Konfigurasi scrape#

Konfigurasi scrape Prometheus ditulis dalam YAML pada berkas prometheus.yml. Bagian scrape_configs mendaftarkan setiap target beserta interval dan timeout. Karena berkas YAML bukan kode yang dapat dieksekusi, contoh berikut tidak dijalankan di sandbox dan hanya menjadi referensi konfigurasi.

yaml Konfigurasi prometheus.yml untuk tiga node
global:
  scrape_interval: 15s        # ambil metrik tiap 15 detik
  evaluation_interval: 15s     # evaluasi rule alert tiap 15 detik

scrape_configs:
  - job_name: node
    static_configs:
      - targets:
          - node-01:9100
          - node-02:9100
          - node-03:9100
    relabel_configs:
      - source_labels: [__address__]
        regex: '([^:]+):.*'
        target_label: node
        replacement: '${1}'
text Keluaran
YAML valid (lulus parse dengan yaml.safe_load).

Bagian global mengatur interval default, sedangkan scrape_configs mendaftarkan job node dengan tiga target node_exporter pada port 9100. relabel_configs memetakan label __address__ menjadi label node yang lebih mudah digunakan dalam query. Setelah konfigurasi dimuat, Prometheus mulai mengambil metrik dan menyimpannya ke TSDB lokal.

Retensi jangka pendek#

Prometheus menyimpan data ke TSDB lokal dengan retensi default 15 hari. Retensi ini bukan kebetulan, melainkan pilihan desain yang menargetkan pemantauan operasional waktu nyata. Pada retensi pendek, TSDB Prometheus mencapai target sekitar 1,3 hingga 2 byte per sampel setelah kompresi, sehingga ruang disk tetap kecil bahkan pada laju ingest tinggi. Penambahan retensi ke 30 atau 60 hari dimungkinkan, tetapi bukan tujuan desain utama, sebab beban query pada rentang panjang menjadi berat bagi mesin single-node Prometheus.

Untuk retensi panjang, ekosistem Prometheus menyediakan solusi terpisah seperti Mimir, Cortex, atau Thanos, yang menerima remote write dari Prometheus dan menyimpan data ke basis data objek atau basis data time-series lain. Pemisahan ini menjaga Prometheus tetap ringan pada edge, sementara retensi panjang dipindahkan ke lapisan yang dirancang untuk tujuan itu. Basis data time-series umum seperti TimescaleDB juga dapat menerima remote write Prometheus melalui adapter, sehingga satu hypertable dapat melayani baik PromQL (melalui adapter) maupun SQL analitik.

PromQL versus SQL#

PromQL adalah bahasa query khusus untuk metrik yang dirancang oleh tim Prometheus. PromQL unggul pada operasi yang lazim pada pemantauan, yaitu agregasi rentang, rate pada counter, dan histogram quantile. Sebuah query seperti rate(node_cpu_seconds_total{mode="user"}[5m]) menghitung laju perubahan counter CPU user selama lima menit terakhir tanpa boilerplate. Padanan SQL pada TimescaleDB memerlukan subquery window dan kalkulasi eksplisit, sehingga lebih panjang tetapi lebih fleksibel untuk analitik lintas tabel.

SQL menjadi keunggulan saat query melibatkan join dengan tabel dimensi, agregasi pada level non-waktu, atau perhitungan yang kompleks seperti deteksi anomali berbasis z-score. PromQL tidak dirancang untuk operasi semacam itu, sehingga peminjam SQL yang sudah familiar akan lebih produktif di TimescaleDB atau InfluxDB 3.x. Contoh berikut tidak dijalankan di sandbox karena memerlukan server TimescaleDB aktif.

postgres Query SQL TimescaleDB untuk rerata CPU per jam
SELECT
    time_bucket('1 hour', ts) AS bucket,
    node,
    avg(cpu_persen) AS cpu_avg,
    stddev(cpu_persen) AS cpu_std
FROM cpu_node
WHERE ts > now() - interval '7 days'
GROUP BY bucket, node
ORDER BY bucket, node;
text Keluaran
bucket|node|cpu_avg|cpu_std
2026-11-08 11:00:00+00|node-01|26|4.35285750066007
2026-11-08 11:00:00+00|node-02|27|4.35285750066007
2026-11-08 11:00:00+00|node-03|28|4.35285750066007
2026-11-08 12:00:00+00|node-01|26|4.35285750066007
2026-11-08 12:00:00+00|node-02|27|4.35285750066007
2026-11-08 12:00:00+00|node-03|28|4.35285750066007
2026-11-08 13:00:00+00|node-01|26|4.35285750066007
2026-11-08 13:00:00+00|node-02|27|4.35285750066007
2026-11-08 13:00:00+00|node-03|28|4.35285750066007

Perbandingan ukuran disk#

Karena Prometheus dan TimescaleDB menyimpan data dengan format yang berbeda, perbandingan ukuran disk pada beban kerja yang sama menjadi informatif. Skrip berikut menghitung perkiraan ukuran disk untuk tiga node dengan 100 deret metrik per node dan interval scrap 15 detik, pada dua skenario retensi, yaitu 15 hari (default Prometheus) dan 365 hari (target TimescaleDB). Skrip tidak menjalankan Prometheus atau Postgres.

python bandingkan_prometheus_tsdb.py
"""Bandingkan ukuran disk Prometheus vs TimescaleDB untuk retensi berbeda.

Skrip ini TIDAK menjalankan prometheus atau postgres. Tujuannya
memperlihatkan mengapa stack pemantauan kerap memadukan keduanya:
Prometheus untuk retensi jangka pendek dengan kompresi efisien, dan
basis data time-series (TimescaleDB) untuk retensi panjang yang
menyimpan agregasi serta mendukung SQL analitik.
"""
from __future__ import annotations

# Asumsi beban kerja: tiga node, masing-masing mempublikasikan 100 deret
# metrik, dengan interval scrap 15 detik (4 sampel per menit per deret).
NODES = 3
SERIES_PER_NODE = 100
SAMPLE_INTERVAL_SEC = 15

# Retensi default
PROM_RETENSI_HARI = 15          # retensi lokal TSDB Prometheus (default 15 hari)
TSDB_RETENSI_HARI = 365         # retensi hypertable TimescaleDB (satu tahun)
TSDB_RETENSI_MENTAH_HARI = 7    # data mentah dipertahankan sebelum dikompres

# Estimasi ukuran per sampel (angka kasar dari dokumentasi resmi).
# Prometheus TSDB: target ~1.3-2 byte per sampel setelah kompresi.
# TimescaleDB baris mentah (timestamptz + 1 tag + 1 float + overhead):
# ~30 byte per baris. Setelah kompresi kolumnar: ~10 byte per baris.
PROM_BYTES_PER_SAMPLE = 2
TSDB_BYTES_PER_SAMPLE_RAW = 30
TSDB_BYTES_PER_SAMPLE_COMPRESSED = 10

# Overhead indeks dan chunk metadata (perkiraan kasar, sumber dokumentasi).
PROM_OVERHEAD_FRAC = 0.10    # +10% untuk indeks dan WAL
TSDB_OVERHEAD_FRAC = 0.20    # +20% untuk indeks, chunk, dan TOAST


def sampel_per_hari() -> int:
    series = NODES * SERIES_PER_NODE
    per_min = series * (60 // SAMPLE_INTERVAL_SEC)
    return per_min * 60 * 24


def ukuran_prometheus(hari: int) -> int:
    sampel = sampel_per_hari() * hari
    return int(sampel * PROM_BYTES_PER_SAMPLE * (1 + PROM_OVERHEAD_FRAC))


def ukuran_tsdb(hari: int) -> int:
    sampel = sampel_per_hari() * hari
    mentah = min(hari, TSDB_RETENSI_MENTAH_HARI) * sampel_per_hari()
    kompres = max(0, hari - TSDB_RETENSI_MENTAH_HARI) * sampel_per_hari()
    return int(
        (mentah * TSDB_BYTES_PER_SAMPLE_RAW
         + kompres * TSDB_BYTES_PER_SAMPLE_COMPRESSED)
        * (1 + TSDB_OVERHEAD_FRAC)
    )


def fmt_gib(byte: int) -> str:
    gib = byte / (1024 ** 3)
    return f"{gib:.2f} GiB"


def fmt_mib(byte: int) -> str:
    mib = byte / (1024 ** 2)
    return f"{mib:.1f} MiB"


def main() -> None:
    sps = sampel_per_hari()
    print("=== Beban kerja ===")
    print(f"node: {NODES}, deret per node: {SERIES_PER_NODE}, "
          f"total deret: {NODES * SERIES_PER_NODE}")
    print(f"interval scrap: {SAMPLE_INTERVAL_SEC} detik "
          f"({60 // SAMPLE_INTERVAL_SEC} sampel/menit/deret)")
    print(f"sampel per hari: {sps:,}")
    print()

    print("=== Retensi Prometheus (TSDB lokal, default 15 hari) ===")
    print(f"retensi: {PROM_RETENSI_HARI} hari")
    prom = ukuran_prometheus(PROM_RETENSI_HARI)
    print(f"ukuran: {prom:,} byte ({fmt_mib(prom)})")
    print(f"per sampel: ~{PROM_BYTES_PER_SAMPLE} byte (target TSDB)")
    print()

    print("=== Retensi TimescaleDB (1 tahun, kompresi setelah 7 hari) ===")
    print(f"retensi: {TSDB_RETENSI_HARI} hari, "
          f"mentah {TSDB_RETENSI_MENTAH_HARI} hari")
    tsdb = ukuran_tsdb(TSDB_RETENSI_HARI)
    print(f"ukuran: {tsdb:,} byte ({fmt_gib(tsdb)})")
    print(f"per sampel mentah: ~{TSDB_BYTES_PER_SAMPLE_RAW} byte, "
          f"terkompresi: ~{TSDB_BYTES_PER_SAMPLE_COMPRESSED} byte")
    print()

    print("=== Perbandingan pada retensi 15 hari ===")
    p15 = ukuran_prometheus(15)
    t15 = ukuran_tsdb(15)
    print(f"Prometheus: {fmt_mib(p15)}")
    print(f"TimescaleDB: {fmt_mib(t15)}")
    print(f"rasio tsdb/prom: {t15 / p15:.1f}x (Prometheus lebih ringkas)")
    print()

    print("=== Perbandingan pada retensi 365 hari ===")
    p365 = ukuran_prometheus(365)
    t365 = ukuran_tsdb(365)
    print(f"Prometheus (bila dipaksa): {fmt_gib(p365)}")
    print(f"TimescaleDB: {fmt_gib(t365)}")
    print(f"rasio tsdb/prom: {t365 / p365:.1f}x")
    print()

    print("Kesimpulan:")
    print(f"- Pada retensi 15 hari, TimescaleDB menggunakan {t15 / p15:.1f}x "
          f"lebih banyak disk daripada Prometheus.")
    print(f"- Pada retensi 365 hari, TimescaleDB menggunakan {t365 / p365:.1f}x "
          f"lebih banyak disk, sebab kompresi kolumnar TimescaleDB "
          f"mengecilkan baris lama, tetapi rasio byte per sampel tetap "
          f"lebih besar dari Prometheus TSDB.")
    print(f"- Prometheus tidak dirancang untuk retensi 365 hari, sehingga")
    print(f"  solusi praktis adalah memadukan Prometheus untuk 15 hari")
    print(f"  dengan basis data time-series untuk retensi panjang.")


if __name__ == "__main__":
    main()
text Keluaran
=== Beban kerja ===
node: 3, deret per node: 100, total deret: 300
interval scrap: 15 detik (4 sampel/menit/deret)
sampel per hari: 1,728,000

=== Retensi Prometheus (TSDB lokal, default 15 hari) ===
retensi: 15 hari
ukuran: 57,024,000 byte (54.4 MiB)
per sampel: ~2 byte (target TSDB)

=== Retensi TimescaleDB (1 tahun, kompresi setelah 7 hari) ===
retensi: 365 hari, mentah 7 hari
ukuran: 7,858,944,000 byte (7.32 GiB)
per sampel mentah: ~30 byte, terkompresi: ~10 byte

=== Perbandingan pada retensi 15 hari ===
Prometheus: 54.4 MiB
TimescaleDB: 573.5 MiB
rasio tsdb/prom: 10.5x (Prometheus lebih ringkas)

=== Perbandingan pada retensi 365 hari ===
Prometheus (bila dipaksa): 1.29 GiB
TimescaleDB: 7.32 GiB
rasio tsdb/prom: 5.7x

Kesimpulan:
- Pada retensi 15 hari, TimescaleDB menggunakan 10.5x lebih banyak disk daripada Prometheus.
- Pada retensi 365 hari, TimescaleDB menggunakan 5.7x lebih banyak disk, sebab kompresi kolumnar TimescaleDB mengecilkan baris lama, tetapi rasio byte per sampel tetap lebih besar dari Prometheus TSDB.
- Prometheus tidak dirancang untuk retensi 365 hari, sehingga
  solusi praktis adalah memadukan Prometheus untuk 15 hari
  dengan basis data time-series untuk retensi panjang.

Keluaran di atas memperlihatkan dua hal. Pertama, pada retensi 15 hari, Prometheus jauh lebih ringkas daripada TimescaleDB, sebab TSDB Prometheus dioptimalkan untuk metrik dengan kompresi Gorilla dan XOR. Kedua, pada retensi 365 hari, rasio TimescaleDB terhadap Prometheus turun karena kompresi kolumnar TimescaleDB mulai menyumbang, tetapi Prometheus tetap lebih kecil per sampel. Angka di sini hanya perkiraan kasar berdasarkan dokumentasi resmi, bukan pengukuran sebenarnya pada disk.

Kapan basis data time-series tetap cocok#

Prometheus adalah pilihan tepat bila kebutuhan utama adalah pemantauan operasional dengan retensi pendek, alerting atas ambang, dan dashboard dasar melalui Grafana. Skala kecil hingga menengah dengan sepuluh hingga ratusan node cocok dengan single-node Prometheus. Bila kebutuhan meluas ke analitik lintas dimensi, join dengan tabel dimensi, retensi panjang untuk audit tahunan, atau pelatihan model anomali, basis data time-series seperti TimescaleDB atau InfluxDB 3.x menjadi lebih sesuai.

Pemaduan kedua pendekatan adalah pola yang sering dijumpai pada produksi. Prometheus menjalankan scraping dan alerting pada level edge, lalu remote write mengirim salinan ke basis data time-series jangka panjang. Pemisahan ini memungkinkan Prometheus tetap ringan, sementara TimescaleDB melayani query analitik yang berat tanpa membebani mesin pemantauan. Pemilihan antara murni Prometheus atau pemaduan dengan basis data time-series bergantung pada panjang retensi yang diinginkan dan kompleksitas analisis yang dibutuhkan.

Kesalahan umum#

  • Memaksa Prometheus menyimpan satu tahun data dengan harapan menggantikan basis data time-series. Hasilnya adalah disk membengkak, performa query turun, dan pemulihan bila korupsi TSDB terjadi menjadi lambat.
  • Membandingkan langsung PromQL dengan SQL tanpa memperhatikan tujuan. PromQL unggul pada operasi metrik, sedangkan SQL unggul pada analitik lintas tabel, sehingga perbandingan harus mempertimbangkan beban kerja nyata.
  • Menggunakan Pushgateway sebagai pengganti pull untuk semua target. Pushgateway dirancang untuk batch job yang singkat, sehingga pemakaian pada long-running service menumpuk metrik usang dan menyesatkan alert.

Ringkasan#

  • Prometheus bekerja dengan model pull, di mana server mengambil metrik dari endpoint /metrics target pada interval tetap, biasanya 15 detik.
  • Retensi default Prometheus adalah 15 hari, dengan target ~1,3-2 byte per sampel setelah kompresi, sehingga cocok untuk pemantauan operasional waktu nyata.
  • PromQL unggul pada operasi metrik seperti rate dan histogram quantile, sedangkan SQL unggul pada analitik lintas tabel dan perhitungan kompleks.
  • Pemaduan Prometheus dengan basis data time-series seperti TimescaleDB atau InfluxDB 3.x adalah pola lazim pada produksi, di mana Prometheus melayani edge dan basis data time-series melayani retensi panjang.

Referensi#