Chapter 9

The Performance Lie

Your cache is solving a problem your architecture created.
Demo 1: The Circular Argument: why caching never ends
Objects are slow
Add cache
Stale data
Add invalidation
Complexity
Thundering herd
Loop
0
The cycle never breaks. The cache creates the problem it solves.
Demo 2: Object graph + cache vs flat SQL query: nanoseconds
☠ ORM + cache layer
Request arrives 41ns
Check cache key 41ns
Cache MISS 41ns
Load Customer object 41ns
↳ pointer chase → Orders 41ns
↳ pointer chase → LineItems 42ns
↳ pointer chase → Addresses 41ns
Assemble response DTO 83ns
Store in cache 42ns
Return response 41ns
✦ Flat SQL query
Request arrives 41ns
SELECT ... JOIN ... 84ns
Return dict 41ns
0
Nanoseconds (ORM + cache)
0
Nanoseconds (flat query)

What you just saw

Demo 1: The caching circular argument. Objects scatter data across the heap. The scattered data is slow to traverse. A cache compensates for the slowness. The cache serves stale data. Invalidation logic adds complexity. The complexity creates thundering herd problems. The system is slow again. Add more cache. The cycle never breaks because the cache is solving a problem the architecture created.

Demo 2: A flat SQL query returns the same data in 166 nanoseconds that the ORM + cache layer returns in 454 nanoseconds. The query planner optimizes the join. The data comes back contiguous. No pointer chases. No cache checks. No stale data. No invalidation logic. The "performance optimization" (caching) is 2.7× slower than the simple alternative (a query).

The cache was never a performance optimization. It was a compensation for an architecture that scattered data across the heap. A flat data structure eliminates the scatter, which eliminates the need for the cache, which eliminates the invalidation logic, the stale data bugs, and the thundering herd problems. The simplest solution is also the fastest.

How this works: This demo visualizes the execution difference between dishonest and honest code. Timing is proportional to real captured nanosecond costs. Instrumented source code, Dockerfile, and raw trace data: github.com/adamzwasserman/honest-code-traces
← Ch.8: Let It Crash Ch.10: Testing Honest Code →