<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rangga Aprilio Utama</title>
    <description>The latest articles on DEV Community by Rangga Aprilio Utama (@ranggaaprilio).</description>
    <link>https://dev.to/ranggaaprilio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F559554%2F63b8cca4-9511-44ec-90a6-12db9c166988.jpeg</url>
      <title>DEV Community: Rangga Aprilio Utama</title>
      <link>https://dev.to/ranggaaprilio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ranggaaprilio"/>
    <language>en</language>
    <item>
      <title>Software Factory : Plan, Build, dan Evaluate dengan AI dalam ADLC</title>
      <dc:creator>Rangga Aprilio Utama</dc:creator>
      <pubDate>Sun, 11 Oct 2026 02:11:17 +0000</pubDate>
      <link>https://dev.to/ranggaaprilio/software-factory-anda-hanya-sebaik-gerbangnya-plan-build-dan-evaluate-dengan-ai-dalam-adlc-33il</link>
      <guid>https://dev.to/ranggaaprilio/software-factory-anda-hanya-sebaik-gerbangnya-plan-build-dan-evaluate-dengan-ai-dalam-adlc-33il</guid>
      <description>&lt;p&gt;AI sekarang bisa membantu kita menulis kode jauh lebih cepat. Tapi ada satu pertanyaan yang sering terlupakan:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Apakah kita benar-benar menjadi lebih cepat, atau hanya menghasilkan lebih banyak kode?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Beberapa penelitian menunjukkan bahwa jawabannya tidak sesederhana “AI = lebih produktif”. Dalam satu studi METR, developer berpengalaman yang menggunakan AI justru membutuhkan waktu sekitar 19% lebih lama, meskipun mereka merasa pekerjaan mereka menjadi lebih cepat.&lt;/p&gt;

&lt;p&gt;Di sisi lain, laporan lain menunjukkan bahwa penggunaan AI yang lebih tinggi bisa meningkatkan jumlah task yang selesai, tetapi juga diikuti peningkatan bug dan incident.&lt;/p&gt;

&lt;p&gt;Jadi masalahnya bukan sekadar bagaimana membuat AI menulis kode lebih cepat.&lt;/p&gt;

&lt;p&gt;Masalah sebenarnya adalah:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bagaimana kita membuat sistem yang memastikan AI mengerjakan hal yang benar, dengan cara yang benar, dan hasilnya benar-benar bisa dipercaya?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Di sinilah konsep &lt;strong&gt;Software Factory&lt;/strong&gt; menjadi menarik.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Apa Itu Software Factory?
&lt;/h2&gt;

&lt;p&gt;Bayangkan kita memiliki sebuah pabrik.&lt;/p&gt;

&lt;p&gt;Sebuah pabrik yang baik tidak hanya punya mesin yang cepat. Ia juga punya:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bahan baku yang jelas,&lt;/li&gt;
&lt;li&gt;proses kerja yang teratur,&lt;/li&gt;
&lt;li&gt;aturan keselamatan,&lt;/li&gt;
&lt;li&gt;quality control,&lt;/li&gt;
&lt;li&gt;dan pemeriksaan sebelum produk dikirim.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Konsep yang sama bisa diterapkan pada software development dengan AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software Factory&lt;/strong&gt; adalah sistem yang menggabungkan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI agents,&lt;/li&gt;
&lt;li&gt;engineering tools,&lt;/li&gt;
&lt;li&gt;knowledge dan context,&lt;/li&gt;
&lt;li&gt;workflow otomatis,&lt;/li&gt;
&lt;li&gt;automated verification,&lt;/li&gt;
&lt;li&gt;dan human review.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tujuannya adalah membawa sebuah pekerjaan dari:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business Request
      ↓
     Plan
      ↓
     Build
      ↓
   Evaluate
      ↓
   Release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yang menarik, peran developer juga berubah.&lt;/p&gt;

&lt;p&gt;Kita mungkin menulis lebih sedikit kode secara manual, tetapi justru harus lebih banyak memikirkan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requirement,&lt;/li&gt;
&lt;li&gt;acceptance criteria,&lt;/li&gt;
&lt;li&gt;architecture,&lt;/li&gt;
&lt;li&gt;context untuk AI,&lt;/li&gt;
&lt;li&gt;permission,&lt;/li&gt;
&lt;li&gt;testing,&lt;/li&gt;
&lt;li&gt;evaluation,&lt;/li&gt;
&lt;li&gt;dan edge cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jadi bukan berarti manusia tidak dibutuhkan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manusia berpindah dari “penulis kode utama” menjadi orang yang mendesain dan mengontrol sistem produksinya.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Di Mana Posisi ADLC?
&lt;/h2&gt;

&lt;p&gt;AWS memperkenalkan konsep &lt;strong&gt;AI-Driven Development Life Cycle (AI-DLC)&lt;/strong&gt; yang menempatkan AI di tengah proses development, sementara manusia tetap memegang keputusan penting.&lt;/p&gt;

&lt;p&gt;Secara sederhana, ada tiga fase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────┐
│   Inception  │
│     PLAN     │
└──────┬───────┘
       ↓
┌──────────────┐
│ Construction │
│     BUILD    │
└──────┬───────┘
       ↓
┌──────────────┐
│  Operations  │
│   EVALUATE   │
└──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inception / Plan
&lt;/h3&gt;

&lt;p&gt;AI membantu:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;memahami kebutuhan,&lt;/li&gt;
&lt;li&gt;mengajukan pertanyaan,&lt;/li&gt;
&lt;li&gt;membuat requirement,&lt;/li&gt;
&lt;li&gt;membuat unit kerja.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Manusia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;menjawab pertanyaan,&lt;/li&gt;
&lt;li&gt;memvalidasi requirement,&lt;/li&gt;
&lt;li&gt;menentukan keputusan bisnis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Construction / Build
&lt;/h3&gt;

