[{"data":1,"prerenderedAt":315},["ShallowReactive",2],{"tag-labels":3,"site-header":4,"article-cache-hit-rate-zero-en":72},{},{"featuredPost":5,"navigations":29},{"id":6,"title":7,"title_id":8,"slug":9,"excerpt":10,"excerpt_id":11,"has_translation":12,"published_at":13,"reading_time":14,"hidden_from_listing":15,"tags":16,"thumbnail_image":21,"og_image":22,"series":23,"authors":28},110,"When You Pick a Framework Just to Look Different","Ketika Pilih Framework Cuma Biar Kelihatan Beda","ketika-pilih-framework-cuma-biar-kelihatan-beda","The last time you chose a new framework or library, was it because your problem needed that tool, or because it sounded cool and few people around you were using it? That question is uncomfortable. Technology decisions are often made for reasons that never appear in any technical document.","Terakhir kali kamu milih framework atau library baru, itu karena masalahmu butuh alat itu, atau karena alatnya kedengaran keren dan belum banyak yang pakai? Pertanyaan ini nggak enak dijawab. Soalnya keputusan teknologi sering diambil dengan alasan yang nggak pernah ditulis di dokumen teknis mana pun.",true,"2026-10-06T15:25:21.000Z",5,false,[17,18,19,20],"karier","framework","opini","pengalaman",null,"\u002Fog\u002Fketika-pilih-framework-cuma-biar-kelihatan-beda.png",{"id":24,"title":25,"title_id":26,"slug":27},9,"Articles","Artikel","all",[],[30,46,67],{"collection":31,"item":32},"series",{"__typename":31,"title":25,"title_id":26,"slug":27,"children_series":33},[34,38,42],{"title":35,"title_id":36,"slug":37},"Artificial Intelligence","Kecerdasan Artifisial","kecerdasan-artifisial",{"title":39,"title_id":40,"slug":41},"Programming Fundamentals","Konsep Dasar Pemrograman","konsep-dasar-pemrograman",{"title":43,"title_id":44,"slug":45},"Algorithms and Data Structures","Algoritma dan Struktur Data","algoritma-struktur-data",{"collection":31,"item":47},{"__typename":31,"title":48,"title_id":48,"slug":49,"children_series":50},"Tutorial","tutorial",[51,55,59,63],{"title":52,"title_id":53,"slug":54},"Learning Python","Belajar Python","belajar-python",{"title":56,"title_id":57,"slug":58},"Learning Go","Belajar Golang","belajar-golang",{"title":60,"title_id":61,"slug":62},"Learning Java","Belajar Java","belajar-java",{"title":64,"title_id":65,"slug":66},"Learning Pascal","Belajar Pascal","belajar-pascal",{"collection":31,"item":68},{"__typename":31,"title":69,"title_id":69,"slug":70,"children_series":71},"Lab","lab",[],{"article":73,"renderedBody":192,"renderedTakeaway":193,"latestArticles":194,"toc":298},{"id":74,"title":75,"title_id":76,"slug":77,"excerpt":78,"excerpt_id":79,"has_translation":12,"published_at":80,"reading_time":81,"hidden_from_listing":15,"tags":82,"thumbnail_image":21,"og_image":86,"series":87,"authors":184,"seoTitle":21,"seoDescription":21,"body_locale":187,"available_locales":188,"body":190,"takeway":191,"prerequisite":21},141,"A 6,000-Token Handbook and a 0% Cache Hit Rate","Buku Panduan 6.000 Token dan Hit Rate Cache 0%","cache-hit-rate-zero","Twenty-four turns, caching switched on, and a bill 21% higher than running with no cache at all. A support agent whose prompt looks static, and the three lines that quietly change it every turn.","Dua puluh empat giliran, caching menyala, dan tagihan 21% lebih tinggi daripada menjalankannya tanpa cache sama sekali. Agen support yang prompt-nya kelihatan statis, dan tiga baris yang diam-diam mengubahnya tiap giliran.","2026-11-08T01:20:00.000Z",3,[70,83,84,85],"llm","cache","api","\u002Fog\u002Fcache-hit-rate-zero.png",{"id":88,"title":69,"title_id":69,"slug":70,"description":89,"description_id":90,"articles":91,"children_series":183,"parent_series":21},29,"Practice labs: work the problem first, then read the answer. Every lab ships with a repo you can clone, production-sized data, and a target you have to hit yourself. The write-up lives in this series too, and it only opens from the problem article.","Lab praktik: kerjakan masalahnya dulu, baru lihat jawabannya. Tiap lab punya repo yang bisa di-clone, data seukuran produksi, dan target yang harus kamu capai sendiri. Artikel jawabannya ada di seri ini juga, dan cuma bisa kamu buka dari artikel masalahnya.",[92,113,131,146,163,178],{"id":93,"title":94,"title_id":95,"slug":96,"excerpt":97,"excerpt_id":98,"has_translation":12,"published_at":99,"reading_time":14,"hidden_from_listing":15,"tags":100,"thumbnail_image":21,"og_image":104,"series":105,"authors":106},104,"N+1 Was Never the Bottleneck: 41 Queries Down to 2, Still One Second","Query-nya Tinggal 2, Tapi Response-nya Masih 1 Detik","query-tinggal-2-tapi-response-masih-1-detik","A feed endpoint that shows 20 posts takes a full second and hits the database with 41 queries. Apply the standard N+1 advice, get it down to 2 queries, and the latency does not move. This is that problem as it happened, plus the lab.","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.","2026-10-04T09:59:21.000Z",[101,102,103],"database","performance","backend","\u002Fog\u002Fquery-tinggal-2-tapi-response-masih-1-detik.png",{"id":88,"title":69,"title_id":69,"slug":70},[107],{"authors_id":108},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},1,"Daffa Izzuddin","izzudd","Writer",{"id":114,"title":115,"title_id":116,"slug":117,"excerpt":118,"excerpt_id":119,"has_translation":12,"published_at":120,"reading_time":121,"hidden_from_listing":15,"tags":122,"thumbnail_image":21,"og_image":126,"series":127,"authors":128},114,"One Payment, Four Ledger Rows: An Idempotency Lab","Saldo Naik Empat Kali untuk Satu Pembayaran","saldo-naik-empat-kali-untuk-satu-pembayaran","The code is not wrong and the gateway is not wrong, yet one payment shows up four times in the ledger. Guess why, then make `make check` green in the lab.","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.","2026-10-11T13:45:00.000Z",4,[123,124,125,101,70],"idempotency","webhook","postgres","\u002Fog\u002Fsaldo-naik-empat-kali-untuk-satu-pembayaran.png",{"id":88,"title":69,"title_id":69,"slug":70},[129],{"authors_id":130},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":132,"title":133,"title_id":134,"slug":135,"excerpt":136,"excerpt_id":137,"has_translation":12,"published_at":138,"reading_time":81,"hidden_from_listing":15,"tags":139,"thumbnail_image":21,"og_image":141,"series":142,"authors":143},116,"The Webhook Arrived Late. The Reconciliation Job Had Already Run.","Webhook-nya Telat, Job Rekonsiliasinya Keburu Jalan","webhook-telat-job-rekonsiliasi-keburu-jalan","The webhook path is already idempotent. Then a morning reconciliation job appears, and one payment gets recorded twice from two paths that are both right. Guess where the key is wrong.","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.","2026-10-11T13:44:00.000Z",[123,140,124,125,70],"reconciliation","\u002Fog\u002Fwebhook-telat-job-rekonsiliasi-keburu-jalan.png",{"id":88,"title":69,"title_id":69,"slug":70},[144],{"authors_id":145},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":147,"title":148,"title_id":149,"slug":150,"excerpt":151,"excerpt_id":152,"has_translation":12,"published_at":153,"reading_time":121,"hidden_from_listing":15,"tags":154,"thumbnail_image":21,"og_image":158,"series":159,"authors":160},120,"Every Receipt in This Café Lists the Same Order","Tiap Nota di Kafe Ini Isinya Pesanan yang Sama","tiap-nota-isinya-pesanan-yang-sama","Every table's receipt holds the same items, and the total is Rp0 — even though each table ordered exactly one thing. Guess why, then make `make check` green. A Python scope and mutation lab.","Nota tiap meja isinya sama semua, dan totalnya Rp0 — padahal tiap meja cuma pesan satu barang. Coba tebak kenapa.","2026-10-11T23:00:15.000Z",[155,156,157,70],"python","scope","mutasi","\u002Fog\u002Ftiap-nota-isinya-pesanan-yang-sama.png",{"id":88,"title":69,"title_id":69,"slug":70},[161],{"authors_id":162},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":164,"title":165,"title_id":166,"slug":167,"excerpt":168,"excerpt_id":169,"has_translation":12,"published_at":153,"reading_time":121,"hidden_from_listing":15,"tags":170,"thumbnail_image":21,"og_image":173,"series":174,"authors":175},122,"A Script That Cannot Say Where It Went Wrong","Script yang Nggak Bisa Bilang di Mana Salahnya","script-yang-tidak-bilang-di-mana-salahnya","A script that stops at the first bad line reports only part of the problem. This is what shows up on screen right now.","Script yang berhenti di baris jelek pertama cuma melaporkan sebagian masalah yang ada. Ini yang muncul di layar sekarang.",[155,171,172,70],"error-handling","validasi","\u002Fog\u002Fscript-yang-tidak-bilang-di-mana-salahnya.png",{"id":88,"title":69,"title_id":69,"slug":70},[176],{"authors_id":177},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":74,"title":75,"title_id":76,"slug":77,"excerpt":78,"excerpt_id":79,"has_translation":12,"published_at":80,"reading_time":81,"hidden_from_listing":15,"tags":82,"thumbnail_image":21,"og_image":86,"series":179,"authors":180},{"id":88,"title":69,"title_id":69,"slug":70},[181],{"authors_id":182},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},[],[185],{"authors_id":186},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},"en",[187,189],"id","\nThe support agent answers every ticket correctly. It has a six-thousand-word policy handbook in its prompt, five tool definitions, and the growing transcript of the conversation. Prompt caching is on, which is the part the team checked when the invoices started climbing.\n\nTwenty-four turns across three tickets send 164,854 tokens and cost $0.4841. The same loop with caching switched off costs $0.4017. The feature is not just failing to help; it is charging a premium of 21% for the privilege.\n\nThis is lab 6 of [inva-lab](https:\u002F\u002Fgithub.com\u002Fizzudd\u002Finva-lab), and it runs with `python3` alone: no Docker, no database, no key, no network. The provider is a simulation of one vendor's documented rules, published in November 2026, so the numbers are reproducible and free.\n\n## What you see when you run it\n\n| command | what appears |\n|---|---|\n| `make demo` | `hit=  0.0%  $0.4841` for all three tickets |\n| `make what-changes` | tools `DIFFERENT`, block `[0]` `CHANGED`, breakpoint moved from block `[1]` to `[3]` |\n| `make check` | **0 of 7** checks green |\n| the same loop with `cache_enabled=False` | `$0.4017` |\n\nNothing looks broken. Every ticket is answered, the loop exits 0, and the provider reports no error. The bill is the only symptom, and `make bench` turns it into a per-turn table where `write` equals `sent` on every single row: the whole prompt is written again, every turn, and nothing is ever read.\n\n## Why a prompt that looks static is not\n\nThree things change between two consecutive requests, and each one is defensible in a code review.\n\nThe tool definitions carry a `notes` field with the registry snapshot time. It is there for debugging, it changes every turn, and the provider hashes the tools before it hashes anything else, so the handbook below it is new text every time.\n\nThe system prompt opens with the date and time. Telling the agent what day it is seems obviously useful, and the model does use it; the cache does not.\n\nThe breakpoint sits on the last message. That is the block that changes every turn. The provider's documentation names it as the mistake that writes a fresh entry and never reads one: the lookup walks backward looking for entries earlier requests *wrote*, and nothing was ever written at the end of the handbook.\n\nThere is a fourth, quieter one in the loop: every third turn the transcript is replaced by a one-line summary to keep the context small. It does keep the context small. It also guarantees the prefix never survives, because a rewritten transcript is not a prefix.\n\n## Your mission\n\nMake `make check` green. Seven checks, one theme: the cache follows the bytes.\n\n1. **At least 75% of the tokens you send come back as cache reads,** and the run costs at most 45% of the same loop with caching off.\n2. **The model still gets what it needs.** The date has to reach the model, the tools array has to be byte-identical on every request, and every request has to be the previous one plus new blocks rather than a rewrite.\n3. **The loop survives a ten-minute pause** after turn four, and `python3 agent\u002Floop.py` prints one line with the numbers it actually measured.\n\nThe fixed version in the repository reaches 90.9% and $0.1437, which is 34% of the same requests with caching off. The transcript is 6% *longer* than the broken version, because nothing is summarised away any more. The bill went down while the token count went up, and that is the whole lesson.\n\n## Why the provider is simulated\n\nA lab that calls a real API is a lab that costs money, needs a key, and gives different numbers on your machine. This one has a fake clock, so a five-minute cache timeout and a ten-minute customer pause run in under a second, and the ledger is deterministic. The trade is explicit: `agent\u002Fprovider.py` implements one vendor's rules, one token is one word, and the numbers are not what your account will be charged.\n\nIf you want the rules the other vendors play by, and what happens when the prefix grows from 512 tokens to 1,024 while the cache stays put, that is [the companion explainer](\u002Fp\u002Fwhat-a-prompt-cache-remembers).\n\n## When you are stuck\n\n`HINTS.md` has three levels, and the first one only asks you to look at two consecutive requests side by side. The answer article has the measured progression, including the two fixes that changed nothing and the one line that changed everything.\n","- **Caching is on and the hit rate is 0.0%.** 164,854 tokens sent across twenty-four turns, $0.4841, which is 21% more than the same loop with caching disabled at $0.4017.\n- **Three lines break the prefix, and all three look reasonable in review.** A registry timestamp inside the tool definitions, a clock inside the system prompt, and a breakpoint parked on the block that changes every turn.\n- **The mission is `make check`:** seven checks, none green at the initial state, and the fixed version reaches 90.9% with a bill at 34% of the no-cache run.\n- **The lab runs offline.** Python 3, no API key, no network: the provider is a deterministic simulation of one vendor's published caching rules.","\u003Cp>The support agent answers every ticket correctly. It has a six-thousand-word policy handbook in its prompt, five tool definitions, and the growing transcript of the conversation. Prompt caching is on, which is the part the team checked when the invoices started climbing.\u003C\u002Fp>\n\u003Cp>Twenty-four turns across three tickets send 164,854 tokens and cost $0.4841. The same loop with caching switched off costs $0.4017. The feature is not just failing to help; it is charging a premium of 21% for the privilege.\u003C\u002Fp>\n\u003Cp>This is lab 6 of \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fizzudd\u002Finva-lab\">inva-lab\u003C\u002Fa>, and it runs with \u003Ccode>python3\u003C\u002Fcode> alone: no Docker, no database, no key, no network. The provider is a simulation of one vendor&#39;s documented rules, published in November 2026, so the numbers are reproducible and free.\u003C\u002Fp>\n\u003Ch2 id=\"what-you-see-when-you-run-it\">What you see when you run it\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>command\u003C\u002Fth>\n\u003Cth>what appears\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>\u003Ccode>make demo\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>hit=  0.0%  $0.4841\u003C\u002Fcode> for all three tickets\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>make what-changes\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>tools \u003Ccode>DIFFERENT\u003C\u002Fcode>, block \u003Ccode>[0]\u003C\u002Fcode> \u003Ccode>CHANGED\u003C\u002Fcode>, breakpoint moved from block \u003Ccode>[1]\u003C\u002Fcode> to \u003Ccode>[3]\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>make check\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>0 of 7\u003C\u002Fstrong> checks green\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>the same loop with \u003Ccode>cache_enabled=False\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>$0.4017\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>Nothing looks broken. Every ticket is answered, the loop exits 0, and the provider reports no error. The bill is the only symptom, and \u003Ccode>make bench\u003C\u002Fcode> turns it into a per-turn table where \u003Ccode>write\u003C\u002Fcode> equals \u003Ccode>sent\u003C\u002Fcode> on every single row: the whole prompt is written again, every turn, and nothing is ever read.\u003C\u002Fp>\n\u003Ch2 id=\"why-a-prompt-that-looks-static-is-not\">Why a prompt that looks static is not\u003C\u002Fh2>\n\u003Cp>Three things change between two consecutive requests, and each one is defensible in a code review.\u003C\u002Fp>\n\u003Cp>The tool definitions carry a \u003Ccode>notes\u003C\u002Fcode> field with the registry snapshot time. It is there for debugging, it changes every turn, and the provider hashes the tools before it hashes anything else, so the handbook below it is new text every time.\u003C\u002Fp>\n\u003Cp>The system prompt opens with the date and time. Telling the agent what day it is seems obviously useful, and the model does use it; the cache does not.\u003C\u002Fp>\n\u003Cp>The breakpoint sits on the last message. That is the block that changes every turn. The provider&#39;s documentation names it as the mistake that writes a fresh entry and never reads one: the lookup walks backward looking for entries earlier requests \u003Cem>wrote\u003C\u002Fem>, and nothing was ever written at the end of the handbook.\u003C\u002Fp>\n\u003Cp>There is a fourth, quieter one in the loop: every third turn the transcript is replaced by a one-line summary to keep the context small. It does keep the context small. It also guarantees the prefix never survives, because a rewritten transcript is not a prefix.\u003C\u002Fp>\n\u003Ch2 id=\"your-mission\">Your mission\u003C\u002Fh2>\n\u003Cp>Make \u003Ccode>make check\u003C\u002Fcode> green. Seven checks, one theme: the cache follows the bytes.\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>At least 75% of the tokens you send come back as cache reads,\u003C\u002Fstrong> and the run costs at most 45% of the same loop with caching off.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The model still gets what it needs.\u003C\u002Fstrong> The date has to reach the model, the tools array has to be byte-identical on every request, and every request has to be the previous one plus new blocks rather than a rewrite.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The loop survives a ten-minute pause\u003C\u002Fstrong> after turn four, and \u003Ccode>python3 agent\u002Floop.py\u003C\u002Fcode> prints one line with the numbers it actually measured.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The fixed version in the repository reaches 90.9% and $0.1437, which is 34% of the same requests with caching off. The transcript is 6% \u003Cem>longer\u003C\u002Fem> than the broken version, because nothing is summarised away any more. The bill went down while the token count went up, and that is the whole lesson.\u003C\u002Fp>\n\u003Ch2 id=\"why-the-provider-is-simulated\">Why the provider is simulated\u003C\u002Fh2>\n\u003Cp>A lab that calls a real API is a lab that costs money, needs a key, and gives different numbers on your machine. This one has a fake clock, so a five-minute cache timeout and a ten-minute customer pause run in under a second, and the ledger is deterministic. The trade is explicit: \u003Ccode>agent\u002Fprovider.py\u003C\u002Fcode> implements one vendor&#39;s rules, one token is one word, and the numbers are not what your account will be charged.\u003C\u002Fp>\n\u003Cp>If you want the rules the other vendors play by, and what happens when the prefix grows from 512 tokens to 1,024 while the cache stays put, that is \u003Ca href=\"\u002Fp\u002Fwhat-a-prompt-cache-remembers\">the companion explainer\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"when-you-are-stuck\">When you are stuck\u003C\u002Fh2>\n\u003Cp>\u003Ccode>HINTS.md\u003C\u002Fcode> has three levels, and the first one only asks you to look at two consecutive requests side by side. The answer article has the measured progression, including the two fixes that changed nothing and the one line that changed everything.\u003C\u002Fp>\n","\u003Cul>\n\u003Cli>\u003Cstrong>Caching is on and the hit rate is 0.0%.\u003C\u002Fstrong> 164,854 tokens sent across twenty-four turns, $0.4841, which is 21% more than the same loop with caching disabled at $0.4017.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Three lines break the prefix, and all three look reasonable in review.\u003C\u002Fstrong> A registry timestamp inside the tool definitions, a clock inside the system prompt, and a breakpoint parked on the block that changes every turn.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The mission is \u003Ccode>make check\u003C\u002Fcode>:\u003C\u002Fstrong> seven checks, none green at the initial state, and the fixed version reaches 90.9% with a bill at 34% of the no-cache run.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The lab runs offline.\u003C\u002Fstrong> Python 3, no API key, no network: the provider is a deterministic simulation of one vendor&#39;s published caching rules.\u003C\u002Fli>\n\u003C\u002Ful>\n",[195,217,238,256,261,278],{"id":196,"title":197,"title_id":198,"slug":199,"excerpt":200,"excerpt_id":201,"has_translation":12,"published_at":202,"reading_time":121,"hidden_from_listing":15,"tags":203,"thumbnail_image":21,"og_image":208,"series":209,"authors":214},48,"What a Linked List Actually Is","Tentang Struktur Data LinkedList","tentang-struktur-data-linked-list","A linked list is a linear chain of nodes, each holding data and a pointer to the next node. Here is what that chain looks like, what it costs next to an array, and the same minimal implementation in Java, Python, and JavaScript.","Linked list adalah rantai linear berisi node, dan setiap node menyimpan data plus pointer ke node berikutnya. Ini bentuk rantainya, ongkosnya dibanding array, dan implementasi paling sederhana dalam Java, Python, serta JavaScript.","2026-11-21T01:00:00.000Z",[204,205,206,207],"struktur-data","linked-list","pointer","konsep","\u002Fog\u002Ftentang-struktur-data-linked-list.png",{"id":210,"title":211,"title_id":212,"slug":213},28,"Linear Data Structures","Struktur Data Linear","asd-struktur-linear",[215],{"authors_id":216},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":218,"title":219,"title_id":220,"slug":221,"excerpt":222,"excerpt_id":223,"has_translation":12,"published_at":224,"reading_time":225,"hidden_from_listing":15,"tags":226,"thumbnail_image":21,"og_image":229,"series":230,"authors":235},47,"Why Understanding Algorithms and Data Structures Actually Matters","Pentingnya Memahami Algoritma dan Struktur Data","pentingnya-memahami-algoritma-dan-struktur-data","An algorithm is an ordered list of steps, and that order decides how expensive a problem is. The examples are on the back of an instant noodle packet, in a factorial, and behind ctrl+z.","Sebagai konsep fundamental, algoritma menentukan seberapa mahal sebuah masalah diselesaikan. Contohnya ada di bungkus mie instan, di bilangan faktorial, dan di tombol undo.","2026-11-19T01:00:00.000Z",7,[227,204,207,228],"algoritma","dasar","\u002Fog\u002Fpentingnya-memahami-algoritma-dan-struktur-data.png",{"id":231,"title":232,"title_id":233,"slug":234},27,"About Algorithms and Data Structures","Tentang Algoritma dan Struktur Data","asd-intro",[236],{"authors_id":237},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":239,"title":240,"title_id":241,"slug":242,"excerpt":243,"excerpt_id":244,"has_translation":12,"published_at":245,"reading_time":14,"hidden_from_listing":15,"tags":246,"thumbnail_image":21,"og_image":251,"series":252,"authors":253},108,"At 11 a.m. the AI Quota Runs Out, and the Work Stops There","Jam 11 siang kuota AI-nya habis, dan kerjaan berhenti di situ","jam-11-kuota-ai-habis-kerjaan-berhenti","The panel says the usage limit is reached and the work stops, not because it is finished. Three guesses explain it, and all three are wrong: the limit is shaped like a cliff, and the day is built on top of one tool.","Panel di layar bilang batas pemakaian tercapai, dan kerja berhenti di situ. Bukan karena selesai. Ada tiga tebakan kenapa ini terjadi, dan ketiganya salah: batasnya berbentuk tebing, dan harinya dibangun di atas satu alat.","2026-11-12T01:00:00.000Z",[247,248,249,250],"ai","tooling","rate-limit","produktivitas","\u002Fog\u002Fjam-11-kuota-ai-habis-kerjaan-berhenti.png",{"id":24,"title":25,"title_id":26,"slug":27},[254],{"authors_id":255},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":74,"title":75,"title_id":76,"slug":77,"excerpt":78,"excerpt_id":79,"has_translation":12,"published_at":80,"reading_time":81,"hidden_from_listing":15,"tags":82,"thumbnail_image":21,"og_image":86,"series":257,"authors":258},{"id":88,"title":69,"title_id":69,"slug":70},[259],{"authors_id":260},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":262,"title":263,"title_id":264,"slug":265,"excerpt":266,"excerpt_id":267,"has_translation":12,"published_at":268,"reading_time":269,"hidden_from_listing":15,"tags":270,"thumbnail_image":21,"og_image":272,"series":273,"authors":275},140,"What a Prompt Cache Actually Remembers","Apa yang Sebenarnya Diingat Prompt Cache","what-a-prompt-cache-remembers","Four providers cache the same bytes under four different rulebooks. The question that decides your bill: when the second request is longer than the first, does it reuse the whole prefix or only the part that was already written?","Empat provider meng-cache byte yang sama dengan empat buku aturan berbeda. Pertanyaan yang menentukan tagihanmu: saat permintaan kedua lebih panjang, apakah seluruh prefix dipakai ulang atau cuma bagian yang sudah pernah ditulis?","2026-11-08T01:10:00.000Z",6,[83,271,84,85],"ai-agent","\u002Fog\u002Fwhat-a-prompt-cache-remembers.png",{"id":274,"title":35,"title_id":36,"slug":37},8,[276],{"authors_id":277},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},{"id":279,"title":280,"title_id":281,"slug":282,"excerpt":283,"excerpt_id":284,"has_translation":12,"published_at":285,"reading_time":14,"hidden_from_listing":15,"tags":286,"thumbnail_image":21,"og_image":289,"series":290,"authors":295},138,"Python venv: the Install That Went Into the Wrong Python","venv Python: Instalasi yang Masuk ke Python yang Salah","python-venv-pip","`pip install` printed Successfully installed, and the next run raised ModuleNotFoundError on the same machine. Two interpreters, one install, and the variable your script checks is the one the interpreter never sets.","`pip install` mencetak Successfully installed, lalu jalan berikutnya melempar ModuleNotFoundError di mesin yang sama. Dua interpreter, satu instalasi, dan variabel yang skripmu periksa justru tidak pernah dipasang oleh interpreter.","2026-11-07T12:00:00.000Z",[155,287,288],"venv","pip","\u002Fog\u002Fpython-venv-pip.png",{"id":291,"title":292,"title_id":293,"slug":294},18,"Working with Python Scripts","Menggunakan Script Python","python-pemrograman-dengan-script",[296],{"authors_id":297},{"id":109,"name":110,"slug":111,"role":112,"profile_picture":21},[299,303,306,309,312],{"text":300,"depth":301,"id":302},"What you see when you run it",2,"what-you-see-when-you-run-it",{"text":304,"depth":301,"id":305},"Why a prompt that looks static is not","why-a-prompt-that-looks-static-is-not",{"text":307,"depth":301,"id":308},"Your mission","your-mission",{"text":310,"depth":301,"id":311},"Why the provider is simulated","why-the-provider-is-simulated",{"text":313,"depth":301,"id":314},"When you are stuck","when-you-are-stuck",1794150713313]