[{"data":1,"prerenderedAt":144},["ShallowReactive",2],{"site-header":3,"site-footer-license":42,"article-saldo-naik-empat-kali-untuk-satu-pembayaran-with-latest":46},{"navigations":4},[5,20,37],{"collection":6,"item":7},"series",{"__typename":6,"title":8,"slug":9,"children_series":10},"Artikel","all",[11,14,17],{"title":12,"slug":13},"Algoritma dan Struktur Data","algoritma-struktur-data",{"title":15,"slug":16},"Kecerdasan Artifisial","kecerdasan-artifisial",{"title":18,"slug":19},"Konsep Dasar Pemrograman","konsep-dasar-pemrograman",{"collection":6,"item":21},{"__typename":6,"title":22,"slug":23,"children_series":24},"Tutorial","tutorial",[25,28,31,34],{"title":26,"slug":27},"Belajar Java","belajar-java",{"title":29,"slug":30},"Belajar Pascal","belajar-pascal",{"title":32,"slug":33},"Belajar Golang","belajar-golang",{"title":35,"slug":36},"Belajar Python","belajar-python",{"collection":6,"item":38},{"__typename":6,"title":39,"slug":40,"children_series":41},"Lab","lab",[],{"name":43,"url":44,"show":45},"CC BY-SA","https://creativecommons.org/licenses/by-sa/4.0/",false,{"article":47,"renderedBody":87,"renderedTakeaway":88,"latestArticles":89,"toc":133},{"prerequisite":48,"id":49,"title":50,"slug":51,"excerpt":52,"published_at":48,"thumbnail_image":48,"tags":53,"reading_time":58,"takeway":59,"body":60,"authors":61,"series":67},null,"114","Saldo Naik Empat Kali untuk Satu Pembayaran","saldo-naik-empat-kali-untuk-satu-pembayaran","Kodenya nggak salah, dan gateway-nya juga nggak salah. Tapi satu pembayaran muncul empat kali di ledger. Coba tebak kenapa — lalu bikin `make check` hijau di lab-nya.",[54,55,56,57,40],"idempotency","webhook","postgres","database",4,"Empat baris ledger untuk satu pembayaran, dan nggak ada bug di kodenya.\n- HTTP nggak bisa memberi tahu pengirim bahwa jawabannya sampai, jadi pengiriman ulang itu normal, bukan kesalahan siapa pun.\n- Gateway memilih dobel daripada hilang; dobelnya yang jadi pekerjaanmu.\n- Dua puluh baris masuk ke ledger sementara saldo cuma naik dua kali: ada dua masalah berbeda di satu endpoint.\n- Pertanyaannya bukan \"di mana bugnya\", tapi siapa yang berhak memutuskan bahwa sebuah pembayaran sudah pernah diterima.","Sebuah merchant komplain: saldonya bertambah, tapi bukan dengan jumlah yang benar. Di laporan\nmutasi, satu pembayaran senilai dua puluh lima ribu muncul **empat kali**. Nilai saldonya naik\nempat kali lipat dari yang seharusnya.\n\nKamu buka kodenya. Endpoint `POST /webhooks/payments` — satu request masuk, satu baris ledger\nkeluar, saldo ditambah. Nggak ada `try/except` yang mencurigakan, nggak ada perulangan,\nnggak ada bug. Kalau kamu tes dengan mengirim request yang sama dua kali, hasilnya ya dua baris —\ntapi kamu juga yang mengirimnya dua kali, jadi itu wajar.\n\nSaya pernah ketemu sepupunya masalah ini di kerjaan pertama saya: bukan saldo yang dobel, tapi stok gudang yang angkanya ketinggalan beberapa langkah, dan barangnya keburu kebeli orang sebelum angkanya membaik. Bentuknya beda, akarnya sama — dan itu sebabnya lab ini ada. [Ceritanya di sini](/p/pub-sub-sendiri-lalu-belajar-idempotency).\n\nYang nggak kelihatan: **HTTP nggak punya cara memberi tahu pengirim bahwa jawaban kita sampai.**\nGateway mengirim eventnya, kita commit transaksinya, lalu jawabannya hilang di jalan — koneksi\nputus, load balancer timeout, container kita di-restart sedetik terlalu cepat. Dari sisi kita\nsemuanya beres. Dari sisi gateway, eventnya belum pernah diterima, jadi dia kirim lagi.\n\nItu bukan gateway yang rusak. Itu satu-satunya pilihan yang dia punya, dan dia memilih **dobel\ndaripada hilang** — karena kehilangan pembayaran lebih mahal daripada mengulangnya. Dobelnya jadi\npekerjaanmu.\n\nIni yang terjadi kalau kamu jalankan lab-nya:\n\n| | kondisi awal |\n|---|---|\n| satu event dikirim ulang 4× | **4 baris** ledger untuk 1 event, saldo naik **4× nominal** |\n| satu event dikirim 30× sekaligus | **30 baris**, dan saldo cuma naik sebagian (40.000–60.000 dari 300.000 yang seharusnya) |\n| 3 event berbeda, masing-masing dikirim 2× | **6 baris**, saldo naik **6× nominal** |\n| request yang persis sama dikirim 2× | **2 baris** — nggak ada apa pun di database yang bisa membedakan mana yang sudah pernah diproses |\n\nBaris kedua itu layak dibaca ulang. Dua puluh baris masuk ke ledger, tapi saldonya cuma naik dua\nkali — artinya ada **dua** masalah berbeda di satu endpoint, dan yang kedua bukan soal idempotensi\nsama sekali.\n\nKejadian yang sama bisa sampai ke sistemmu lewat tiga cara, dan ketiganya pernah saya alami:\n\n1. **Datang lebih dari sekali.** Gateway mengirim ulang karena jawabannya nggak sampai. Lab ini soal yang ini.\n2. **Datang dari dua jalur.** Webhook yang telat, plus job rekonsiliasi yang keburu menutup hari itu. Sudutnya ada di [lab satunya](/p/webhook-telat-job-rekonsiliasi-keburu-jalan).\n3. **Datang tidak berurutan.** Update yang datang belakangan membawa data yang lebih tua, dan yang lebih tua menang. Ini yang saya alami di stok gudang, dan bentuknya beda dari dua yang di atas.\n\nAkarnya satu: keputusan \"kejadian ini sudah pernah diterapkan atau belum\" diambil berdasarkan **kedatangan pesannya**, di aplikasi. Yang berhak memutuskan bukan aplikasimu, dan yang jadi patokan bukan urutan kedatangan.\n\n## Misi lab-nya\n\nEmpat syarat, dan `make check` memeriksa keempatnya:\n\n1. **Tepat sekali.** Satu event diterapkan tepat satu kali. Tidak dobel, dan tidak ada yang\n   hilang: tiga event berbeda tetap jadi tiga baris ledger, bukan enam, bukan dua.\n2. **Pengiriman ulang dijawab seperti jawaban pertama.** Bukan error, bukan pesan \"sudah\n   diproses\" — body yang sama, dengan `entry_id` yang sama. Alasannya bukan sekadar sopan:\n   jawaban yang dihitung ulang dari keadaan database **saat itu** bisa salah, karena saldonya\n   sudah berubah oleh event lain.\n3. **`event_id` yang dipakai ulang dengan isi berbeda tidak ikut diproses.** Nominal yang\n   berbeda untuk event yang sama tidak boleh masuk ke ledger.\n4. **Saldo tetap benar saat banyak event datang bersamaan.** Tiga puluh event *berbeda* yang\n   datang sekaligus harus menaikkan saldo tiga puluh kali nominal, bukan dua kali.\n\n## Kalau kamu mau mencobanya\n\nLab-nya repo publik, semuanya jalan di dalam Docker — nggak perlu install Postgres, Python, atau\napa pun:\n\n```bash\ngit clone https://github.com/izzudd/inva-lab.git\ncd inva-lab/idempotency\nmake up        # database + API\nmake replay    # putar ulang satu event, seperti yang dilakukan gateway\nmake check     # target: 21 pemeriksaan, semua hijau\n```\n\nAda `HINTS.md` dengan tiga tingkat petunjuk, dan aturan mainnya satu: jangan buka branch `solusi`\nsebelum kamu benar-benar mentok.\n\n## Pertanyaannya\n\nSebelum kamu menambahkan pengecekan apa pun, jawab ini dulu: **kenapa gateway mengirim ulang,\npadahal permintaan pertamanya dibalas 200?**\n\nKalau jawabannya belum jelas, semua tambalan yang kamu tulis cuma menutupi gejala. Dan begitu\njawabannya jelas, muncul pertanyaan kedua yang lebih menarik: kalau pengiriman ulang itu normal\ndan bukan kesalahan siapa pun, **siapa yang seharusnya memutuskan bahwa pembayaran ini sudah\npernah diterima — aplikasimu, atau database-nya?**\n\nVersi panjangnya, lengkap dengan argumen kenapa menambah `UNIQUE` saja justru bikin masalah baru,\nada di [artikel jawabannya](/p/jawaban-konflik-bukan-error).\n",[62],{"authors_id":63},{"name":64,"slug":65,"role":66,"profile_picture":48},"Daffa Izzuddin","izzudd","Writer",{"id":68,"title":39,"slug":40,"articles":69,"parent_series":48},"29",[70,78,80],{"id":71,"title":72,"slug":73,"excerpt":74,"thumbnail_image":48,"tags":75},"104","Query-nya Tinggal 2, Tapi Response-nya Masih 1 Detik","query-tinggal-2-tapi-response-masih-1-detik","Endpoint feed yang cuma menampilkan 20 tulisan butuh satu detik, dan server database dihujani 41 query. Kamu kerjakan nasihat N+1 yang standar, query-nya turun jadi 2, dan latency-nya nggak bergerak. Ini versi \"apa adanya\" dari masalah itu, plus lab-nya.",[57,76,77],"performance","backend",{"id":49,"title":50,"slug":51,"excerpt":52,"thumbnail_image":48,"tags":79},[54,55,56,57,40],{"id":81,"title":82,"slug":83,"excerpt":84,"thumbnail_image":48,"tags":85},"116","Webhook-nya Telat, Job Rekonsiliasinya Keburu Jalan","webhook-telat-job-rekonsiliasi-keburu-jalan","Jalur webhook sudah idempotent. Lalu ada job rekonsiliasi pagi, dan satu pembayaran tercatat dua kali dari dua jalur yang dua-duanya benar. Coba tebak kuncinya salah di mana.",[54,86,55,56,40],"reconciliation","\u003Cp>Sebuah merchant komplain: saldonya bertambah, tapi bukan dengan jumlah yang benar. Di laporan\nmutasi, satu pembayaran senilai dua puluh lima ribu muncul \u003Cstrong>empat kali\u003C/strong>. Nilai saldonya naik\nempat kali lipat dari yang seharusnya.\u003C/p>\n\u003Cp>Kamu buka kodenya. Endpoint \u003Ccode>POST /webhooks/payments\u003C/code> — satu request masuk, satu baris ledger\nkeluar, saldo ditambah. Nggak ada \u003Ccode>try/except\u003C/code> yang mencurigakan, nggak ada perulangan,\nnggak ada bug. Kalau kamu tes dengan mengirim request yang sama dua kali, hasilnya ya dua baris —\ntapi kamu juga yang mengirimnya dua kali, jadi itu wajar.\u003C/p>\n\u003Cp>Saya pernah ketemu sepupunya masalah ini di kerjaan pertama saya: bukan saldo yang dobel, tapi stok gudang yang angkanya ketinggalan beberapa langkah, dan barangnya keburu kebeli orang sebelum angkanya membaik. Bentuknya beda, akarnya sama — dan itu sebabnya lab ini ada. \u003Ca href=\"/p/pub-sub-sendiri-lalu-belajar-idempotency\">Ceritanya di sini\u003C/a>.\u003C/p>\n\u003Cp>Yang nggak kelihatan: \u003Cstrong>HTTP nggak punya cara memberi tahu pengirim bahwa jawaban kita sampai.\u003C/strong>\nGateway mengirim eventnya, kita commit transaksinya, lalu jawabannya hilang di jalan — koneksi\nputus, load balancer timeout, container kita di-restart sedetik terlalu cepat. Dari sisi kita\nsemuanya beres. Dari sisi gateway, eventnya belum pernah diterima, jadi dia kirim lagi.\u003C/p>\n\u003Cp>Itu bukan gateway yang rusak. Itu satu-satunya pilihan yang dia punya, dan dia memilih \u003Cstrong>dobel\ndaripada hilang\u003C/strong> — karena kehilangan pembayaran lebih mahal daripada mengulangnya. Dobelnya jadi\npekerjaanmu.\u003C/p>\n\u003Cp>Ini yang terjadi kalau kamu jalankan lab-nya:\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>\u003C/th>\n\u003Cth>kondisi awal\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>satu event dikirim ulang 4×\u003C/td>\n\u003Ctd>\u003Cstrong>4 baris\u003C/strong> ledger untuk 1 event, saldo naik \u003Cstrong>4× nominal\u003C/strong>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>satu event dikirim 30× sekaligus\u003C/td>\n\u003Ctd>\u003Cstrong>30 baris\u003C/strong>, dan saldo cuma naik sebagian (40.000–60.000 dari 300.000 yang seharusnya)\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>3 event berbeda, masing-masing dikirim 2×\u003C/td>\n\u003Ctd>\u003Cstrong>6 baris\u003C/strong>, saldo naik \u003Cstrong>6× nominal\u003C/strong>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>request yang persis sama dikirim 2×\u003C/td>\n\u003Ctd>\u003Cstrong>2 baris\u003C/strong> — nggak ada apa pun di database yang bisa membedakan mana yang sudah pernah diproses\u003C/td>\n\u003C/tr>\n\u003C/tbody>\u003C/table>\n\u003Cp>Baris kedua itu layak dibaca ulang. Dua puluh baris masuk ke ledger, tapi saldonya cuma naik dua\nkali — artinya ada \u003Cstrong>dua\u003C/strong> masalah berbeda di satu endpoint, dan yang kedua bukan soal idempotensi\nsama sekali.\u003C/p>\n\u003Cp>Kejadian yang sama bisa sampai ke sistemmu lewat tiga cara, dan ketiganya pernah saya alami:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Datang lebih dari sekali.\u003C/strong> Gateway mengirim ulang karena jawabannya nggak sampai. Lab ini soal yang ini.\u003C/li>\n\u003Cli>\u003Cstrong>Datang dari dua jalur.\u003C/strong> Webhook yang telat, plus job rekonsiliasi yang keburu menutup hari itu. Sudutnya ada di \u003Ca href=\"/p/webhook-telat-job-rekonsiliasi-keburu-jalan\">lab satunya\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Datang tidak berurutan.\u003C/strong> Update yang datang belakangan membawa data yang lebih tua, dan yang lebih tua menang. Ini yang saya alami di stok gudang, dan bentuknya beda dari dua yang di atas.\u003C/li>\n\u003C/ol>\n\u003Cp>Akarnya satu: keputusan &quot;kejadian ini sudah pernah diterapkan atau belum&quot; diambil berdasarkan \u003Cstrong>kedatangan pesannya\u003C/strong>, di aplikasi. Yang berhak memutuskan bukan aplikasimu, dan yang jadi patokan bukan urutan kedatangan.\u003C/p>\n\u003Ch2 id=\"misi-lab-nya\">Misi lab-nya\u003C/h2>\n\u003Cp>Empat syarat, dan \u003Ccode>make check\u003C/code> memeriksa keempatnya:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Tepat sekali.\u003C/strong> Satu event diterapkan tepat satu kali. Tidak dobel, dan tidak ada yang\nhilang: tiga event berbeda tetap jadi tiga baris ledger, bukan enam, bukan dua.\u003C/li>\n\u003Cli>\u003Cstrong>Pengiriman ulang dijawab seperti jawaban pertama.\u003C/strong> Bukan error, bukan pesan &quot;sudah\ndiproses&quot; — body yang sama, dengan \u003Ccode>entry_id\u003C/code> yang sama. Alasannya bukan sekadar sopan:\njawaban yang dihitung ulang dari keadaan database \u003Cstrong>saat itu\u003C/strong> bisa salah, karena saldonya\nsudah berubah oleh event lain.\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode>event_id\u003C/code> yang dipakai ulang dengan isi berbeda tidak ikut diproses.\u003C/strong> Nominal yang\nberbeda untuk event yang sama tidak boleh masuk ke ledger.\u003C/li>\n\u003Cli>\u003Cstrong>Saldo tetap benar saat banyak event datang bersamaan.\u003C/strong> Tiga puluh event \u003Cem>berbeda\u003C/em> yang\ndatang sekaligus harus menaikkan saldo tiga puluh kali nominal, bukan dua kali.\u003C/li>\n\u003C/ol>\n\u003Ch2 id=\"kalau-kamu-mau-mencobanya\">Kalau kamu mau mencobanya\u003C/h2>\n\u003Cp>Lab-nya repo publik, semuanya jalan di dalam Docker — nggak perlu install Postgres, Python, atau\napa pun:\u003C/p>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black/40 inline-block\">\u003C/span>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">BASH\u003C/span>\n    \u003C/div>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"git%20clone%20https%3A%2F%2Fgithub.com%2Fizzudd%2Finva-lab.git%0Acd%20inva-lab%2Fidempotency%0Amake%20up%20%20%20%20%20%20%20%20%23%20database%20%2B%20API%0Amake%20replay%20%20%20%20%23%20putar%20ulang%20satu%20event%2C%20seperti%20yang%20dilakukan%20gateway%0Amake%20check%20%20%20%20%20%23%20target%3A%2021%20pemeriksaan%2C%20semua%20hijau\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C/path>\n      \u003C/svg>\n      \u003Cspan class=\"copy-text\">Copy\u003C/span>\n    \u003C/button>\n  \u003C/div>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">git\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> clone\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> https://github.com/izzudd/inva-lab.git\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">cd\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> inva-lab/idempotency\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">make\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> up\u003C/span>\u003Cspan style=\"color:#6A737D\">        # database + API\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">make\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> replay\u003C/span>\u003Cspan style=\"color:#6A737D\">    # putar ulang satu event, seperti yang dilakukan gateway\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">make\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> check\u003C/span>\u003Cspan style=\"color:#6A737D\">     # target: 21 pemeriksaan, semua hijau\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n  \u003C/div>\n\u003C/div>\u003Cp>Ada \u003Ccode>HINTS.md\u003C/code> dengan tiga tingkat petunjuk, dan aturan mainnya satu: jangan buka branch \u003Ccode>solusi\u003C/code>\nsebelum kamu benar-benar mentok.\u003C/p>\n\u003Ch2 id=\"pertanyaannya\">Pertanyaannya\u003C/h2>\n\u003Cp>Sebelum kamu menambahkan pengecekan apa pun, jawab ini dulu: \u003Cstrong>kenapa gateway mengirim ulang,\npadahal permintaan pertamanya dibalas 200?\u003C/strong>\u003C/p>\n\u003Cp>Kalau jawabannya belum jelas, semua tambalan yang kamu tulis cuma menutupi gejala. Dan begitu\njawabannya jelas, muncul pertanyaan kedua yang lebih menarik: kalau pengiriman ulang itu normal\ndan bukan kesalahan siapa pun, \u003Cstrong>siapa yang seharusnya memutuskan bahwa pembayaran ini sudah\npernah diterima — aplikasimu, atau database-nya?\u003C/strong>\u003C/p>\n\u003Cp>Versi panjangnya, lengkap dengan argumen kenapa menambah \u003Ccode>UNIQUE\u003C/code> saja justru bikin masalah baru,\nada di \u003Ca href=\"/p/jawaban-konflik-bukan-error\">artikel jawabannya\u003C/a>.\u003C/p>\n","\u003Cp>Empat baris ledger untuk satu pembayaran, dan nggak ada bug di kodenya.\u003C/p>\n\u003Cul>\n\u003Cli>HTTP nggak bisa memberi tahu pengirim bahwa jawabannya sampai, jadi pengiriman ulang itu normal, bukan kesalahan siapa pun.\u003C/li>\n\u003Cli>Gateway memilih dobel daripada hilang; dobelnya yang jadi pekerjaanmu.\u003C/li>\n\u003Cli>Dua puluh baris masuk ke ledger sementara saldo cuma naik dua kali: ada dua masalah berbeda di satu endpoint.\u003C/li>\n\u003Cli>Pertanyaannya bukan &quot;di mana bugnya&quot;, tapi siapa yang berhak memutuskan bahwa sebuah pembayaran sudah pernah diterima.\u003C/li>\n\u003C/ul>\n",[90,100,111,113,121,131],{"id":91,"title":92,"slug":93,"excerpt":94,"thumbnail_image":48,"tags":95},"113","Garbage Collector dituduh bikin aplikasi lemot. Seberapa adil tuduhan itu?","garbage-collector-dituduh-bikin-aplikasi-lemot","GC sering jadi tersangka utama tiap aplikasi melambat, dan banyak yang percaya dia jalan pakai timer tiap beberapa detik. Dua-duanya nggak sepenuhnya benar. Yuk bedah cara kerja GC dari dalam, plus satu pengecualian yang bikin Discord kesakitan tiap 2 menit. 🤔",[77,76,96,97,98,99],"golang","jvm","garbage-collector","memory",{"id":101,"title":102,"slug":103,"excerpt":104,"thumbnail_image":48,"tags":105},"111","Rust Masuk Kernel Linux: Revolusi Nyata atau Cuma Euforia RIIR?","rust-di-kernel-linux-revolusi-atau-cuma-hype","Selama lebih dari 30 tahun kernel Linux cuma mau bahasa C, lalu tiba-tiba Rust resmi masuk di Linux 6.1. Itu revolusi beneran atau cuma kebawa euforia meme Rewrite It In Rust? Yuk lihat datanya, bukan cuma opininya.",[106,107,108,109,110],"rust","linux","kernel","system-programming","memory-safety",{"id":49,"title":50,"slug":51,"excerpt":52,"thumbnail_image":48,"tags":112},[54,55,56,57,40],{"id":114,"title":115,"slug":116,"excerpt":117,"thumbnail_image":48,"tags":118},"112","Aplikasimu lambat, dan kamu udah kepikiran ganti bahasa. Tunggu dulu","aplikasimu-lambat-dan-kamu-udah-kepikiran-ganti-bahasa-tunggu-dulu","Ada endpoint yang grafiknya spike tiap beberapa menit, dan kepikiran buat pindah dari Go ke Rust? Discord dan Cloudflare beneran melakukannya — tapi cuma setelah kehabisan cara lain dan punya datanya. Yuk, bedah gejala mana yang beneran butuh rewrite, dan mana yang cuma butuh profiling. 🤔",[77,76,96,106,119,120],"system-design","profiling",{"id":122,"title":123,"slug":124,"excerpt":125,"thumbnail_image":48,"tags":126},"118","Belajar Idempotency dari Stok yang Keburu Kebeli","pub-sub-sendiri-lalu-belajar-idempotency","Tugas pertama saya di kerjaan pertama: sistem yang kewalahan menerima webhook. Saya putuskan membangun pub/sub sendiri dari nol, dan pelajaran yang akhirnya datang bukan dari situ — tapi dari stok gudang yang keburu kebeli orang.",[54,127,128,129,130],"event-driven","celery","rabbitmq","post-mortem",{"id":81,"title":82,"slug":83,"excerpt":84,"thumbnail_image":48,"tags":132},[54,86,55,56,40],[134,138,141],{"text":135,"depth":136,"id":137},"Misi lab-nya",2,"misi-lab-nya",{"text":139,"depth":136,"id":140},"Kalau kamu mau mencobanya","kalau-kamu-mau-mencobanya",{"text":142,"depth":136,"id":143},"Pertanyaannya","pertanyaannya",1791651537517]