&lt;p&gt;AI membantu:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;membuat architecture proposal,&lt;/li&gt;
&lt;li&gt;membuat domain model,&lt;/li&gt;
&lt;li&gt;menulis kode,&lt;/li&gt;
&lt;li&gt;membuat test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Manusia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;memvalidasi keputusan teknis,&lt;/li&gt;
&lt;li&gt;melakukan review,&lt;/li&gt;
&lt;li&gt;menentukan apakah hasil boleh masuk ke branch utama.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operations / Evaluate
&lt;/h3&gt;

&lt;p&gt;AI membantu:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deployment,&lt;/li&gt;
&lt;li&gt;infrastructure,&lt;/li&gt;
&lt;li&gt;monitoring,&lt;/li&gt;
&lt;li&gt;analisis hasil.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Manusia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mengawasi production,&lt;/li&gt;
&lt;li&gt;mengevaluasi hasil,&lt;/li&gt;
&lt;li&gt;mengambil keputusan jika terjadi masalah.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kalau disederhanakan:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ADLC adalah blueprint prosesnya. Software Factory adalah mesin dan quality control yang menjalankan blueprint tersebut.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Kenapa “Gerbang” Sangat Penting?
&lt;/h2&gt;

&lt;p&gt;Bayangkan AI bisa menghasilkan 10 PR dalam sehari.&lt;/p&gt;

&lt;p&gt;Kedengarannya luar biasa.&lt;/p&gt;

&lt;p&gt;Tapi kalau tidak ada pemeriksaan yang baik, kita juga bisa mendapatkan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10 PR
 ↓
10x kode
 ↓
10x sesuatu yang harus direview
 ↓
lebih banyak bug
 ↓
lebih banyak incident
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jadi semakin cepat AI bekerja, semakin penting sistem quality control kita.&lt;/p&gt;

&lt;p&gt;Ada tiga hal penting yang bisa kita pelajari dari berbagai penelitian.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 AI sangat bagus untuk task yang jelas
&lt;/h3&gt;

&lt;p&gt;AI cenderung bekerja lebih baik ketika task:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kecil,&lt;/li&gt;
&lt;li&gt;spesifik,&lt;/li&gt;
&lt;li&gt;punya requirement yang jelas,&lt;/li&gt;
&lt;li&gt;dan punya acceptance criteria yang bisa diperiksa.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Artinya, jangan memberikan AI task seperti:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Buatkan authentication system.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lebih baik:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Tambahkan rate limiting pada endpoint &lt;code&gt;/login&lt;/code&gt;. Batasi 10 percobaan gagal per IP dalam 15 menit. Setelah melewati batas, return HTTP 429 dengan &lt;code&gt;Retry-After&lt;/code&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Task kedua jauh lebih mudah untuk diverifikasi.&lt;/p&gt;

&lt;p&gt;Jadi:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI cepat ketika input-nya jelas.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inilah alasan gerbang &lt;strong&gt;Plan&lt;/strong&gt; penting.&lt;/p&gt;




&lt;h3&gt;
  
  
  3.2 Kita tidak selalu bisa merasakan apakah AI benar-benar membantu
&lt;/h3&gt;

&lt;p&gt;Ini bagian yang cukup menarik.&lt;/p&gt;

&lt;p&gt;Dalam studi METR, developer berpengalaman merasa mereka bekerja lebih cepat dengan AI. Tetapi ketika waktu sebenarnya diukur, mereka justru membutuhkan waktu lebih lama.&lt;/p&gt;

&lt;p&gt;Artinya:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Perasaan kita tentang produktivitas tidak selalu akurat.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Karena itu kita membutuhkan tahap &lt;strong&gt;Evaluate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Jangan hanya bertanya:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Apakah developer merasa lebih produktif?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tapi ukur:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lead time,&lt;/li&gt;
&lt;li&gt;deployment frequency,&lt;/li&gt;
&lt;li&gt;change failure rate,&lt;/li&gt;
&lt;li&gt;recovery time,&lt;/li&gt;
&lt;li&gt;bug,&lt;/li&gt;
&lt;li&gt;incident,&lt;/li&gt;
&lt;li&gt;dan kualitas software.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3.3 AI memperkuat proses yang sudah kita punya
&lt;/h3&gt;

&lt;p&gt;AI adalah amplifier.&lt;/p&gt;

&lt;p&gt;Kalau proses kita bagus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Good Process
     +
     AI
     ↓
Better / Faster Process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tapi kalau proses kita buruk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad Process
     +
     AI
     ↓
Bad Process, but Faster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Misalnya proses review kita sudah buruk.&lt;/p&gt;

&lt;p&gt;Sebelum AI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5 PR / hari
↓
review asal-asalan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setelah menggunakan AI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;30 PR / hari
↓
review tetap asal-asalan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kita bukan menyelesaikan masalah.&lt;/p&gt;

&lt;p&gt;Kita hanya memperbesar masalah.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Gerbang Pertama: PLAN
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tujuan
&lt;/h3&gt;

&lt;p&gt;Sebelum AI menulis kode, kita harus memastikan AI memahami &lt;strong&gt;apa yang sebenarnya harus dibuat&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Output dari tahap Plan sebaiknya bukan dokumen 50 halaman.&lt;/p&gt;

&lt;p&gt;Justru sebaliknya:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Buat plan yang singkat, jelas, dan bisa divalidasi manusia.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  4.1 Biarkan AI Bertanya
&lt;/h3&gt;

&lt;p&gt;Daripada langsung berkata:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Implementasikan fitur X.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Berikan business intent terlebih dahulu.&lt;/p&gt;

&lt;p&gt;Misalnya:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Kami ingin membatasi brute-force attack pada login.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kemudian minta AI mencari hal-hal yang masih belum jelas.&lt;/p&gt;

&lt;p&gt;Contohnya:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Berapa maksimal percobaan?

Dalam berapa menit?

Rate limit berdasarkan apa?

- IP?
- User?
- Device?

Apa response ketika diblokir?

Apakah admin tool ikut terkena?

Bagaimana behavior setelah login berhasil?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pertanyaan-pertanyaan tersebut kemudian dijawab oleh manusia.&lt;/p&gt;

&lt;p&gt;Jawaban itu menjadi bagian dari context.&lt;/p&gt;




