docs/guide/cached-props.md
@available_since rails=3.21.0
Cached props use your server-side cache store to avoid recomputing expensive data on every request. When the cache is warm, the block is never evaluated — Inertia serves the pre-serialized JSON directly.
[!NOTE] To understand when to use cached props vs once props vs HTTP caching, see the Caching guide.
To create a cached prop, use the InertiaRails.cache method. This method requires a cache key and a block that returns the prop data.
class DashboardController < ApplicationController
def index
render inertia: {
stats: InertiaRails.cache('dashboard_stats', expires_in: 1.hour) { Stats.compute },
}
end
end
On the first request, the block is evaluated, serialized to JSON, and written to the cache. Subsequent requests serve the cached JSON without evaluating the block.
Cache keys determine when cached data is invalidated. Inertia supports several key formats.
The simplest form — a static string:
InertiaRails.cache('sidebar_nav') { NavigationItem.tree }
Pass an Active Record object to derive the key from cache_key_with_version. The cache is automatically invalidated when the record is updated:
InertiaRails.cache(@post) { PostSerializer.render(@post) }
# Cache key: "inertia_rails/posts/1-20260410120000"
Pass an array to build a composite key:
InertiaRails.cache(['stats', current_user.id]) { Stats.for(current_user) }
# Cache key: "inertia_rails/stats/42"
You can pass expires_in and race_condition_ttl options to control cache behavior:
InertiaRails.cache('stats', expires_in: 1.hour) { Stats.compute }
InertiaRails.cache('stats', expires_in: 1.hour, race_condition_ttl: 10.seconds) { Stats.compute }
The cache option can be passed to deferred and optional props:
class DashboardController < ApplicationController
def index
render inertia: {
# Deferred prop with caching
feed: InertiaRails.defer(cache: { key: 'feed', expires_in: 5.minutes }, group: 'feed') { current_user.feed },
# Optional prop with caching
categories: InertiaRails.optional(cache: @team) { @team.categories },
}
end
end
The cache option accepts the same key formats as InertiaRails.cache: strings, Active Record objects, arrays, and hashes with options.
InertiaRails.defer(cache: { key: 'feed', expires_in: 5.minutes }) { current_user.feed }
By default, Inertia uses Rails.cache. You can configure a different store via the cache_store option. All cached prop keys are automatically prefixed with inertia_rails/ to avoid collisions.
For more information on configuring cache stores, cache key strategies, and expiration policies, see the Rails low-level caching guide.