ruby 15 lines · 1 tab

Fragment caching for expensive JSON serialization

Alex Kumar Jan 2026
1 tab
json.array! @posts do |post|
  json.cache! ['v1', post], expires_in: 1.hour do
    json.id post.id
    json.title post.title
    json.excerpt post.excerpt
    json.published_at post.published_at
    json.author do
      json.id post.author.id
      json.name post.author.name
      json.avatar_url post.author.avatar_url
    end
    json.comments_count post.comments_count
    json.likes_count post.likes_count
  end
end
1 file · ruby Explain with highlit

Serializing complex ActiveRecord objects to JSON can consume significant CPU time, especially when rendering collections with nested associations. Fragment caching stores rendered JSON fragments in Redis keyed by a cache key that includes the record's cache_key_with_version, which automatically invalidates when the record updates. This approach delivers massive performance gains for read-heavy endpoints—instead of serializing hundreds of records on every request, I serve cached fragments and only serialize changed records. The cache key must include all dependencies, so I use touch: true on associations to invalidate parent caches when children change. For endpoints with heavy traffic, this can reduce response times from seconds to milliseconds.


Related snips

ruby
class CommentsController < ApplicationController
  before_action :set_post

  def create
    @comment = @post.comments.build(comment_params)

System test: asserting Turbo Stream responses

rails hotwire turbo
by codesnips 4 tabs
ruby
class Post < ApplicationRecord
  belongs_to :author, class_name: 'User'
  has_many :comments, dependent: :destroy

  scope :published, -> { where.not(published_at: nil).where('published_at <= ?', Time.current) }
  scope :draft, -> { where(published_at: nil) }

ActiveRecord scopes for reusable query logic

rails activerecord patterns
by Alex Kumar 1 tab
ruby
module Api
  module V1
    class UsersController < BaseController
      def show
        user = User.includes(:profile).find(params[:id])

ETags for conditional requests and caching

rails caching http-caching
by Alex Kumar 1 tab
ruby
class PostsController < ApplicationController
  def index
    @posts = Post.includes(:author)
                 .order(created_at: :desc)
                 .page(params[:page])
                 .per(10)

Turbo Frames: infinite scroll with lazy-loading frame

rails turbo hotwire
by codesnips 4 tabs
ruby
require "csv"

class PeopleCsvStream
  include Enumerable

  HEADERS = %w[id full_name email signed_up_at plan].freeze

Resilient CSV Export as a Streamed Response

rails performance streaming
by codesnips 3 tabs
erb
<form data-controller="query-sync" data-action="change->query-sync#apply">
  <select name="status" class="rounded border p-2">
    <option value="">Any</option>
    <option value="open">Open</option>
    <option value="closed">Closed</option>
  </select>

Filter UI that syncs query params via Stimulus (no front-end router)

rails hotwire stimulus
by Henry Kim 2 tabs

Share this code

Here's the card — post it anywhere.

Fragment caching for expensive JSON serialization — share card
Link copied