FIELD NOTE · DEBUGGING · DEVOPS · JUN 2026

235K Restart yang Bunuh Server

Server berasa berat, load average naik terus, beberapa bot mulai telat respon. Pas dicek, dua systemd service lagi crash-looping: gagal start, di-restart, gagal lagi, di-restart lagi. Tiap 5 detik. Berhari-hari. Total tembus 235.000+ siklus restart sebelum ketahuan.

RESTART: 235K+ INTERVAL: 5s IMPACT: CPU + OOM LEVEL: Postmortem
— TL;DR

Dua service punya Restart=always + RestartSec=5 tapi tanpa StartLimitBurst dan StartLimitIntervalSec. Pas service gagal start karena error config, systemd nurut: restart terus tanpa batas. Akumulasi restart bikin CPU kepake percuma dan journal membengkak. Fix: pasang start-limit plus backoff, terus benerin akar error start-nya. Sekarang semua service restarts=0.

01

Gejala: Server Berat Tanpa Sebab Jelas

Awalnya cuma kerasa: bot yang biasa balas instan jadi ada jeda. htop nunjukin CPU kepake tinggi padahal nggak ada job berat yang lagi jalan. Yang aneh, beban itu nggak nempel ke satu proses gede, dia nyebar, muncul-ilang tiap beberapa detik.

Pola "muncul-ilang tiap beberapa detik" itu petunjuk pertama. Proses yang hidup-mati cepat biasanya bukan workload beneran. Itu sesuatu yang lagi di-restart berulang.

$ systemctl show forwarder-bot -p NRestarts --value 235000+

Angka NRestarts di salah satu service udah ratusan ribu. systemd dengan patuh nge-restart tiap kali proses-nya mati, dan proses-nya mati tiap 5 detik. Kali sekian hari, ketemu angka itu.

02

Diagnosa: Restart Loop Tanpa Rem

Akar masalahnya dua lapis. Lapis pertama: service-nya emang gagal start, ada error di config yang bikin proses exit beberapa detik setelah nyala. Lapis kedua, yang bikin jadi bencana: unit file-nya nggak punya rem.

# Unit file yang bermasalah [Service] ExecStart=/usr/bin/python3 /root/bot/main.py Restart=always RestartSec=5 # nggak ada StartLimitBurst # nggak ada StartLimitIntervalSec

Tanpa StartLimitBurst dan StartLimitIntervalSec, systemd nggak pernah nyerah. Harusnya kalau service gagal start sekian kali dalam jendela waktu tertentu, systemd masuk state failed dan berhenti nyoba. Di sini, dia restart selamanya.

Log-nya nunjukin pola yang sama berulang sampai mata pegel:

$ journalctl -u forwarder-bot --no-pager | tail Scheduled restart job, restart counter is at 235xxx. Started forwarder-bot.service. Process exited, code=exited, status=1/FAILURE Scheduled restart job, restart counter is at 235xxx.

Tiap siklus nulis beberapa baris ke journal. Dikali 235 ribu, journal jadi gendut dan ikut makan disk. Dua masalah sekaligus dari satu loop.

03

Fix: Pasang Rem, Benerin Akar

Urutan fix-nya penting. Kalau cuma pasang rem tapi nggak benerin error start-nya, service-nya bakal stop di state failed: nggak nge-loop lagi, tapi juga nggak jalan. Jadi dua-duanya dibenerin.

Satu, pasang start-limit di unit file:

[Unit] StartLimitIntervalSec=300 StartLimitBurst=5 [Service] ExecStart=/usr/bin/python3 /root/bot/main.py Restart=always RestartSec=10

Artinya: kalau service gagal start 5 kali dalam 300 detik, systemd berhenti nyoba dan tandai failed. Nggak ada lagi loop tak terbatas. RestartSec dinaikin ke 10 detik biar restart yang sah pun nggak terlalu agresif.

Dua, benerin akar error start-nya (di kasus ini config yang nggak ke-load). Setelah itu reload dan reset:

$ systemctl daemon-reload $ systemctl reset-failed forwarder-bot $ systemctl restart forwarder-bot $ systemctl show forwarder-bot -p NRestarts --value 0

Journal yang udah membengkak dirapihin biar disk balik lega:

$ journalctl --vacuum-time=7d
04

Lesson

Restart=always itu pisau bermata dua. Dia bikin service tahan banting, tapi tanpa start-limit dia juga bikin satu config error kecil berubah jadi loop yang ngabisin CPU dan disk diam-diam.

Rem dulu

StartLimit wajib

Tiap unit dengan Restart=always harus punya StartLimitBurst dan StartLimitIntervalSec. Tanpa itu, gagal start sama dengan loop selamanya.

Monitor

Pantau NRestarts

Restart count yang naik cepat itu sinyal, bukan angka biasa. Cron kecil yang alert kalau NRestarts lewat ambang bisa nyelametin berhari-hari.

Akar dulu

Jangan tutup gejala

Pasang rem doang bikin loop berhenti, tapi service tetap mati. Selalu benerin kenapa proses-nya exit, bukan cuma seberapa sering di-restart.

— CATATAN

Sekarang semua 9 service di server (forwarder, scalper, pearl-bridge, kol-detector, unified-scraper, dan lainnya) jalan dengan restarts=0 dan start-limit terpasang. Loop kayak gini nggak akan kejadian dua kali.