unkletayo.dev
Essays / Why I Take Software Apart: Learning from First Principles

Why I Take Software Apart: Learning from First Principles

Adetayo Akinsanya (unkletayo) • 2026-09-05 • 2 min read

It is easy to spend an entire software career as a consumer of abstractions.

You install an npm package, import a Spring annotation, paste a Dockerfile snippet, and move on. As long as the happy path holds, you can ship features quickly without ever knowing what the machine is actually doing underneath.

Then production throws an edge case.

A React component stutters because a V8 garbage collection cycle pauses the main thread long enough to drop frames. A container gets abruptly killed with exit code 137 because the JVM heap size wasn’t calibrated against cgroup v2 memory limits. A microservice deadlocks because two database transactions acquired row locks in reverse order.

In those moments, the abstractions vanish. The framework documentation can’t save you because the problem isn’t inside the framework; it’s happening in the operating system, the runtime memory model, or the network socket buffer.


What First-Principles Engineering Actually Means

To me, first-principles thinking in engineering isn’t an academic exercise. It’s asking the mechanical question before reaching for a tool:

  • Instead of asking “Which state library is trending?”, asking “How does the browser event loop schedule microtasks against layout and GPU composite passes?”
  • Instead of asking “Why is Docker slow?”, asking “How does OverlayFS traverse directory layers when a process issues a write syscall?”

When you understand the byte layout of an array or how an OS kernel schedules threads across CPU cores, modern frameworks stop feeling like mysterious black boxes. You start seeing them for what they actually are: pragmatic collections of trade-offs made by engineers dealing with the exact same physical constraints.


Why I Write Publicly

This site is my notebook. When I study how V8 compiles bytecodes, how Kafka achieves zero-copy I/O with sendfile, or why ArrayList grows its internal array by half each time it fills, writing it down forces me to test whether I understand it or if I’m just nodding along with documentation.

If you can’t explain the failure modes in plain code, you don’t understand the abstraction yet.

💬 Discussion & Thoughts

Have reflections or want to discuss this essay? Reach out directly: