plan/chapter_3_tasks
Raw Download raw file

authors: Bryon bryon@fryer.io state: pre-discussion labels: language-choice, golang, engineering date: 2025-07-20

Choosing Golang as the Primary Language

Summary

This RFD proposes adopting Go (Golang) as the primary implementation language for our backend and systems-level development. Go offers simplicity, performance, strong concurrency primitives, and a thriving ecosystem that aligns well with our goals for maintainability, reliability, and developer productivity.

Motivation

We need a language that:

  • Produces reliable, fast binaries
  • Has a low barrier to entry for new contributors
  • Encourages maintainable and readable code
  • Supports concurrency with minimal cognitive overhead
  • Has excellent tooling and ecosystem support
  • Offers a strong standard library for networking, file I/O, and HTTP

Requirements

The primary language should:

  1. Be simple to learn and onboard new developers
  2. Support high-concurrency and networked systems efficiently
  3. Provide cross-platform compilation with minimal setup
  4. Have a strong ecosystem of open source libraries and tooling
  5. Be used widely in production by companies operating at scale
  6. Offer first-class support for testing and static analysis
  7. Enable fast iteration and deployment without lengthy build chains

Evaluation

Language Simple Syntax Concurrency Ecosystem Binary Output Tooling Adoption
Go ✅ Goroutines, Channels ✅ Robust, Standardized ✅ Single binary go fmt, go test, go vet, gopls ✅ Google, Uber, Cloudflare, etc.
Rust ❌ Complex tokio, async/await ✅ Strong ✅ Excellent, but heavy ✅ Dropbox, AWS, Meta
Python ❌ GIL limits concurrency ✅ Rich ❌ Needs interpreter ✅ Excellent ✅ Google, Instagram
Node.js ✅ Event-loop model ✅ Large but fragmented ❌ Requires runtime ✅ Good, npm-heavy ✅ Vercel, Netflix
Java ❌ Verbose ✅ Threads, Loom (preview) ✅ Mature ✅ JVM-based ✅ Heavyweight ✅ Everywhere

Benefits of Go

  • Simplicity: Go has a small surface area; developers can become productive quickly.
  • Concurrency: Goroutines and channels provide a clean abstraction over threads and async code.
  • Tooling: The Go toolchain is self-contained and includes built-in formatting, testing, vetting, and documentation tools.
  • Deployment: Statically linked binaries make deployment trivial and reduce runtime surprises.
  • Community: Large, vibrant open-source community with active development and library support.
  • Performance: Close to C-level performance with minimal optimization effort.

Risks and Tradeoffs

  • Runtime GC: Garbage collection introduces non-deterministic pauses, though this is usually negligible.
  • No exceptions: Go prefers explicit error handling; this is stylistically different from some other languages.
  • Not as low-level as Rust or C: Go is not designed for systems programming requiring strict control over memory layout.

Alternatives Considered

  • Rust: Excellent for performance and safety, but significantly higher complexity and slower iteration time.
  • Python: Excellent for scripting and data tasks but lacks performance and concurrency for backend systems.
  • JavaScript/Node.js: Good for fast prototyping but less suited for long-lived backend services with heavy concurrency.

Recommendation

Adopt Go as the primary language for:

  • Backend services
  • Network proxies, schedulers, or agents
  • Internal tooling
  • CLIs and infrastructure automation

Project Fit: buylater.email

The buylater.email project is a strong match for Go, due to its focus on minimalism, privacy, and deterministic backend behavior. The core architectural needs include:

  • Stateless HTTP endpoints for link submission, confirmation, and unsubscribe
  • Scheduled email delivery without persistent infrastructure
  • Secure, tokenized URLs for one-click interactions
  • Transparent, inspectable code that can run on cheap VPS or on-prem

Go is particularly well suited here because:

  • It supports zero-dependency deployments — one static binary does it all
  • It includes robust native libraries for net/http, crypto, html/template, context, and time
  • Its concurrency model is ideal for building timed job schedulers and retry queues
  • Go makes it easy to avoid shelling out — all logic can live safely in a single process
  • Low cold start time and predictable memory usage enable frictionless hosting

We also expect the project to scale to serve thousands of scheduled reminders per day, a throughput well within Go’s sweet spot for low-latency I/O and CPU-light tasks.