[{"data":1,"prerenderedAt":147},["ShallowReactive",2],{"site-header":3,"site-footer-license":42,"article-webhook-telat-job-rekonsiliasi-keburu-jalan-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,"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,55,56,57,40],"idempotency","reconciliation","webhook","postgres",3,"Dua jalur yang sama-sama benar tetap bisa mencatat satu pembayaran dua kali.\n- Jalur webhook memakai kunci milik pesannya; job rekonsiliasi membuat kuncinya sendiri — dan keduanya nggak pernah bertemu.\n- Job yang dijalankan dua kali melaporkan `inserted=6` dua kali, dengan yakin, untuk hari yang sudah selesai.\n- Kunci yang benar bukan kunci yang unik, tapi kunci yang dimiliki oleh faktanya, bukan oleh pesannya.\n- Dua jalur boleh punya kebijakan berbeda waktu menemukan keanehan — penunggunya memang berbeda.","Gateway-nya down semalam. Pembayaran yang terjadi di sisi mereka nggak ada yang sampai ke kita\nlewat webhook, dan pagi harinya job rekonsiliasi membaca laporan settlement hari itu lalu menutup\nyang belum tercatat. Sampai di sini semua benar — job-nya bekerja persis seperti yang dimaksud.\n\nLalu jam sebelas siang, gateway mengirim ulang webhook yang belum pernah dijawab. Dan satu\npembayaran yang sama tercatat dua kali: satu dari job, satu dari webhook.\n\nBukan karena salah satunya rusak. Jalur webhook-nya sudah idempotent — dia jawaban lab sebelumnya,\nlengkap dengan klaim per event dan jawaban yang disimpan. Job-nya juga benar untuk pertanyaan yang\ndia jawab. Masalahnya cuma satu: **keduanya memakai kunci yang berbeda, dan nggak ada satu pun dari\nkeduanya yang tahu bahwa jalur satunya ada.**\n\n| | kondisi awal |\n|---|---|\n| 3 webhook malam itu, lalu job rekonsiliasi paginya | 6 pembayaran jadi **9 baris** — 3 di antaranya punya dua baris, satu dari tiap jalur |\n| webhook yang telat akhirnya sampai | 6 pembayaran jadi **12 baris**; saldo 665.000 dari 220.000 yang seharusnya |\n| job rekonsiliasi dijalankan dua kali | **6 baris baru** tiap kali, dan job-nya melaporkan `inserted=6` — bukan 0 |\n| dua run job jalan bersamaan | **12 baris** untuk 6 pembayaran |\n| laporan settlement beda nominal dengan yang sudah tercatat | **2 baris** untuk 1 pembayaran, dan `mismatched` tetap kosong |\n\nPerhatikan baris ketiga. Job-nya bukan cuma menulis dobel — dia **melaporkan** bahwa dia menulis\nenam baris baru, dengan yakin, untuk hari yang sebenarnya sudah selesai.\n\nDi kerjaan pertama saya jalur keduanya bukan job rekonsiliasi, tapi panggilan balik ke backend storefront yang beda — dan bentuk masalahnya persis sama: satu fakta, dua jalur, dua kunci yang nggak pernah bertemu. [Ceritanya di sini](/p/pub-sub-sendiri-lalu-belajar-idempotency).\n\nIni sudut kedua dari tiga sudut yang saya rapikan di situ:\n\n1. **Datang lebih dari sekali** → [lab sebelumnya](/p/saldo-naik-empat-kali-untuk-satu-pembayaran).\n2. **Datang dari dua jalur** → lab ini.\n3. **Datang tidak berurutan** → yang bikin stok gudang saya salah; bentuknya beda dari lab ini.\n\nAkarnya satu: keputusan \"sudah pernah diterapkan atau belum\" diambil berdasarkan kedatangan\npesannya, di aplikasi — bukan di database, dengan kunci dan patokan waktu yang dimiliki faktanya\nsendiri.\n\n## Misi lab-nya\n\nTiga syarat:\n\n1. **Satu pembayaran, satu baris.** Dari jalur mana pun, dan berapa kali pun jalurnya dipanggil.\n2. **Job boleh dijalankan lagi, dan laporannya jujur.** Run kedua untuk hari yang sama nggak\n   menambah baris dan melaporkan `inserted=0`. Run yang cuma sanggup memproses sebagian boleh\n   dilanjutkan kapan saja. Dua run yang tumpang tindih juga nggak boleh mendobel.\n3. **Nominal yang sudah tercatat nggak berubah diam-diam.** Kalau laporan settlement menyebut\n   nominal yang berbeda, barisnya tetap satu, nominalnya tetap yang pertama, dan perbedaannya\n   **dilaporkan** — bukan ditelan.\n\n## Kenapa ini layak dicoba\n\nDi lab sebelumnya, \"pembayaran\" dan \"pesan yang memberitahukan pembayaran itu\" selalu datang\nberpasangan, jadi nggak pernah ada bedanya. Begitu ada jalur kedua, bedanya jadi hal paling penting\ndi seluruh sistem: **kunci yang benar bukan kunci yang unik, tapi kunci yang dimiliki oleh\nfaktanya — bukan oleh pesannya.**\n\nDan bagian kedua yang lebih halus: dua jalur yang sama-sama benar bisa butuh **kebijakan yang\nberbeda** waktu menemukan keanehan. Webhook boleh membalas 409 untuk satu event yang aneh; job\nrekonsiliasi nggak boleh mati cuma karena satu baris laporan nggak cocok.\n\n## Kalau kamu mau mencobanya\n\n```bash\ngit clone https://github.com/izzudd/inva-lab.git\ncd inva-lab/reconciliation\nmake up      # database + API + gateway tiruan\nmake demo    # cerita lengkapnya: webhook malam itu, job paginya, webhook yang telat\nmake check   # target: 24 pemeriksaan, semua hijau\n```\n\nGateway-nya tiruan dan laporannya dibangkitkan dari tanggalnya, jadi kamu bisa pakai tanggal apa\npun: `make demo DAY=2024-03-17`.\n\n## Pertanyaannya\n\nJob rekonsiliasi itu jalur kedua yang menerima satu fakta lewat dua kunci berbeda. Sebelum\nmenyentuh kode, jawab ini: **kunci mana yang berasal dari pembayarannya, dan kunci mana yang\nberasal dari pesan yang memberitahukannya?** Dan yang kedua: kenapa job-nya harus membuat kuncinya\nsendiri, padahal jalur webhook sudah punya kunci yang unik?\n\nJawaban lengkapnya, termasuk kenapa menghapus id run dari kuncinya juga menghapus kebutuhan akan\nkursor, ada di [artikel jawabannya](/p/jawaban-kunci-itu-milik-faktanya).\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,79,85],{"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.",[76,77,78],"database","performance","backend",{"id":80,"title":81,"slug":82,"excerpt":83,"thumbnail_image":48,"tags":84},"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,56,57,76,40],{"id":49,"title":50,"slug":51,"excerpt":52,"thumbnail_image":48,"tags":86},[54,55,56,57,40],"\u003Cp>Gateway-nya down semalam. Pembayaran yang terjadi di sisi mereka nggak ada yang sampai ke kita\nlewat webhook, dan pagi harinya job rekonsiliasi membaca laporan settlement hari itu lalu menutup\nyang belum tercatat. Sampai di sini semua benar — job-nya bekerja persis seperti yang dimaksud.\u003C/p>\n\u003Cp>Lalu jam sebelas siang, gateway mengirim ulang webhook yang belum pernah dijawab. Dan satu\npembayaran yang sama tercatat dua kali: satu dari job, satu dari webhook.\u003C/p>\n\u003Cp>Bukan karena salah satunya rusak. Jalur webhook-nya sudah idempotent — dia jawaban lab sebelumnya,\nlengkap dengan klaim per event dan jawaban yang disimpan. Job-nya juga benar untuk pertanyaan yang\ndia jawab. Masalahnya cuma satu: \u003Cstrong>keduanya memakai kunci yang berbeda, dan nggak ada satu pun dari\nkeduanya yang tahu bahwa jalur satunya ada.\u003C/strong>\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>3 webhook malam itu, lalu job rekonsiliasi paginya\u003C/td>\n\u003Ctd>6 pembayaran jadi \u003Cstrong>9 baris\u003C/strong> — 3 di antaranya punya dua baris, satu dari tiap jalur\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>webhook yang telat akhirnya sampai\u003C/td>\n\u003Ctd>6 pembayaran jadi \u003Cstrong>12 baris\u003C/strong>; saldo 665.000 dari 220.000 yang seharusnya\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>job rekonsiliasi dijalankan dua kali\u003C/td>\n\u003Ctd>\u003Cstrong>6 baris baru\u003C/strong> tiap kali, dan job-nya melaporkan \u003Ccode>inserted=6\u003C/code> — bukan 0\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>dua run job jalan bersamaan\u003C/td>\n\u003Ctd>\u003Cstrong>12 baris\u003C/strong> untuk 6 pembayaran\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>laporan settlement beda nominal dengan yang sudah tercatat\u003C/td>\n\u003Ctd>\u003Cstrong>2 baris\u003C/strong> untuk 1 pembayaran, dan \u003Ccode>mismatched\u003C/code> tetap kosong\u003C/td>\n\u003C/tr>\n\u003C/tbody>\u003C/table>\n\u003Cp>Perhatikan baris ketiga. Job-nya bukan cuma menulis dobel — dia \u003Cstrong>melaporkan\u003C/strong> bahwa dia menulis\nenam baris baru, dengan yakin, untuk hari yang sebenarnya sudah selesai.\u003C/p>\n\u003Cp>Di kerjaan pertama saya jalur keduanya bukan job rekonsiliasi, tapi panggilan balik ke backend storefront yang beda — dan bentuk masalahnya persis sama: satu fakta, dua jalur, dua kunci yang nggak pernah bertemu. \u003Ca href=\"/p/pub-sub-sendiri-lalu-belajar-idempotency\">Ceritanya di sini\u003C/a>.\u003C/p>\n\u003Cp>Ini sudut kedua dari tiga sudut yang saya rapikan di situ:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Datang lebih dari sekali\u003C/strong> → \u003Ca href=\"/p/saldo-naik-empat-kali-untuk-satu-pembayaran\">lab sebelumnya\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Datang dari dua jalur\u003C/strong> → lab ini.\u003C/li>\n\u003Cli>\u003Cstrong>Datang tidak berurutan\u003C/strong> → yang bikin stok gudang saya salah; bentuknya beda dari lab ini.\u003C/li>\n\u003C/ol>\n\u003Cp>Akarnya satu: keputusan &quot;sudah pernah diterapkan atau belum&quot; diambil berdasarkan kedatangan\npesannya, di aplikasi — bukan di database, dengan kunci dan patokan waktu yang dimiliki faktanya\nsendiri.\u003C/p>\n\u003Ch2 id=\"misi-lab-nya\">Misi lab-nya\u003C/h2>\n\u003Cp>Tiga syarat:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Satu pembayaran, satu baris.\u003C/strong> Dari jalur mana pun, dan berapa kali pun jalurnya dipanggil.\u003C/li>\n\u003Cli>\u003Cstrong>Job boleh dijalankan lagi, dan laporannya jujur.\u003C/strong> Run kedua untuk hari yang sama nggak\nmenambah baris dan melaporkan \u003Ccode>inserted=0\u003C/code>. Run yang cuma sanggup memproses sebagian boleh\ndilanjutkan kapan saja. Dua run yang tumpang tindih juga nggak boleh mendobel.\u003C/li>\n\u003Cli>\u003Cstrong>Nominal yang sudah tercatat nggak berubah diam-diam.\u003C/strong> Kalau laporan settlement menyebut\nnominal yang berbeda, barisnya tetap satu, nominalnya tetap yang pertama, dan perbedaannya\n\u003Cstrong>dilaporkan\u003C/strong> — bukan ditelan.\u003C/li>\n\u003C/ol>\n\u003Ch2 id=\"kenapa-ini-layak-dicoba\">Kenapa ini layak dicoba\u003C/h2>\n\u003Cp>Di lab sebelumnya, &quot;pembayaran&quot; dan &quot;pesan yang memberitahukan pembayaran itu&quot; selalu datang\nberpasangan, jadi nggak pernah ada bedanya. Begitu ada jalur kedua, bedanya jadi hal paling penting\ndi seluruh sistem: \u003Cstrong>kunci yang benar bukan kunci yang unik, tapi kunci yang dimiliki oleh\nfaktanya — bukan oleh pesannya.\u003C/strong>\u003C/p>\n\u003Cp>Dan bagian kedua yang lebih halus: dua jalur yang sama-sama benar bisa butuh \u003Cstrong>kebijakan yang\nberbeda\u003C/strong> waktu menemukan keanehan. Webhook boleh membalas 409 untuk satu event yang aneh; job\nrekonsiliasi nggak boleh mati cuma karena satu baris laporan nggak cocok.\u003C/p>\n\u003Ch2 id=\"kalau-kamu-mau-mencobanya\">Kalau kamu mau mencobanya\u003C/h2>\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%2Freconciliation%0Amake%20up%20%20%20%20%20%20%23%20database%20%2B%20API%20%2B%20gateway%20tiruan%0Amake%20demo%20%20%20%20%23%20cerita%20lengkapnya%3A%20webhook%20malam%20itu%2C%20job%20paginya%2C%20webhook%20yang%20telat%0Amake%20check%20%20%20%23%20target%3A%2024%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/reconciliation\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 + gateway tiruan\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">make\u003C/span>\u003Cspan style=\"color:#9ECBFF\"> demo\u003C/span>\u003Cspan style=\"color:#6A737D\">    # cerita lengkapnya: webhook malam itu, job paginya, webhook yang telat\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: 24 pemeriksaan, semua hijau\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n  \u003C/div>\n\u003C/div>\u003Cp>Gateway-nya tiruan dan laporannya dibangkitkan dari tanggalnya, jadi kamu bisa pakai tanggal apa\npun: \u003Ccode>make demo DAY=2024-03-17\u003C/code>.\u003C/p>\n\u003Ch2 id=\"pertanyaannya\">Pertanyaannya\u003C/h2>\n\u003Cp>Job rekonsiliasi itu jalur kedua yang menerima satu fakta lewat dua kunci berbeda. Sebelum\nmenyentuh kode, jawab ini: \u003Cstrong>kunci mana yang berasal dari pembayarannya, dan kunci mana yang\nberasal dari pesan yang memberitahukannya?\u003C/strong> Dan yang kedua: kenapa job-nya harus membuat kuncinya\nsendiri, padahal jalur webhook sudah punya kunci yang unik?\u003C/p>\n\u003Cp>Jawaban lengkapnya, termasuk kenapa menghapus id run dari kuncinya juga menghapus kebutuhan akan\nkursor, ada di \u003Ca href=\"/p/jawaban-kunci-itu-milik-faktanya\">artikel jawabannya\u003C/a>.\u003C/p>\n","\u003Cp>Dua jalur yang sama-sama benar tetap bisa mencatat satu pembayaran dua kali.\u003C/p>\n\u003Cul>\n\u003Cli>Jalur webhook memakai kunci milik pesannya; job rekonsiliasi membuat kuncinya sendiri — dan keduanya nggak pernah bertemu.\u003C/li>\n\u003Cli>Job yang dijalankan dua kali melaporkan \u003Ccode>inserted=6\u003C/code> dua kali, dengan yakin, untuk hari yang sudah selesai.\u003C/li>\n\u003Cli>Kunci yang benar bukan kunci yang unik, tapi kunci yang dimiliki oleh faktanya, bukan oleh pesannya.\u003C/li>\n\u003Cli>Dua jalur boleh punya kebijakan berbeda waktu menemukan keanehan — penunggunya memang berbeda.\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. 🤔",[78,77,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":80,"title":81,"slug":82,"excerpt":83,"thumbnail_image":48,"tags":112},[54,56,57,76,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. 🤔",[78,77,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":49,"title":50,"slug":51,"excerpt":52,"thumbnail_image":48,"tags":132},[54,55,56,57,40],[134,138,141,144],{"text":135,"depth":136,"id":137},"Misi lab-nya",2,"misi-lab-nya",{"text":139,"depth":136,"id":140},"Kenapa ini layak dicoba","kenapa-ini-layak-dicoba",{"text":142,"depth":136,"id":143},"Kalau kamu mau mencobanya","kalau-kamu-mau-mencobanya",{"text":145,"depth":136,"id":146},"Pertanyaannya","pertanyaannya",1791651538656]