&lt;h3&gt;
  
  
  4.2 Pecah Pekerjaan Menjadi Unit Kecil
&lt;/h3&gt;

&lt;p&gt;Jangan membuat satu task yang terlalu besar.&lt;/p&gt;

&lt;p&gt;Lebih baik:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 Unit of Work
      ↓
1 Branch
      ↓
1 PR
      ↓
1 Review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kenapa?&lt;/p&gt;

&lt;p&gt;Karena semakin kecil unit kerja:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;semakin mudah direview,&lt;/li&gt;
&lt;li&gt;semakin mudah dites,&lt;/li&gt;
&lt;li&gt;semakin murah rollback,&lt;/li&gt;
&lt;li&gt;semakin mudah mencari sumber masalah.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rule sederhana:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Kalau seseorang tidak bisa memahami dan mereview task dalam satu sesi, kemungkinan task tersebut terlalu besar.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  4.3 Buat Acceptance Criteria Sebelum Coding
&lt;/h3&gt;

&lt;p&gt;Jangan menggunakan:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Fitur harus berjalan dengan baik.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Itu terlalu subjektif.&lt;/p&gt;

&lt;p&gt;Buat sesuatu yang bisa dicek.&lt;/p&gt;

&lt;p&gt;Contoh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given:
IP tertentu melakukan login gagal

When:
Percobaan gagal mencapai percobaan ke-11
dalam waktu 15 menit

Then:
API harus mengembalikan HTTP 429
dan header Retry-After
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dengan begitu AI tahu apa yang harus dibuat.&lt;/p&gt;

&lt;p&gt;Dan reviewer tahu apa yang harus diperiksa.&lt;/p&gt;




&lt;h3&gt;
  
  
  4.4 Tentukan Permission dari Awal
&lt;/h3&gt;

&lt;p&gt;AI agent seharusnya tidak memiliki akses ke semua hal.&lt;/p&gt;

&lt;p&gt;Misalnya untuk task authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALLOW
├── auth middleware
└── authentication tests

DENY
├── production config
├── database migration
└── session store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prinsipnya sederhana:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Agent hanya mendapatkan permission yang benar-benar dibutuhkan untuk task tersebut.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  4.5 Simpan Context di Repository
&lt;/h3&gt;

&lt;p&gt;Jangan mengandalkan AI untuk “ingat” semua aturan.&lt;/p&gt;

&lt;p&gt;Simpan informasi penting di repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repository/
├── docs/
│   ├── architecture.md
│   └── specifications/
│
├── AGENTS.md
├── CONTRIBUTING.md
└── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isi context bisa berupa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;coding conventions,&lt;/li&gt;
&lt;li&gt;architecture rules,&lt;/li&gt;
&lt;li&gt;business rules,&lt;/li&gt;
&lt;li&gt;testing strategy,&lt;/li&gt;
&lt;li&gt;API conventions,&lt;/li&gt;
&lt;li&gt;security rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dengan begitu AI tidak mulai dari nol setiap kali mengerjakan task.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Gerbang Kedua: BUILD
&lt;/h2&gt;

&lt;p&gt;Setelah plan disetujui, baru AI masuk ke tahap implementasi.&lt;/p&gt;

&lt;p&gt;Tujuannya bukan:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Biarkan AI coding sebebas mungkin.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Justru sebaliknya:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Berikan AI ruang kerja yang kecil dan terkontrol.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  5.1 Gunakan Bolt yang Kecil
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Istilah Bolt di definisikan sebagai unit pekerjaan kecil yang memiliki scope jelas dan bisa diselesaikan secara independen.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Idealnya:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 Unit of Work
       ↓
1 Branch
       ↓
1 PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jangan biarkan satu agent mengubah 50 bagian sistem sekaligus.&lt;/p&gt;

&lt;p&gt;Semakin kecil perubahan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;semakin mudah direview,&lt;/li&gt;
&lt;li&gt;semakin mudah di-debug,&lt;/li&gt;
&lt;li&gt;semakin mudah di-rollback.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5.2 Test Harus Berasal dari Acceptance Criteria
&lt;/h3&gt;

&lt;p&gt;Salah satu pendekatan yang menarik adalah:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Acceptance Criteria
       ↓
     Tests
       ↓
Implementation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bukan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt
  ↓
AI writes code
  ↓
AI writes tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kenapa?&lt;/p&gt;

&lt;p&gt;Kalau kode dan test dibuat oleh AI dari konteks yang sama tanpa pemeriksaan independen, ada risiko test hanya “membenarkan” implementasi yang salah.&lt;/p&gt;

&lt;p&gt;Test seharusnya menjadi representasi dari requirement.&lt;/p&gt;




&lt;h3&gt;
  
  
  5.3 Automated Gate Harus Jalan Sebelum Human Review
&lt;/h3&gt;

&lt;p&gt;Sebelum reviewer membaca kode, jalankan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PR
 ↓
Lint
 ↓
Type Check
 ↓
Unit Test
 ↓
Integration Test
 ↓
Security Scan
 ↓
Human Review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kalau salah satu gagal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ STOP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jangan buang waktu reviewer untuk PR yang bahkan belum lolos pemeriksaan dasar.&lt;/p&gt;




&lt;h3&gt;
  
  
  5.4 Review Diff, Bukan Perasaan
&lt;/h3&gt;

&lt;p&gt;AI bisa menghasilkan kode yang terlihat sangat bagus.&lt;/p&gt;

&lt;p&gt;Tetapi:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Kode yang terlihat bagus belum tentu melakukan hal yang benar.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Automated test membantu menjawab:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Apakah kode ini bekerja?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Human review menjawab:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Apakah kode ini melakukan hal yang benar dan sesuai architecture kita?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keduanya berbeda.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Gerbang Ketiga: EVALUATE
&lt;/h2&gt;

&lt;p&gt;Ini adalah bagian yang sering dilewati.&lt;/p&gt;

&lt;p&gt;Setelah kode di-merge dan di-deploy, kita harus melihat hasil sebenarnya.&lt;/p&gt;

&lt;p&gt;Bukan berdasarkan feeling.&lt;/p&gt;

