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

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.

DimensionREST over HTTP/1.1gRPC over HTTP/2
Payload FramingText-based JSONCompressed Protobuf Binary
Connection LifecycleFrequent TCP renegotiationsMultiplexed Single TCP Stream
Streaming SupportSSE / PollingFull Bidirectional Streaming
CPU Serialization CostHigh (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 (indexed topics) 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.

DX

Written by DX

Systems Engineer • Focused on high-performance distributed systems, low-level OS internals, and financial engineering.

← Back to all archives