Why I’m writing this
I’m a software engineer. Most of my career so far has been spent building web applications, largely with Ruby on Rails, in environments that value speed, convenience, and developer productivity.
For a long time, that felt sufficient. Frameworks helped me move fast. They gave me clear structures, familiar patterns, and a sense that I knew what was going on. Most of the complexity was handled for me, and I didn’t really question that.
At some point, though, that stopped feeling enough.
The systems I was building worked, but my understanding of them felt incomplete in certain situations. I could explain the code paths, but not always what was happening once the system was running. I was comfortable thinking in terms of requests, responses, controllers, and services, but much less comfortable explaining things like retries, background work, partial failures, or why something behaved differently after a restart.
When production issues happened, the answers were often outside the parts of the system I was used to thinking about.
That’s when I started noticing how much modern frameworks quietly take off your plate. Not in a bad way. They’re designed to make development accessible and efficient. But they also hide a lot of how software actually behaves over time. And if you never look behind that curtain, you never really build intuition for it.
What I’m aiming for (and what I’m not)
I’m not trying to jump titles or claim expertise I don’t have.
I want to grow into someone who can think about software as something that runs over time, under constraints, and in the presence of failure and uncertainty. Someone who understands abstractions instead of just relying on them. Someone who designs systems with execution in mind, not just structure.
Before moving further in that direction, I want to slow down and make sure I actually understand the basics that everything else is built on.
This site is my way of doing that deliberately.
Why start with terms
A lot of discussions around system design and architecture assume a shared understanding of certain words. In practice, that understanding is often fuzzy.
I’ve noticed that when I feel least confident in production situations, it’s usually because I’m missing clarity around basic terms. Things like what exactly is running, what state it’s in, what happens when something fails halfway through, or what assumptions the system makes about time and communication.
So instead of jumping straight into higher-level architecture topics, I want to start by grounding myself in the vocabulary that describes how software actually behaves once it’s running.
This list is a baseline for that.
Baseline checklist
Checked items mean I’m comfortable explaining the term in my own words and recognizing it when it shows up in real systems. I will also add a post on this topic in the terms library page.
This list is intentionally broad. It’s not a plan or a syllabus. It’s a way to make sure I’m not skipping over important pieces of reality just because a framework made them feel invisible.
Computation and program artifacts
- machine instruction
- program
- source code
- compilation
- linking
- binary
- executable
- runtime
- runtime environment
- interpreter
- JIT compilation
- AOT compilation
Operating system basics
- operating system
- kernel
- user space
- system call
- isolation
- process
Process lifecycle
- process lifecycle
- process start
- exit code
- crash
- signal
- graceful shutdown
- forced shutdown
Scheduling and execution
- scheduling
- context switch
- preemption
- CPU-bound work
- I/O-bound work
Threads and concurrency
- thread
- concurrency
- parallelism
- shared mutable state
- race condition
- deadlock
Asynchronous execution
- blocking I/O
- non-blocking I/O
- event loop
- callback
- future
- promise
- backpressure
Memory and resources
- virtual memory
- stack
- heap
- garbage collection
- memory leak
- resource exhaustion
Time
- wall-clock time
- monotonic time
- latency
- throughput
- timeout
- deadline
- ordering
- causality
State
- state
- stateless vs stateful
- in-memory state
- persisted state
- derived state
- source of truth
- state machine
- invariant
- idempotency
Failure and recovery
- error vs failure
- partial failure
- retry
- backoff
- circuit breaker
- graceful degradation
- recovery
Communication and distribution
- message
- request-response
- asynchronous messaging
- latency
- message loss
- message duplication
- partition
Interfaces and protocols
- interface
- contract
- protocol
- schema
- serialization
- versioning
- backward compatibility
Data and storage
- database
- transaction
- isolation level
- durability
- write-ahead log
- replay
Observability
- observability
- logging
- metrics
- tracing
- health check
Design and architecture vocabulary
- cohesion
- coupling
- boundary
- component
- service
- failure domain
- scalability
How I’ll use this list
I’ll revisit this checklist periodically and update it as my understanding changes. For now I’ve used GPT to generate me the list of the terms I should know.
When something moves from unchecked to checked, it won’t be because I’ve memorized a definition or seen it mentioned in a talk. It’ll be because I feel more comfortable explaining it in my own words and recognizing it when it shows up in real systems I work on.