&lt;p&gt;Tapi berdasarkan data.&lt;/p&gt;




&lt;h3&gt;
  
  
  6.1 Ukur Delivery, Bukan Aktivitas AI
&lt;/h3&gt;

&lt;p&gt;Jangan hanya mengukur:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Berapa banyak kode yang dibuat AI?
Berapa banyak suggestion AI yang diterima?
Berapa banyak PR yang dibuat?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Angka tersebut hanya menunjukkan aktivitas.&lt;/p&gt;

&lt;p&gt;Lebih berguna mengukur:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lead Time
Deployment Frequency
Change Failure Rate
Recovery Time
Bug
Incident
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  6.2 Kecepatan Harus Dilihat Bersama Kualitas
&lt;/h3&gt;

&lt;p&gt;Misalnya:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before AI

10 deployment
2 bugs
1 incident
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setelah AI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20 deployment
8 bugs
5 incidents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apakah kita menjadi lebih produktif?&lt;/p&gt;

&lt;p&gt;Belum tentu.&lt;/p&gt;

&lt;p&gt;Kita memang mengirim lebih banyak perubahan.&lt;/p&gt;

&lt;p&gt;Tapi kualitasnya memburuk.&lt;/p&gt;

&lt;p&gt;Karena itu:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Throughput tanpa quality bukan kemenangan.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  6.3 Buat Baseline
&lt;/h3&gt;

&lt;p&gt;Sebelum menerapkan AI secara besar-besaran, ukur kondisi sekarang.&lt;/p&gt;

&lt;p&gt;Contoh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lead Time          : 3 hari
Deployment/Week    : 10
Change Failure     : 8%
Critical Bugs      : 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setelah menggunakan AI, bandingkan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lead Time          : 1.5 hari
Deployment/Week    : 18
Change Failure     : 9%
Critical Bugs      : 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sekarang kita punya data untuk menilai dampaknya.&lt;/p&gt;

&lt;p&gt;Tanpa baseline, kita hanya menebak.&lt;/p&gt;




&lt;h3&gt;
  
  
  6.4 Evaluasi Agent-nya Juga
&lt;/h3&gt;

&lt;p&gt;Agent adalah bagian dari sistem.&lt;/p&gt;

&lt;p&gt;Jadi agent juga harus dievaluasi.&lt;/p&gt;

&lt;p&gt;Buat kumpulan task yang representatif:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Evaluation Dataset
├── Authentication
├── CRUD
├── Database query
├── API integration
├── Refactoring
└── Bug fixing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kemudian jalankan kembali ketika kita mengubah:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;model,&lt;/li&gt;
&lt;li&gt;prompt,&lt;/li&gt;
&lt;li&gt;agent rules,&lt;/li&gt;
&lt;li&gt;tools,&lt;/li&gt;
&lt;li&gt;context,&lt;/li&gt;
&lt;li&gt;workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dengan begitu kita tahu apakah perubahan tersebut benar-benar membuat agent lebih baik.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Satu Contoh dari Awal Sampai Akhir
&lt;/h2&gt;

&lt;p&gt;Misalnya product team meminta:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Tambahkan rate limiting untuk login.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  PLAN
&lt;/h3&gt;

&lt;p&gt;AI bertanya:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Berapa maksimal percobaan?

Berapa lama window-nya?

Rate limit berdasarkan IP atau account?

Apa response ketika diblokir?

Bagaimana dengan admin tools?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tim menjawab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10 failed attempts
per IP
dalam 15 menit

Response:
HTTP 429
Retry-After header

Admin tools harus tetap bekerja.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acceptance criteria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Percobaan gagal ke-11 → HTTP 429
2. Response memiliki Retry-After
3. Login berhasil → counter reset
4. Existing admin integration test tetap pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permission:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent boleh:
- auth middleware
- authentication tests

Agent tidak boleh:
- production config
- database migration
- session store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  BUILD
&lt;/h3&gt;

&lt;p&gt;Agent membuat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Branch
 ↓
Tests
 ↓
Implementation
 ↓
Lint
 ↓
Type Check
 ↓
Integration Test
 ↓
Security Scan
 ↓
PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reviewer menemukan:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Counter disimpan di memory aplikasi.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Masalahnya:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Instance A → counter = 5
Instance B → counter = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kalau aplikasi berjalan di beberapa instance, rate limit tidak konsisten.&lt;/p&gt;

&lt;p&gt;Maka plan diperbaiki:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Memory
  ↓
Redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agent melakukan perubahan.&lt;/p&gt;

&lt;p&gt;PR kemudian di-merge.&lt;/p&gt;




&lt;h3&gt;
  
  
  EVALUATE
&lt;/h3&gt;

&lt;p&gt;Dua hari kemudian ada laporan:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“User kantor terkena rate limit karena banyak orang menggunakan IP yang sama.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ternyata requirement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate limit berdasarkan IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tidak mempertimbangkan shared network.&lt;/p&gt;

&lt;p&gt;Masalahnya bukan hanya di kode.&lt;/p&gt;

&lt;p&gt;Masalahnya ada di &lt;strong&gt;Plan&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Maka kita memperbaiki sistem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Auth Context

Rule baru:
"Pertimbangkan shared IP/network."

+

Clarification question baru:
"Apakah user dapat berbagi IP?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sekarang failure tersebut menjadi pengetahuan untuk pekerjaan berikutnya.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inilah inti Software Factory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kegagalan tidak hanya diperbaiki di kode.&lt;/p&gt;

&lt;p&gt;Kegagalan digunakan untuk memperbaiki &lt;strong&gt;pabriknya&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Jadi Apa Sebenarnya Peran Manusia?
&lt;/h2&gt;

&lt;p&gt;Dengan semua otomatisasi ini, apakah developer akan hilang?&lt;/p&gt;

&lt;p&gt;Menurut saya, bukan itu yang terjadi.&lt;/p&gt;

&lt;p&gt;Peran developer justru bergeser.&lt;/p&gt;

&lt;p&gt;Dari:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write Code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;menjadi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Define Problem
       ↓
Define Constraints
       ↓
