7 คะแนน โดย GN⁺ 2025-12-27 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • ตัวจัดการแพ็กเกจ หลายตัวเลือก ใช้ Git ราวกับเป็นฐานข้อมูล เพราะสะดวกต่อการจัดการเวอร์ชันและการทำงานร่วมกัน แต่เมื่อระบบใหญ่ขึ้นก็เจอปัญหาด้านประสิทธิภาพและการบำรุงรักษา
  • Cargo, Homebrew, CocoaPods เป็นต้น ต่างต้องเปลี่ยนไปใช้ ดัชนีแบบ HTTP หรือ CDN ในที่สุด เนื่องจากขนาดของ Git index ที่โตขึ้น ความช้าในการอัปเดต และความไม่มีประสิทธิภาพในสภาพแวดล้อม CI
  • vcpkg ยังทำงานโดยอิงกับ Git tree hash และในสภาพแวดล้อมแบบ shallow clone ก็เกิด การบิลด์ล้มเหลวและวิธีแก้ชั่วคราวที่ซับซ้อน
  • ระบบ Go modules นำ GOPROXY และ ฐานข้อมูล checksum (sumdb) มาใช้ เพื่อตัดการพึ่งพา Git และปรับปรุงทั้งความปลอดภัยและความเร็ว
  • Git ยอดเยี่ยมสำหรับการทำงานร่วมกันบนโค้ด แต่มีหลักฐานซ้ำๆ ว่า ไม่เหมาะกับการ query เมทาดาทาของแพ็กเกจหรือการจัดการ registry ขนาดใหญ่

ความล้มเหลวที่เกิดซ้ำของความพยายามใช้ Git เป็นฐานข้อมูล

  • Git มีข้อดีอย่าง ประวัติเวอร์ชัน, โครงสร้างแบบกระจายศูนย์, และโฮสติ้งฟรี จึงดูน่าสนใจ แต่เมื่อใช้เป็นฐานข้อมูลก็จะชนกับข้อจำกัดด้านการขยายระบบ
  • ตัวจัดการแพ็กเกจหลายตัวนำ Git มาใช้เป็นดัชนี แต่เมื่อเวลาผ่านไป ปัญหาประสิทธิภาพและภาระด้านโครงสร้างพื้นฐาน ก็หนักขึ้นเรื่อยๆ

Cargo

  • ดัชนีของ crates.io เริ่มต้นในรูปแบบ Git repository และไคลเอนต์ทุกตัวต้องทำการ clone ทั้งหมด
    • เมื่อ repository โตขึ้น ก็เกิด คอขวดด้านประสิทธิภาพของ libgit2 ในขั้นตอน delta resolution
    • ในสภาพแวดล้อม CI ต้องดาวน์โหลดดัชนีทั้งหมดใหม่ทุกครั้งที่บิลด์ ทำให้สิ้นเปลืองอย่างมาก
  • ผ่าน RFC 2789 มีการนำ sparse HTTP protocol มาใช้ เพื่อดึงเฉพาะเมทาดาทาที่จำเป็นผ่าน HTTPS
    • ณ เดือนเมษายน 2025 คำขอ 99% ใช้ sparse mode
    • Git index ยังมีอยู่ แต่ผู้ใช้ส่วนใหญ่ไม่ได้เข้าถึงแล้ว

Homebrew

  • GitHub ขอให้ Homebrew หยุดใช้ shallow clone โดยชี้ว่าการอัปเดตเป็น “การประมวลผลที่มีต้นทุนสูงมาก”
    • โฟลเดอร์ .git ของ homebrew-core มีขนาดเกือบ 1GB และการอัปเดตเกิดความหน่วงจาก delta resolution
  • ใน Homebrew 4.0.0 เดือนกุมภาพันธ์ 2023 การอัปเดต tap ถูกเปลี่ยนเป็น การดาวน์โหลดแบบ JSON
    • เมื่อเลิกใช้ Git fetch ความเร็วในการอัปเดตดีขึ้น และรอบการอัปเดตอัตโนมัติก็เปลี่ยนจากทุก 5 นาทีเป็นทุก 24 ชั่วโมง

