- stevencodes.swe
- Posts
- stevencodes.swe - September 28, 2025
stevencodes.swe - September 28, 2025
Book updates, weekly video highlight, book snippet
👋 Hi friends,
Here’s what I’ve got for you this week:
Book Updates
A snippet from The Backend Lowdown
Weekly video highlight: Cache Key Design
Let’s get into it 👇
Book Updates - Chapter 4 Released, EPUB Format
Chapter 4 is finally out! This chapter is 40 pages long and brings the book up to a whopping 115 pages of high-value content. Chapter 4 is all about caching strategies and their various pitfalls. It skips over talking about what a cache is and opinions behind where caching can/should be used and jumps right into app-level caching patterns, when these can be helpful, and things to look out for when using them. As mentioned before, with the book reaching more than 100 pages, the price is now $5 PWYW. Additionally, as requested, an EPUB format is now available. Please check it out and let me know what you think!
The Backend Lowdown: Chapter 4 Preview
Every newsletter will include a snippet from my book in progress, The Backend Lowdown, available for $5 right now on Gumroad!
Get The Backend Lowdown →
Sequence diagram part 1

Sequence diagram part 2 (it’s long, okay?)
Write Through
Write-through is when you successfully write data to your database, you also immediately update the cache with the new value. This means subsequent reads will find fresh data in the cache right away: users see their changes instantly without waiting for the old cached value to expire.
When it helps
Users need to see their own changes immediately (think profile updates, settings changes, feature toggles)
You have hot objects that are read frequently but written to occasionally
You can afford a small amount of extra latency on writes (to update both database and cache)
class ProductsController < ApplicationController
def update
product = Product.find(params[:id])
Product.transaction do
product.update!(product_params)
end
write_through_cache(product) # User sees their changes immediately
head :no_content
end
private
def write_through_cache(product)
# Same key structure as your cache-aside reads
key = "v3:product:#{product.id}:#{I18n.locale}"
payload = ProductPresenter.new(product, locale: I18n.locale).as_json # Lean DTO, not full ORM object
ttl = 10.minutes + rand(0..30).seconds # Jitter prevents synchronized expiry
# Best-effort: cache failure shouldn't break the user's save
Rails.cache.write(key, payload, expires_in: ttl)
rescue => e
Rails.logger.warn("cache.write failed for #{key}: #{e.class}: #{e.message}")
# Optional: Queue a repair job if consistency is critical
# RepairCacheJob.perform_later(product.id, I18n.locale)
end
def product_params
params.require(:product).permit(:name, :price_cents, :description)
end
endTripwires
Making cache critical for writes: If your cache goes down and takes your entire write path with it, you've built a fragile system. Always use timeouts and treat cache updates as best-effort: log failures but let the write succeed.
Inconsistent freshness: You updated the product in cache, but the category page still shows old data. Write-through only updates individual entities. You need to separately handle any lists, search results, or aggregates that include this data.
Cache/read mismatch: If you cache raw database records but your reads expect a formatted presenter object, you'll get errors. Always cache the exact same data structure that your read path expects to find.
Overusing write-through: Adding cache updates to every single write operation adds latency for no benefit. Most writes don't need immediate consistency. Save write-through for the places where users truly need to see their changes instantly.
Weekly Video Highlight: Cache Key Design
This week I posted a video about something straight out of Chapter 4: cache key design. It’s something I found interesting when I first encountered it. Here are the four rules I use:
Include every input that affects output: feature flags, locale, user/role, pagination, query params… include all of it.
Stabilize inputs
Sort arrays and params, trim/case-normalize strings, set explicit defaults.Version your shape
AddvNwhen response structure or semantics change to invalidate safely.Keep it small, safe, debuggable
Human-readable prefix + short hash. No PII. Keep under a few hundred bytes.
Pattern:<ns>:<resource>:<scope>:v2:<normalized-input-hash>
Example: feed:user:42:v2:en:7f9a3c
Some common misses: forgetting locale/role/feature flags, unsorted filters, and silent shape changes.
If your keys follow these four rules, your cache will be faster and more honest.
Watch the video here:
@stevencodes.swe Your cache keys are broken. Here are 4 cache key rules that will help fix them. #techtok #coding #programming #software
That’s a wrap for this week. If something here made your day smoother, feel free to reply and tell me about it. And if you think a friend or teammate would enjoy this too, I’d be grateful if you shared it with them.
Until next time,
Steven