Define Acceptance Criteria
       ↓
Design System
       ↓
Control Agents
       ↓
Evaluate Result
       ↓
Improve Process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kita mungkin menulis lebih sedikit kode.&lt;/p&gt;

&lt;p&gt;Tetapi kita harus lebih baik dalam:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;system design,&lt;/li&gt;
&lt;li&gt;requirement analysis,&lt;/li&gt;
&lt;li&gt;architecture,&lt;/li&gt;
&lt;li&gt;testing,&lt;/li&gt;
&lt;li&gt;security,&lt;/li&gt;
&lt;li&gt;observability,&lt;/li&gt;
&lt;li&gt;dan decision making.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. Checklist Sederhana
&lt;/h2&gt;

&lt;h2&gt;
  
  
  PLAN
&lt;/h2&gt;

&lt;p&gt;Sebelum lanjut, pastikan ada:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Business intent yang jelas&lt;/li&gt;
&lt;li&gt;[ ] Pertanyaan klarifikasi sudah dijawab&lt;/li&gt;
&lt;li&gt;[ ] Unit kerja cukup kecil&lt;/li&gt;
&lt;li&gt;[ ] Acceptance criteria bisa diverifikasi&lt;/li&gt;
&lt;li&gt;[ ] Permission agent sudah ditentukan&lt;/li&gt;
&lt;li&gt;[ ] Area yang tidak boleh disentuh sudah jelas&lt;/li&gt;
&lt;li&gt;[ ] Context tersedia di repository&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  BUILD
&lt;/h2&gt;

&lt;p&gt;Pastikan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Satu unit kerja → satu branch&lt;/li&gt;
&lt;li&gt;[ ] Test berasal dari acceptance criteria&lt;/li&gt;
&lt;li&gt;[ ] Lint berhasil&lt;/li&gt;
&lt;li&gt;[ ] Type check berhasil&lt;/li&gt;
&lt;li&gt;[ ] Test berhasil&lt;/li&gt;
&lt;li&gt;[ ] Security scan berhasil&lt;/li&gt;
&lt;li&gt;[ ] Human review dilakukan&lt;/li&gt;
&lt;li&gt;[ ] Diff tetap kecil dan mudah dipahami&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  EVALUATE
&lt;/h2&gt;

&lt;p&gt;Pastikan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Sudah memiliki baseline&lt;/li&gt;
&lt;li&gt;[ ] Lead time diukur&lt;/li&gt;
&lt;li&gt;[ ] Deployment frequency diukur&lt;/li&gt;
&lt;li&gt;[ ] Change failure rate diukur&lt;/li&gt;
&lt;li&gt;[ ] Incident dan bug diukur&lt;/li&gt;
&lt;li&gt;[ ] Agent memiliki evaluation set&lt;/li&gt;
&lt;li&gt;[ ] Feedback dari incident masuk kembali ke workflow&lt;/li&gt;
&lt;li&gt;[ ] Ada audit trail&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Kesimpulan
&lt;/h2&gt;

&lt;p&gt;AI membuat kita bisa menghasilkan software lebih cepat.&lt;/p&gt;

&lt;p&gt;Tetapi:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Menghasilkan kode lebih cepat tidak sama dengan menghasilkan software yang lebih baik.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kalau kita memasukkan AI ke dalam proses development yang buruk, kita hanya mendapatkan proses buruk yang berjalan lebih cepat.&lt;/p&gt;

&lt;p&gt;Karena itu, kita membutuhkan &lt;strong&gt;gerbang&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 SOFTWARE FACTORY

Business Intent
      │
      ▼
┌──────────────┐
│     PLAN     │
│              │
│ Apa yang     │
│ sebenarnya   │
│ harus dibuat?│
└──────┬───────┘
       │
       ▼
┌──────────────┐
│    BUILD     │
│              │
│ Apakah kita  │
│ membuatnya    │
│ dengan benar?│
└──────┬───────┘
       │
       ▼
┌──────────────┐
│   EVALUATE   │
│              │
│ Apakah hasil │
│ akhirnya     │
│ benar-benar  │
│ lebih baik?  │
└──────┬───────┘
       │
       └──────────────┐
                      │
                      ▼
                Improve Factory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Plan memastikan kita mengerjakan hal yang benar.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build memastikan kita mengerjakannya dengan benar.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluate memastikan hasilnya benar-benar memberikan nilai.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dan yang paling penting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ketika terjadi kegagalan, jangan hanya memperbaiki kodenya. Perbaiki juga gerbang yang seharusnya menangkap kegagalan tersebut.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Itulah yang membuat Software Factory menjadi sistem yang terus belajar.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referensi
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Peng, S., Kalliamvakou, E., Cihon, P., Demirer, M. (2023). &lt;em&gt;The Impact of AI on Developer Productivity: Evidence from GitHub Copilot.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;METR (2025). &lt;em&gt;Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;DORA (2025). &lt;em&gt;State of AI-assisted Software Development.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;DORA (2025). &lt;em&gt;AI Capabilities Model.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;AWS DevOps &amp;amp; Developer Productivity Blog (2025). &lt;em&gt;AI-Driven Development Life Cycle.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;AWS Labs. &lt;em&gt;aidlc-workflows.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Faros AI. &lt;em&gt;What is a Software Factory?&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>SSO Is More Than "Log In Once"</title>
      <dc:creator>Rangga Aprilio Utama</dc:creator>
      <pubDate>Sun, 07 Jun 2026 01:26:27 +0000</pubDate>
      <link>https://dev.to/ranggaaprilio/sso-is-more-than-log-in-once-42gc</link>
      <guid>https://dev.to/ranggaaprilio/sso-is-more-than-log-in-once-42gc</guid>
      <description>&lt;p&gt;&lt;em&gt;A practical look at identity, sessions, OAuth 2.0, OpenID Connect, and tenant isolation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Single Sign-On is often summarized as "log in once and access many applications." That is correct, but incomplete. A real SSO system must also answer several security questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which application is requesting access?&lt;/li&gt;