CocoaPods

  • ตัวจัดการแพ็กเกจสำหรับ iOS/macOS อย่าง CocoaPods มี Specs repository ที่ประกอบด้วย podspec หลายแสนรายการจนใหญ่เกินไป
    • การ clone และอัปเดตกินเวลาหลายนาที และเวลาส่วนใหญ่ใน CI หมดไปกับการทำงานของ Git
  • GitHub ใช้ CPU rate limit และชี้ว่า shallow clone เป็นสาเหตุหนึ่งของภาระบนเซิร์ฟเวอร์
  • ทีมงานใช้มาตรการชั่วคราว เช่น หยุด fetch อัตโนมัติ, เปลี่ยนเป็น full clone, และ sharding repository
  • ตั้งแต่ เวอร์ชัน 1.8 เป็นต้นมา ได้เปลี่ยนเป็น การแจกจ่ายผ่าน HTTP บน CDN ช่วยประหยัดพื้นที่ดิสก์ของผู้ใช้ราว 1GB และเพิ่มความเร็วในการติดตั้งอย่างมาก

Nixpkgs

  • ฝั่งไคลเอนต์ของ Nix ใช้ channel แบบ tarball อยู่แล้ว จึงหลีกเลี่ยงการ clone Git
    • package expression ถูกให้บริการผ่าน HTTP จาก S3 และ CDN
  • อย่างไรก็ตาม โครงสร้างพื้นฐานของ GitHub ยังรับภาระจาก repository ขนาด 83GB และ fork 20,000 รายการ
    • ในเดือนพฤศจิกายน 2025 GitHub รายงาน ความล้มเหลวของฉันทามติระหว่างสำเนาและข้อผิดพลาดในงานบำรุงรักษา
    • แม้ local clone จะมีขนาด 2.5GB แต่ทั้งเครือข่ายของ fork ก็ยังกดดันพื้นที่จัดเก็บของ GitHub

vcpkg

  • vcpkg ตัวจัดการแพ็กเกจ C++ ของ Microsoft ใช้ Git tree hash ในการจัดการเวอร์ชัน
    • หากต้องการทำซ้ำพอร์ต ณ commit หนึ่งผ่าน builtin-baseline ก็จำเป็นต้องมีประวัติทั้งหมด
  • ใน สภาพแวดล้อมแบบ shallow clone (GitHub Actions, DevContainers) จะเกิดการบิลด์ล้มเหลว
    • วิธีแก้คือต้องตั้งค่า fetch-depth: 0 เพื่อดาวน์โหลดประวัติทั้งหมด
  • ด้วยโครงสร้างของ Git tree hash ทำให้ ติดตาม commit ไม่ได้ และแก้ไขข้อจำกัดเชิงโครงสร้างนี้ไม่ได้
  • ปัจจุบันยังรองรับเฉพาะ registry แบบ Git repository เท่านั้น และ ยังไม่มีทางเลือกแบบ HTTP หรือ CDN

ระบบ Go modules

  • ทีมวิศวกรรมของ Grab ระบุว่า หลังนำ module proxy มาใช้ เวลา go get ลดจาก 18 นาที → 12 วินาที
  • วิธีเดิมต้อง clone repository ทั้งหมดของแต่ละ dependency เพื่ออ่าน go.mod
  • ทีม Go กังวลเรื่อง การพึ่งพาเครื่องมือ VCS และช่องโหว่ด้านความปลอดภัย
  • ตั้งแต่ Go 1.13 เป็นต้นมา GOPROXY เป็นค่าปริยาย โดยให้บริการ source ของโมดูลและ go.mod ผ่าน HTTP
    • sumdb (ฐานข้อมูล checksum) ช่วยรับประกันความสมบูรณ์และความคงอยู่ของโมดูล

ปัญหาทั่วไปเมื่อใช้ Git เป็นฐานข้อมูล

  • Git-based wiki (Gollum) มีปัญหาการไล่ดูไดเรกทอรีและโหลดหน้าที่ช้าลงเมื่อ repository มีขนาดใหญ่
    • GitLab มีแผนเลิกใช้ Gollum
  • Git-based CMS (Decap) ติดเพดานคำขอของ GitHub API ที่ 5,000 ครั้ง
    • ประสิทธิภาพลดลงเมื่อมีรายการราว 10,000 รายการขึ้นไป และผู้ใช้ใหม่ที่เริ่มจากแคชว่างจะทำให้คำขอพุ่งสูง
  • เครื่องมือ GitOps (ArgoCD) มีปัญหาพื้นที่ดิสก์ไม่พอเมื่อ clone repository
    • commit เดียวสามารถทำให้แคชทั้งหมดใช้ไม่ได้ และ monorepo ขนาดใหญ่ต้องสเกลแยกต่างหาก

