Field notes — essays & research notes

Things I've written down.

Ruby, Rails, performance, security and applied machine learning. Updated when something feels finished.

31 posts in Ruby & Rails
RUBY & RAILS 08 / 13 / 26

The callback that fires in a test you didn't write

Active Record callbacks are convenient until a fixture, a seed script or a bulk import triggers side effects nobody expected.

3 min
RUBY & RAILS 08 / 11 / 26

Indexes that earn their keep

Adding an index is the reflex fix for a slow query. Column order, cardinality and write cost decide whether it does anything at all.

3 min
RUBY & RAILS 08 / 06 / 26

Fat models, skinny controllers, and the third option

Both halves of the old advice produce the same result at scale: one enormous class. Naming the operation is what actually helps.

2 min
RUBY & RAILS 08 / 04 / 26

Three threads, not five: what the GVL actually costs you

Rails ships a default most people never revisit. Here's how CRuby's global lock decides your thread count for you, and the arithmetic for picking workers.

5 min
RUBY & RAILS 07 / 31 / 26

SQLite in production, honestly

It is a real option for real applications now — with one constraint that decides your entire deployment shape.

2 min
RUBY & RAILS 07 / 29 / 26

Four caches, and knowing which one you need

HTTP, fragment, low-level and query caching solve different problems. Reaching for the wrong one hides the bug instead of fixing it.

3 min
RUBY & RAILS 07 / 22 / 26

Where Rails memory actually goes

Your app is not leaking. Ruby freed the memory and the allocator kept it. Arenas, fragmentation, and the two environment variables that fix most of it.

4 min
RUBY & RAILS 07 / 15 / 26

Your connection pool is probably wrong in one of two directions

ActiveRecord::ConnectionTimeoutError and "too many connections" are the same mistake made in opposite directions. The arithmetic is simple.

3 min
RUBY & RAILS 07 / 08 / 26

What belongs in a job, and what belongs in the request

Moving work to a background job doesn't make it faster. It moves who waits, and sometimes that's the wrong trade.

3 min