&lt;li&gt;Which organization owns that application?&lt;/li&gt;
&lt;li&gt;Is the user allowed to use it?&lt;/li&gt;
&lt;li&gt;What information did the user approve sharing?&lt;/li&gt;
&lt;li&gt;How can the application trust the tokens it receives?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Three Actors
&lt;/h2&gt;

&lt;p&gt;An SSO flow has three main actors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The end user&lt;/strong&gt; who wants to sign in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The client application&lt;/strong&gt; that needs the user's identity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The identity provider&lt;/strong&gt;, which authenticates the user and issues tokens.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The client application never receives the user's password. Instead, it redirects the browser to the identity provider. The provider handles authentication and sends the application a short-lived authorization code.&lt;/p&gt;

&lt;p&gt;This separation is fundamental: applications delegate authentication to one trusted identity provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Sign-In Flow Works
&lt;/h2&gt;

&lt;p&gt;A secure implementation can use the OAuth 2.0 Authorization Code Flow with OpenID Connect and PKCE.&lt;/p&gt;

&lt;p&gt;The sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A client redirects the browser to the identity provider with its &lt;code&gt;client_id&lt;/code&gt;, callback URL, requested scopes, &lt;code&gt;state&lt;/code&gt;, and an S256 PKCE challenge.&lt;/li&gt;
&lt;li&gt;The provider validates the client and callback URL before showing any login page.&lt;/li&gt;
&lt;li&gt;It resolves the tenant from the registered client, so tenant context does not come from untrusted user input.&lt;/li&gt;
&lt;li&gt;The provider stores the validated request as a short-lived authorization transaction. The frontend receives only an opaque transaction ID.&lt;/li&gt;
&lt;li&gt;The user signs in. The provider verifies the tenant-scoped account, password, account status, and role for that client.&lt;/li&gt;
&lt;li&gt;The user approves or denies the requested access on a consent screen.&lt;/li&gt;
&lt;li&gt;On approval, the provider returns a short-lived, single-use authorization code to the registered callback.&lt;/li&gt;
&lt;li&gt;The client exchanges the code and its PKCE verifier for an ID token, access token, and refresh token.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The ID token tells the client who authenticated. The access token authorizes API access. The refresh token allows the client to obtain a new short-lived access token without asking the user to sign in again.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSO Flow Diagram
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://mermaid.live/edit#pako:eNqFVW1v2jAQ_iuWP4eOtBRKNFWqoJpYpQ0VdZMmpMkkR7BI7MwvrLTqf9_ZTiC8aXyAGN89d8_5eZx3msoMaEI1_LEgUhhzlitWzgXBD7NGClsuQNXr1EhFXnSzrpgyPOUVE4Y8VBVhmowKDmFV8JQZLsVp6CSbutBJhpHcbMlUyQ3PzoHOQGuEcNHN4wxbgDPlpxMXhVAGUgOZ-2Ne13YNd-7vsacEYQrcJ3M647kgXJC_3KzIbPZ9TkMwRjWxX0CAYgaINu6biYxMn0aPZAOKL3nTb0hATgl5sGYlFX_zvIlyI9UmVEjDXCbj6PNCfbpXkHHlGnl5nkQBH39SWeHPrk66YkUBIq_pYomm0A9W8Mz1FGAjcoDnKxgQzO2cx24j1pNNyGgF6ZrAK9eGi9wNheiw10ySFYZ8k2Tjyu_3SP1xcIjnxp2QMddVwbakkDlOuWINi9aBeCozuyi5ISkycHJghT4EbBi7mW-JxcyItLlZHVjVA1aygGOAPUEF_jhB4RF2NGrukKRLgUJDmK-HhYLnfFHAKdsatdN0-AzGKuE8s3JEUPyoQrvzyhGfZ9g0Z-hi2hRYmiJ03Y3ImtmfnW4qhXY5GucHB8f04lGrCr0F-vzoH8JuI1Rs16tEX5yf9x7RKI4COti2J7sXvLtKTtTgnfTcyNN74TTL0_dK3ee3jLiTu_IzhguxntTjK9oGPRNwfb0zpr3oJ0yKzrvqyDunFP3xo8HrAwwJCpYK9IoYuQahT9hNJy4z3BMYJ61K66YDSMhrpU0nLb0pDnh8lV3gXUvWsNVkqWRJvv58mh2n-Eq1iTRefWgchUy51hYd5W8MZjPuXgERXgEVV9u9z_zpHEnDwR5xr3aXb0OlZSmvR7Q4v6TGMYhtS4ptF_xHTj7yt8fOjpWEBqIRzRXPaGKUhYiWoErmlvTdhcwp-rWEOU3wMWNq7V4EH5iDr5VfUpZNmpI2X9FkiRcUrmzl5FK_LHf_KqwGaiStMDTpxR6DJu_0lSZx3L267Q-H3Zu7Qa9_E3cHEd3SpHN7NRhe3w2Gcb8f94f97vVHRN982fgqjgc313E_7vZuu4Ner__xD5uheu0" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2Fpako%3AeNqFVW1v2jAQ_iuWP4eOtBRKNFWqoJpYpQ0VdZMmpMkkR7BI7MwvrLTqf9_ZTiC8aXyAGN89d8_5eZx3msoMaEI1_LEgUhhzlitWzgXBD7NGClsuQNXr1EhFXnSzrpgyPOUVE4Y8VBVhmowKDmFV8JQZLsVp6CSbutBJhpHcbMlUyQ3PzoHOQGuEcNHN4wxbgDPlpxMXhVAGUgOZ-2Ne13YNd-7vsacEYQrcJ3M647kgXJC_3KzIbPZ9TkMwRjWxX0CAYgaINu6biYxMn0aPZAOKL3nTb0hATgl5sGYlFX_zvIlyI9UmVEjDXCbj6PNCfbpXkHHlGnl5nkQBH39SWeHPrk66YkUBIq_pYomm0A9W8Mz1FGAjcoDnKxgQzO2cx24j1pNNyGgF6ZrAK9eGi9wNheiw10ySFYZ8k2Tjyu_3SP1xcIjnxp2QMddVwbakkDlOuWINi9aBeCozuyi5ISkycHJghT4EbBi7mW-JxcyItLlZHVjVA1aygGOAPUEF_jhB4RF2NGrukKRLgUJDmK-HhYLnfFHAKdsatdN0-AzGKuE8s3JEUPyoQrvzyhGfZ9g0Z-hi2hRYmiJ03Y3ImtmfnW4qhXY5GucHB8f04lGrCr0F-vzoH8JuI1Rs16tEX5yf9x7RKI4COti2J7sXvLtKTtTgnfTcyNN74TTL0_dK3ee3jLiTu_IzhguxntTjK9oGPRNwfb0zpr3oJ0yKzrvqyDunFP3xo8HrAwwJCpYK9IoYuQahT9hNJy4z3BMYJ61K66YDSMhrpU0nLb0pDnh8lV3gXUvWsNVkqWRJvv58mh2n-Eq1iTRefWgchUy51hYd5W8MZjPuXgERXgEVV9u9z_zpHEnDwR5xr3aXb0OlZSmvR7Q4v6TGMYhtS4ptF_xHTj7yt8fOjpWEBqIRzRXPaGKUhYiWoErmlvTdhcwp-rWEOU3wMWNq7V4EH5iDr5VfUpZNmpI2X9FkiRcUrmzl5FK_LHf_KqwGaiStMDTpxR6DJu_0lSZx3L267Q-H3Zu7Qa9_E3cHEd3SpHN7NRhe3w2Gcb8f94f97vVHRN982fgqjgc313E_7vZuu4Ner__xD5uheu0%3Ftype%3Dpng" width="1407" height="1796"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where "Single" Sign-On Happens
&lt;/h2&gt;