เหตุผลเชิงโครงสร้างที่ Git ไม่เหมาะเป็นฐานข้อมูล

  • ข้อจำกัดของไดเรกทอรี: ยิ่งมีไฟล์มากก็ยิ่งช้า
    • CocoaPods เคยสร้าง tree object ขนาดมหาศาลจากไดเรกทอรี 16,000 รายการ ก่อนแก้ด้วยการ sharding ตาม hash
  • ปัญหาความต่างตัวพิมพ์เล็ก-ใหญ่: Git แยก แต่ macOS และ Windows ไม่แยก
    • Azure DevOps เพิ่มฟังก์ชันบล็อกฝั่งเซิร์ฟเวอร์เพื่อป้องกันการชนกัน
  • ข้อจำกัดความยาว path: ข้อจำกัด 260 อักขระของ Windows ทำให้ git status เกิดข้อผิดพลาด
  • ไม่มีฟังก์ชันแบบฐานข้อมูล:
    • ไม่มีทั้ง CHECK/UNIQUE constraint, locking, index, หรือ migration
    • ตัวจัดการแพ็กเกจแต่ละตัวต้องสร้างระบบตรวจสอบและทำดัชนีขึ้นมาเอง

สรุป

  • Git ยอดเยี่ยมสำหรับ การทำงานร่วมกันบนซอร์สโค้ด แต่ ไม่เหมาะกับการ query เมทาดาทาของแพ็กเกจหรือการจัดการ registry ขนาดใหญ่
  • ตัวจัดการแพ็กเกจส่วนใหญ่สุดท้ายต้องเปลี่ยนไปใช้ ดัชนีแบบ HTTP หรือฐานข้อมูล
  • แม้ข้อดีของ Git อย่างประวัติเวอร์ชันและ workflow แบบ PR จะน่าสนใจ แต่ ในฐานะตัวแทนฐานข้อมูลนั้นล้มเหลว
  • ต่อให้ Git index ดูน่าสนใจเมื่อออกแบบตัวจัดการแพ็กเกจใหม่ ก็จะไปถึงข้อจำกัดเดิมเช่นเดียวกับกรณีของ Cargo, Homebrew, CocoaPods, vcpkg และ Go

2 ความคิดเห็น

 
lamanus 2025-12-28

