The Systems Landscape: Reflections on Go, Solidity, Dart, and Low-Level Storage

Over the past few years, my technical work has spanned unusual intersections: writing high-throughput storage engines in Go, manipulating low-level Windows APIs and hardware in Dart/Flutter, auditing automated market maker contracts in Solidity, and engineering resilient microservices in NestJS and TypeScript.
When you switch between distinct programming paradigms—from memory-managed garbage-collected runtimes to deterministic EVM execution rings and Win32 C-bindings—clear architectural patterns begin to emerge.
In this retrospective, I want to share the mental models I use when architecting modern software systems.
1. Storage: When LSM-Trees (Pebble) Trump Relational SQL
Read/Write Trade-off Curve
Heavy Writes / Sequential IO Complex Relations / Ad-hoc Queries
<------------------------------------------------------------------------------------------->
Pebble (LSM-Tree) Redis (In-Memory) PostgreSQL (B-Tree)
- Append WAL - Sub-ms Key lookups - Foreign Keys
- Compaction - PubSub / Cluster Locks - Multi-table JOINs
- Prefix Scans - Memory-bound - ACID Compliance
- Use Pebble when: You have high-frequency sensor or coordinate ingestions where disk bandwidth is the primary constraint. Appending to MemTables and background SSTable compactions will beat B-Tree page splits by an order of magnitude.
- Use PostgreSQL when: You have relational joins, multi-entity transactions, and audit ledgers that require rock-solid relational integrity.
- Use Redis when: You need atomic cluster-wide coordination (distributed semaphores, rate limit token buckets, and pub/sub notifications).
2. Network Protocols: JSON REST vs. gRPC Protobuf
For external developer interfaces and public web clients, REST is still king for ergonomics and inspectability. But for internal service meshes and real-time client sync:
[!TIP] Protobuf binary serialization is not just faster to encode/decode; it eliminates payload parsing ambiguity and generates strictly typed client SDKs across Go, Dart, and TypeScript automatically.
| Dimension | REST over HTTP/1.1 | gRPC over HTTP/2 |
|---|---|---|
| Payload Framing | Text-based JSON | Compressed Protobuf Binary |
| Connection Lifecycle | Frequent TCP renegotiations | Multiplexed Single TCP Stream |
| Streaming Support | SSE / Polling | Full Bidirectional Streaming |
| CPU Serialization Cost | High (String escaping & parsing) | Low (Zero-copy byte shifting) |
3. Trust Models: Decentralized State (Solidity) vs. Centralized State (Postgres)
In Web3 systems, every single storage write costs real gas money. This forces an extreme discipline in state minimization:
- Never store what you can compute off-chain.
- Rely on event logs (
indexedtopics) for historical queries. - Keep execution paths strictly deterministic and constant-time where possible.
Bringing this minimalist ethos back to Web2 microservice design dramatically simplifies systems, reduces database bloat, and makes debugging straightforward.
Final Thoughts
The best technology stack is never dogmatic. Great software comes from selecting the simplest primitive that satisfies the latency, throughput, and reliability constraints of the problem at hand.