&lt;p&gt;The reusable part is the identity-provider session.&lt;/p&gt;

&lt;p&gt;After login, the provider creates an opaque server-side browser session and stores its identifier in a host-only, &lt;code&gt;HttpOnly&lt;/code&gt;, &lt;code&gt;SameSite=Lax&lt;/code&gt; cookie. A later authorization request can reuse that session, including for another registered application in the same tenant.&lt;/p&gt;

&lt;p&gt;However, reusing authentication does not mean automatically granting access.&lt;/p&gt;

&lt;p&gt;The provider still checks that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the session belongs to the client's tenant;&lt;/li&gt;
&lt;li&gt;the user is still active;&lt;/li&gt;
&lt;li&gt;the user still has a role for the requesting client; and&lt;/li&gt;
&lt;li&gt;the current request satisfies rules such as &lt;code&gt;prompt=login&lt;/code&gt; or &lt;code&gt;max_age&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reveals an important SSO principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Authentication can be shared, but authorization must be evaluated for every application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A user may be signed in to the identity provider and still be denied access to a specific client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Tenancy Changes the Trust Boundary
&lt;/h2&gt;

&lt;p&gt;In a multi-tenant platform, the same SSO service supports many organizations. Isolation is therefore part of authentication itself, not merely a database concern.&lt;/p&gt;

&lt;p&gt;A multi-tenant implementation should associate users, OAuth clients, roles, sessions, and tokens with a tenant. The &lt;code&gt;client_id&lt;/code&gt; can determine the tenant during authorization, while issued tokens can contain both &lt;code&gt;tenant_id&lt;/code&gt; and &lt;code&gt;client_id&lt;/code&gt; claims.&lt;/p&gt;

&lt;p&gt;This prevents a valid identity from Tenant A from silently becoming valid for an application owned by Tenant B.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PKCE, State, and Redirect URIs Matter
&lt;/h2&gt;

&lt;p&gt;Several small-looking values protect the flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PKCE&lt;/strong&gt; binds the authorization request to the client that started it. An intercepted code is useless without the original verifier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State&lt;/strong&gt; lets the client detect forged or mismatched callbacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registered redirect URI matching&lt;/strong&gt; prevents the provider from sending codes to an attacker-controlled destination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single-use authorization codes&lt;/strong&gt; reduce replay risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nonce and authentication time&lt;/strong&gt; preserve OpenID Connect context in the ID token.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;S256 PKCE should protect both public clients, such as SPAs and mobile apps, and confidential server-side clients. Confidential clients can also authenticate with a secret that is stored as a hash and shown only when created or rotated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tokens Are Verifiable, Not Magical
&lt;/h2&gt;

&lt;p&gt;The identity provider can sign ID and access tokens with RS256. Applications retrieve public keys from a JWKS endpoint and verify token signatures without receiving the private signing key.&lt;/p&gt;

&lt;p&gt;Verification must include more than the signature. A client should also validate the issuer, audience, expiration, tenant, and expected nonce. Roles and scopes can then support application-level authorization.&lt;/p&gt;

&lt;p&gt;Access tokens are deliberately short-lived. Refresh tokens live longer, are stored hashed, rotate when used, and can be revoked. This limits damage while preserving a smooth user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Supports the Security Model
&lt;/h2&gt;

&lt;p&gt;A practical implementation can follow Clean Architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;domain entities describe clients, users, roles, codes, tokens, and sessions;&lt;/li&gt;
&lt;li&gt;use cases implement authorization, login, consent, token exchange, refresh, and logout;&lt;/li&gt;
&lt;li&gt;PostgreSQL stores durable identity and configuration data;&lt;/li&gt;
&lt;li&gt;Redis stores short-lived transactions, sessions, codes, and throttling counters;&lt;/li&gt;
&lt;li&gt;HTTP handlers translate protocol requests into use-case calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation keeps OAuth rules independent from specific web frameworks and storage technologies, making security behavior easier to test.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Main Lesson
&lt;/h2&gt;

&lt;p&gt;SSO is not simply a shared login form. It is a trust system connecting identities, organizations, applications, browser sessions, consent, and cryptographically verifiable tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;authenticate once, validate access per client, keep tenant boundaries explicit, and trust only server-validated protocol state.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is what turns "log in once" from a convenience feature into a secure identity architecture.&lt;/p&gt;