แทนที่จะสร้างระบบแยกต่างหากเพื่อรับการมีส่วนร่วมจากผู้ร่วมพัฒนา ก็แค่ใช้ git เพราะมันสะดวกกว่าเท่านั้นเอง เรื่องที่บอกว่าเป็นข้อจำกัดนั้นผมไม่ค่อยเห็นด้วยเท่าไร และก็ไม่เห็นทางเลือกสำหรับปัญหาในโลกความเป็นจริงเลยด้วย

 
GN⁺ 2025-12-27
ความคิดเห็นบน Hacker News
  • เรื่องนี้ดูคล้าย โศกนาฏกรรมของทรัพยากรส่วนรวม อยู่เหมือนกัน GitHub ฟรีและมีฟีเจอร์ดีๆ มากมาย ทุกคนเลยอยากใช้ แต่การตัดสินใจแบบนี้มักเกิดขึ้นเสมอเมื่อมี ผลกระทบภายนอก
    ผลกระทบภายนอกที่ผมให้ความสำคัญที่สุดคือ เวลาของผู้ใช้ บริษัทซอฟต์แวร์ส่วนใหญ่มักสนใจแค่ต้นทุนเวลาเชิงวิศวกรรม และมองข้ามเวลาของผู้ใช้ พวกเขาทุ่มเทกับการพัฒนาฟีเจอร์ แต่ไม่ค่อยปรับเวลาในการโต้ตอบของผู้ใช้ให้เหมาะสม ตัวอย่างเช่น ถ้าผมใช้เวลา 1 ชั่วโมงเพื่อทำให้แอปเร็วขึ้น 1 วินาที ผู้ใช้หนึ่งล้านคนจะประหยัดเวลาได้รวม 277 ชั่วโมงต่อปี แต่เพราะเวลาของผู้ใช้เป็นผลกระทบภายนอก การปรับแต่งแบบนี้จึงแทบไม่เกิดขึ้น
    สุดท้ายผู้ใช้ก็ต้องดาวน์โหลดข้อมูลเกินความจำเป็นและรอโดยเปล่าประโยชน์ ขณะที่นักพัฒนาไม่ต้องรับผิดชอบต่อความสูญเปล่านั้น

    • ผมไม่แน่ใจนักว่าคำว่า “software house” หมายถึงอะไรกันแน่ แต่ ผลิตภัณฑ์ซอฟต์แวร์สำหรับผู้บริโภค ส่วนใหญ่ที่ผมเคยทำงานด้วยต่างติดตามตัวชี้วัดอย่างความเร็วตอนเริ่มต้นหรือ latency เป็นเรื่องสำคัญ เรื่องแบบนี้ถือเป็นสามัญสำนึกมาตั้งแต่หลายสิบปีก่อนแล้ว เช่น เรามักได้ยินว่า Amazon สูญเงินหลายล้านดอลลาร์เพียงเพราะหน้าเว็บโหลดช้าลงไม่กี่มิลลิวินาที
    • นี่ก็อยู่ในบริบทเดียวกับคำพูดที่ว่า “ความเร็วก็เป็น ฟีเจอร์(feature) อย่างหนึ่ง” เพียงแต่ว่าเวลาของผู้ใช้ไม่ได้ขึ้นกับประสิทธิภาพอย่างเดียว แต่ยังขึ้นกับ การออกแบบ UI อย่างมากด้วย
    • ผมไม่คิดว่านี่จะเป็น “โศกนาฏกรรมของทรัพยากรส่วนรวม” GitHub เป็นของ Microsoft ดังนั้นพวกเขาคงตัดสินใจแล้วว่ารับภาระนี้ได้ ทรัพยากรส่วนรวมจริงๆ ควรเป็นโครงสร้างที่ไม่มีใครเป็นเจ้าของแต่ทุกคนได้ประโยชน์ร่วมกัน
    • พอคิดเรื่องนี้ลึกๆ ก็ทำให้นึกถึงคำพูดของ Alan Kay — “ถ้าคุณเห็นว่าซอฟต์แวร์สำคัญจริง คุณก็ควร สร้างฮาร์ดแวร์เองด้วย” การโหลดผ่านเครือข่ายเป็นประสบการณ์ผู้ใช้ที่แย่อยู่แล้วโดยธรรมชาติ ถ้าอยากเคารพผู้ใช้อย่างแท้จริงก็ควรสร้างแอปแบบ local-first(native-first) แต่บริษัทที่ให้ความสำคัญกับประสบการณ์ผู้ใช้ถึงระดับนั้นมีน้อยมาก
    • ถ้าอ่านบทความของ Andy Hertzfeld “Saving Lives” จะเจอเกร็ดที่น่าสนใจ — มีเรื่องเล่าว่า “Macintosh บูตช้าเกินไป ต้องทำให้เร็วกว่านี้!”
  • ผมกำลังทำ Cargo/UV สำหรับภาษา C อยู่ เห็นด้วยกับบทความนี้มาก
    ตอนเริ่มต้นใหม่ๆ การ ดูแล registry เป็นเรื่องยากมาก ไม่ใช่แค่ต้องเขียนโค้ด รักษาคุณภาพเครื่องมือ และขยายชุมชน แต่ยังต้องคิดเรื่องโครงสร้างพื้นฐานที่จะรองรับทราฟฟิกจากทั่วโลกด้วย ในสถานการณ์แบบนี้ โซลูชันที่อิง git จึงน่าดึงดูดมาก
    แต่ปัญหาคือ sparse checkout ผมอยากใช้ git จัดการเวอร์ชันของ package manifest แต่ต้องติดตาม commit แบบตามอำเภอใจ ทำให้ไม่มีประสิทธิภาพ สุดท้ายเลยกลายเป็นโครงสร้างที่ต้อง push สอง commit ซึ่งในทางปฏิบัติแทบเป็นไปไม่ได้
    ผมคิดว่าแนวทางของ Conan ใช้งานได้จริงที่สุด คือยอมแลก reproducibility แบบสมบูรณ์กับการใส่ตรรกะแบบมีเงื่อนไขไว้ใน manifest และยังทำ mapping ของ manifest ตามช่วงเวอร์ชันได้ด้วย ไม่สมบูรณ์แบบ แต่เป็น ทางประนีประนอมที่ใช้งานได้จริงและมีประโยชน์
    แน่นอนว่าคำตอบที่แท้จริงคือใช้ฐานข้อมูล แต่ในโลกความจริงก็ไม่มีใครมาจ่ายค่าเซิร์ฟเวอร์และค่าดูแลแทนอยู่ดี

    • ถ้ามองอีกมุม package manager ที่ประสบความสำเร็จส่วนใหญ่ก็เริ่มต้นแบบ อิง Git ก่อน แล้วค่อยย้ายไปโครงสร้างที่มีประสิทธิภาพกว่าตอนจำเป็น
    • แนวทางแบบ Arch Linux AUR ก็น่าสนใจ แต่ละแพ็กเกจมี git repository แยกของตัวเองและมีแค่ manifest วิธีนี้ช่วยเลี่ยง ปัญหา monorepo หรือฝันร้ายเรื่องการอ้างอิงได้
    • การใช้ HTTP backend แบบง่ายๆ อย่าง S3 มาทำ storage ก็น่าสนใจ เริ่มจากเซิร์ฟเวอร์เครื่องเดียวก่อน แล้วถ้าเริ่มดังขึ้นก็ค่อยหาสปอนเซอร์แล้วย้ายขึ้นคลาวด์
      ถ้าปัญหาคือเรื่องเงินกับความเป็นอิสระ จะใช้แบบ P2P ก็ได้เหมือนกัน แต่ถ้าไม่มี CI caching ทราฟฟิกอาจพุ่งขึ้นมาก
    • ถ้ายังมีผู้ใช้ไม่มาก การเตรียมโครงสร้างพื้นฐานสำหรับทั้งโลกตั้งแต่แรกก็คือ การเตรียมตัวเกินความจำเป็น
    • จริงๆ แล้วไม่จำเป็นต้องแสดง ข้อมูลประวัติทั้งหมด ให้ผู้ใช้เห็น ใช้ post-commit hook render แค่สถานะของ HEAD ออกมาเป็นไฟล์ static แล้วให้บริการแบบ GitHub Pages ก็พอ
      โครงสร้าง mirror ของลินุกซ์ดิสโทรอย่าง Debian, Fedora, openSUSE ก็น่าศึกษาเช่นกัน
  • บทความนี้กำลังปนกันระหว่างสองปัญหา ปัญหาหนึ่งคือ การใช้ git เป็นฐานข้อมูลสำหรับ package index อีกปัญหาคือ การดึงโค้ดของแต่ละแพ็กเกจผ่าน git ซึ่งเป็นคนละเรื่องกัน
    index จะใช้ git ส่วนแพ็กเกจจะใช้ zip/tar ก็ได้ หรือจะสลับกันก็ได้ สำหรับ Go นั้นเป็นโครงสร้างที่ไม่มี index ไปเลยด้วยซ้ำ

    • ดูเหมือนผู้เขียนจะสับสนเล็กน้อย ผมเห็นด้วยกับข้อโต้แย้งที่ว่า “อย่าให้ผู้ใช้ทุกคนต้อง clone ฐานข้อมูล” แต่ก็ไม่ได้แปลว่าใช้ git graph เป็น data encoding ไม่ได้
      เรื่อง backend implementation ของ GitHub หรือจำนวน fork 20,000 อัน ไม่เกี่ยวกับแก่นของปัญหาเลย แม้ไม่มี git working tree ก็ยังทำ key-value lookup ที่มีประสิทธิภาพได้
      ส่วนคำกล่าวที่ว่า “การ rewrite git history ก็เหมือน DB migration” ก็ดูแปลกๆ ไม่สู้ รัน Postgres ตัวเดียว ไปเลยไม่ดีกว่าหรือ?
    • ประเด็นของบทความจริงๆ ไม่ได้อยู่ที่ตัวโค้ด แต่เป็นกระบวนการดึงไฟล์ go.mod ต่างหาก เพราะอย่างนั้นจึงแก้ด้วยการโฮสต์ go.mod แยกต่างหาก
    • ใน git เองก็ ดึงเฉพาะไฟล์เดียวที่ต้องการ ได้ แต่โดยโครงสร้างแล้วก็ยังดูฝืนอยู่ดี
  • แนวคิดแบบ “ใช้วิธีง่ายก่อนตอนที่มันยังใช้ได้ แล้วค่อยแก้ทีหลังถ้ามีปัญหา” ก็สมเหตุสมผล
    Julia ก็ใช้แนวทางนี้เหมือนกัน และมีจำนวนแพ็กเกจน้อยกว่า Rust ราว 1/7 เลยยังไม่เป็นปัญหา
    ปรับปรุงให้โหลดแค่ไฟล์ระดับบนสุด Registry.toml แล้วค่อยดาวน์โหลดเฉพาะแพ็กเกจที่ต้องใช้ก็ได้ ไม่ใช่ปัญหาใหญ่

    • Julia ใช้ git registry เป็นเพียง ledger ทางการ ส่วน client จริงใช้ Pkg Protocol
    • จะเรียกแนวทางนี้ว่าเป็นจิตวิญญาณแบบ “FAFO(ลองไปก่อนแล้วค่อยพัง)” ก็ได้ ใช้งานได้จริงก็จริง แต่ส่วนตัวผมไม่ค่อยชอบ
    • ผมคิดว่าท่าทีแบบนี้ ผิดจริยธรรม อยู่พอสมควร แนวคิด “ทำให้ง่ายไว้ก่อนแล้วค่อยแก้ทีหลัง” สุดท้ายก็คือการพอกหนี้เทคนิค
      วัฒนธรรม “Move fast and break things” ทำให้เราได้ซอฟต์แวร์ที่ช้าและบั๊กเยอะอย่างในปัจจุบัน
    • ถ้าไปแก้ปัญหาทีหลัง ต้นทุนจะเพิ่มแบบทวีคูณ สุดท้ายก็จะลงเอยที่ “ปล่อยมันพังนิดๆ แล้วใช้ต่อไป” ซึ่งบทความนี้ก็ยกกรณี vcpkg มาเป็นตัวอย่าง
    • มีตัวอย่างหนึ่งที่ดูเหมือนมีคน จงใจปรับแต่ง UUID ซึ่งฟังแล้วก็น่ากังวลว่าทำแบบนั้นได้ด้วยหรือ
  • ผมเห็นด้วยกับข้อสรุปที่ว่า “Git เป็นฐานข้อมูลเริ่มต้นที่ยอดเยี่ยมสำหรับ package manager”

    • แต่ฝั่ง client ไม่ควรรับทั้ง repository ทั้งก้อน ควรมี ชั้น cache หรือ DB คั่นไว้ โดยเฉพาะในสภาพแวดล้อม CI/CD ที่ประสิทธิภาพสำคัญมาก
    • Nixpkgs ก็ประสบความสำเร็จได้เพราะ Git ปัญหาเรื่องสเกลเป็นความหรูหราที่ค่อยกังวลทีหลังได้
    • แต่ก่อนจะสรรเสริญ Git ก็ควรไปอ่าน งานวิจัยด้านฐานข้อมูล บ้างอย่างน้อยสักนิด
    • Git อาจนำไปสู่ฝันร้ายด้านซัพพลายเชนได้ เหตุการณ์ Leftpad อาจเกิดซ้ำทุกสัปดาห์ก็ได้
    • Git แย่มาก ถ้าจะใช้เป็น DB สำหรับ package manager ที่ทุกคนใช้กันก็แค่เพราะ GitHub โฮสต์ให้ฟรี
  • ผมอยู่ฝั่ง “สุดท้ายมันก็เวิร์กนี่” มุมมองคือมันช่วยการดำเนินงานระยะแรกได้มากพอ และปัญหาเรื่องสเกลก็ไปแก้ทีหลังได้

    • แต่บางโปรเจ็กต์ก็ติดอยู่กับ git เพราะ ข้อจำกัดเชิงสถาปัตยกรรม จนหลุดออกมาไม่ได้
    • ถ้าเริ่มจากสโตร์แบบ อิงระบบไฟล์ อย่าง git การเปลี่ยนโปรโตคอลทีหลังแทบเป็นไปไม่ได้ ควรออกแบบแบบ API-centric ตั้งแต่แรก
    • อีกด้านหนึ่งก็ยังมีโอกาสใช้ git ให้มีประสิทธิภาพกว่านี้ การบอกให้เลิกใช้ git โดยไม่เสนอทางเลือกก็เป็น ข้อสรุปครึ่งๆ กลางๆ
    • ยังมีมุกประชดประมาณว่า “แค่สเกลจาก 0 ถึง 1 ล้านล้านผู้ใช้ไม่ได้ ก็กลายเป็นขยะเลยเหรอ”
  • ตรงนี้มี survivorship bias อยู่ Cargo มีปัญหาเรื่อง git index โตขึ้นก็เพราะมันประสบความสำเร็จ
    โปรเจ็กต์เล็กๆ ส่วนใหญ่ยังใช้ git เป็นโปรโตคอลกระจายข้อมูลได้ดีอยู่
    ในช่วงเริ่มต้นที่ยังไม่รู้ว่าจะสเกลแค่ไหน การใช้ git และ GitHub เพื่อ โฟกัสกับปัญหาหลัก ถือว่า合理

    • ต้องระวัง การ optimization เร็วเกินไป Cargo หรือ Homebrew เองก็เติบโตมาได้เพราะเลือกทางง่าย และปัญหาเรื่องสเกลในภายหลังก็เป็น “ปัญหาที่น่ายินดี”
  • เวลาเห็นบทความบนหน้าแรก HN ที่บอกว่า “สิ่งที่คุณทำอยู่ตอนนี้ผิด” ผมมักจะถ่อมตัวลงเสมอ
    ผมเองก็เคยเจอแบบนั้นหลายครั้ง ครั้งนี้เป็นบทความเกี่ยวกับ PG Notify
    แต่ตอนนี้ผมกำลังพัฒนาคนเดียว และยังไม่รู้ด้วยซ้ำว่าโปรเจ็กต์จะสำเร็จไหม ดังนั้นการ แจกจ่ายปลั๊กอินด้วย git จึงเป็นทางเลือกที่สมจริงที่สุด
    ถึงอย่างนั้นถ้าวันหนึ่งมีปัญหาเรื่องสเกล ผมก็ตั้งใจจะกลับมาอ่านบทความนี้อีก

    • ตอนนี้ก็ยังพอหลีกเลี่ยง กับดักบางอย่าง ได้ เช่นปัญหา vendor lock-in จากการพึ่ง GitHub มากเกินไป ซึ่งอาจใหญ่กว่าปัญหาอื่นเสียอีก
  • ส่วนตัวผมโฮสต์โค้ดด้วย Forgejo และป้องกันด้วย mTLS โดยไม่เปิดออกสู่ภายนอก
    แต่ Go modules ต้องการใบรับรอง ทำให้มองไม่เห็นอินสแตนซ์ Forgejo ของผม
    ถึงจะใช้ SSH ก็ยังบอกว่าต้องเข้าผ่าน HTTPS อยู่ดี สุดท้ายเลยต้องใช้ replace directive แล้วอ้างอิง clone ในเครื่องแทน ค่อนข้างยุ่งยาก

    • ถ้าเติม .git ที่ท้าย module path และตั้งค่า $GOPRIVATE ก็จะใช้ การยืนยันตัวตนผ่านคำสั่ง git ได้โดยไม่ต้องมีคำขอ HTTPS ดู เอกสารทางการ
    • ถ้าเพิ่ม ใบรับรอง TLS (CA) ของอินสแตนซ์เข้าไปใน trust store ก็จะดาวน์โหลดผ่าน HTTPS ได้เช่นกัน
    • คำพูดที่ว่า “ต้องมีการเข้าถึงผ่าน HTTP” ไม่เป็นความจริง local proxy ก็แก้ได้
    • ถ้าใช้ Tailscale DNS และใบรับรอง ก็รับใบรับรอง Let’s Encrypt ได้โดยไม่ต้องเปิดออกสู่ภายนอก
  • ไม่ใช่แค่ package manager แต่โปรเจ็กต์เล็กๆ จำนวนมากก็ crowdsource ข้อมูลลงใน git repository เช่นกัน
    ส่วนใหญ่มีขนาดเล็กพอจนยังไม่ชนข้อจำกัดทางเทคนิค
    แต่โครงสร้างแบบนี้ทำให้ อุปสรรคในการมีส่วนร่วมของคนที่ไม่ใช่นักพัฒนา สูงขึ้น แม้ package manager จะเป็นข้อยกเว้น แต่กับโปรเจ็กต์ทั่วไปถือว่าเป็นปัญหา
    ผมสร้างไลบรารีโอเพนซอร์สชื่อ Datatig เพื่อช่วยแก้ปัญหานี้
    สไลด์ประกอบการบรรยายอยู่ ที่นี่ และจากนี้ไปผมก็ตั้งใจจะอ้างอิงบทความนี้เพื่อเพิ่มเนื้อหาเรื่อง การสเกล ด้วย