&lt;p&gt;I will share the source code related to this SSO implementation through the link below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source code:&lt;/strong&gt; &lt;a href="https://github.com/ranggaaprilio/keyles" rel="noopener noreferrer"&gt;Keyles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>sso</category>
      <category>authentication</category>
      <category>oidc</category>
    </item>
    <item>
      <title>🚀 The Secret Sauce of Scalable Apps: Database Connection Pooling</title>
      <dc:creator>Rangga Aprilio Utama</dc:creator>
      <pubDate>Fri, 02 Jan 2026 15:15:52 +0000</pubDate>
      <link>https://dev.to/ranggaaprilio/the-secret-sauce-of-scalable-apps-database-connection-pooling-1di</link>
      <guid>https://dev.to/ranggaaprilio/the-secret-sauce-of-scalable-apps-database-connection-pooling-1di</guid>
      <description>&lt;p&gt;When people talk about scalability, they usually mention caching, load balancers, or microservices.&lt;br&gt;&lt;br&gt;
But many apps fail much earlier — at the &lt;strong&gt;database connection level&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If your app talks to the database inefficiently, no amount of fancy architecture will save you.&lt;br&gt;&lt;br&gt;
That’s where &lt;strong&gt;database connection pooling&lt;/strong&gt; comes in.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 What Is Database Connection Pooling?
&lt;/h2&gt;

&lt;p&gt;A connection pool is simply a &lt;strong&gt;set of database connections kept ready in memory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of opening a brand-new database connection for every request, your app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Borrows a connection from the pool&lt;/li&gt;
&lt;li&gt;Runs the query&lt;/li&gt;
&lt;li&gt;Returns the connection to the pool&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The same connection gets reused many times.&lt;/p&gt;

&lt;p&gt;Simple idea. Massive impact.&lt;/p&gt;




&lt;h2&gt;
  
  
  ❌ Why Opening a New Connection Every Time Is a Bad Idea
&lt;/h2&gt;

&lt;p&gt;It &lt;em&gt;works&lt;/em&gt; in small apps, but breaks badly at scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Connections Are Expensive
&lt;/h3&gt;

&lt;p&gt;Opening a DB connection isn’t instant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;network handshake&lt;/li&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;li&gt;resource allocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can take &lt;strong&gt;tens or even hundreds of milliseconds&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ You Waste Database Resources
&lt;/h3&gt;

&lt;p&gt;Constantly creating and destroying connections forces the database to clean up over and over again.&lt;/p&gt;

&lt;p&gt;At high traffic, this adds up fast.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ You Can Kill Your Own Database
&lt;/h3&gt;

&lt;p&gt;Thousands of concurrent requests opening connections can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exhaust DB limits&lt;/li&gt;
&lt;li&gt;spike latency&lt;/li&gt;
&lt;li&gt;cause timeouts everywhere&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congrats — you’ve DDoS’ed yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ The 3 Pool Settings You Must Understand
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔢 Max Open Connections
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;maximum number of connections&lt;/strong&gt; the app can open to the database.&lt;/p&gt;

&lt;p&gt;If this limit is reached:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;new requests must wait&lt;/li&gt;
&lt;li&gt;wait too long → timeout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Too small = bottleneck&lt;br&gt;&lt;br&gt;
Too large = database overload&lt;/p&gt;




&lt;h3&gt;
  
  
  💤 Max Idle Connections
&lt;/h3&gt;

&lt;p&gt;How many connections are allowed to sit idle in the pool.&lt;/p&gt;

&lt;p&gt;Why this matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;idle connections = faster responses&lt;/li&gt;
&lt;li&gt;no need to reconnect from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But too many idle connections waste DB resources.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⏳ Max Connection Lifetime
&lt;/h3&gt;

&lt;p&gt;How long a connection can live before being recycled.&lt;/p&gt;

&lt;p&gt;This helps prevent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stale connections&lt;/li&gt;
&lt;li&gt;silent disconnects from the database or network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always keep this &lt;strong&gt;shorter than the DB’s own timeout&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ Common Pitfalls (Read This Carefully)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💣 Connection Leaks
&lt;/h3&gt;

&lt;p&gt;The most common pooling bug.&lt;/p&gt;

&lt;p&gt;It happens when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a connection is taken from the pool&lt;/li&gt;
&lt;li&gt;but never returned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usually caused by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing &lt;code&gt;finally&lt;/code&gt; / &lt;code&gt;defer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;early returns&lt;/li&gt;
&lt;li&gt;bad error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pool slowly drains&lt;/li&gt;
&lt;li&gt;requests hang&lt;/li&gt;
&lt;li&gt;app looks “dead”&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔄 Connection Reset Is Mandatory
&lt;/h3&gt;

&lt;p&gt;Before a connection goes back to the pool, it must be cleaned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rollback open transactions&lt;/li&gt;
&lt;li&gt;release locks&lt;/li&gt;
&lt;li&gt;reset session state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Otherwise, the next request inherits a mess.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧐 Pre-Ping vs Optimistic Use
&lt;/h3&gt;

&lt;p&gt;Some pools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;test connections (&lt;code&gt;SELECT 1&lt;/code&gt;) before handing them out → safer, slower&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Others:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use the connection directly&lt;/li&gt;
&lt;li&gt;recreate it only on failure → faster, riskier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose based on your latency and network reliability.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Connection pooling isn’t an optimization — it’s &lt;strong&gt;foundational&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A well-sized pool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keeps latency low&lt;/li&gt;
&lt;li&gt;protects your database&lt;/li&gt;
&lt;li&gt;lets your app scale smoothly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get this wrong, and your app will fail under load no matter how good your code is.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚕 A Simple Analogy
&lt;/h2&gt;

&lt;p&gt;Imagine a taxi company.&lt;/p&gt;

&lt;p&gt;Bad approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build a new car for every passenger&lt;/li&gt;
&lt;li&gt;destroy it after the ride&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s opening a DB connection per request.&lt;/p&gt;

&lt;p&gt;Good approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep a fleet of cars&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reuse them for different passengers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Max Open Connections&lt;/strong&gt; = total cars  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Max Idle Connections&lt;/strong&gt; = cars waiting at the station  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Efficient, scalable, and sane.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>database</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
