Shopify/identity_cache
62.3
Adequate · 19 September 2026
3.1k
lines of production code
Ruby
primary language
1
measurement over time
What this system is
IdentityCache is a Ruby gem that provides high-performance caching for ActiveRecord models by storing associated records and attributes in Memcached. It supports complex association patterns, including recursive relationships and polymorphic references, while optimizing database load through batch fetching and lazy loading strategies. The system ensures cache consistency via deferred expiration hooks and handles thundering herd problems with locking mechanisms.
How it got here
2013 — IdentityCache v2.0 architectural rewrite
7 changes.
This period focused on the complete architectural rewrite of IdentityCache into version 2.0, introducing a modular design with new caching primitives, association handling, and consistency mechanisms. The work included establishing a robust development environment, expanding test coverage for core components, and adding performance benchmarking tools to validate the new implementation.
2015–2021 — caching architecture and test coverage
7 changes.
The project refactored caching internals into modular classes and added support for recursive associations and batch fetching to improve performance. This period also focused on expanding test coverage for these new components and establishing robust CI and local development environments to ensure compatibility across various dependency versions.
Features
Add local development environment configuration for Spin
This change introduces the \.spin\ directory to support the Spin local development environment. It includes a bootstrap script that installs system dependencies (libsasl2-dev, libpq-dev), initializes a MySQL database for testing, and runs bundle install, alongside a service configuration file that defines Memcached and MySQL as required backend services.
.spin · high confidence
Add performance benchmarking and profiling scripts
New scripts have been added to the \performance/\ directory to measure and analyze the library's runtime behavior. \cpu.rb\ provides basic CPU time benchmarking across various cache runner scenarios (find, fetch hit/miss, deleted), while \profile.rb\ leverages \stackprof\ to generate detailed CPU profiles, including the ability to target specific runners via environment variables. Additionally, \externals.rb\ uses \ruby-prof\ to count external calls to Memcache and the database, helping users understand the overhead of different caching strategies.
performance · high confidence
Initial project scaffolding and development environment setup
This change introduces the foundational configuration and documentation for the IdentityCache gem, establishing the development workflow and project standards. It sets the development Ruby version to 3.3.4 via \.ruby-version\ and configures code style enforcement using RuboCop with the \rubocop-shopify\ gem. A \dev.yml\ file is added to streamline local environment setup, providing commands for running tests across multiple dependency configurations (default, minimum supported, latest release, and Rails edge), executing style checks, and running CPU benchmarks or profiling. The project also includes a \CAVEATS.md\ document to warn users about potential issues such as large cache blobs, hot keys, and the thundering herd problem, alongside a comprehensive \README.md\ detailing installation, usage, and configuration for Memcached backends.
(repo-wide) · high confidence
Support for cached recursive associations
The library now supports caching for recursive associations (e.g., a model referencing itself). This is implemented by introducing a new \IdentityCache::Cached::Recursive::Association\ class that handles the reading, writing, and hydration of self-referential cached data, along with specific \HasMany\ and \HasOne\ subclasses to manage these relationships within the caching layer.
_lib/identity\cache/cached/recursive · high confidence
Behavioural changes
Cached reference associations now support batch fetching
The \IdentityCache::Cached::Reference\ module for \has\_many\ and \has\_one\ associations has been refactored to implement batch fetching. Instead of loading associated records individually, the library now uses \fetch\_multi\ to load multiple records in a single operation, which improves performance when accessing cached associations. This change introduces new internal methods for managing cached IDs and records, and ensures that pre-fetched or embedded associations are handled correctly without redundant cache lookups.
_lib/identity\cache/cached/reference · high confidence
IdentityCache v2.0: Complete architectural rewrite with new caching primitives
IdentityCache has been completely rewritten from scratch, replacing the previous implementation with a new modular architecture. This version introduces a new \CacheFetcher\ interface that supports both optimistic locking (CAS) and a \FallbackFetcher\ for backends without CAS support, along with a \FillLock\ mechanism to prevent thundering herd problems. The association caching API has been restructured into distinct classes (\Cached::BelongsTo\, \Cached::Reference::HasMany\, etc.) and now supports recursive embedding and ID-based embedding. A new \CacheKeyLoader\ and \LoadStrategy\ system (Eager/Lazy) manages batch loading and memoization, while \CacheInvalidation\ and \ParentModelExpiration\ handle cache consistency with deferred expiry hooks. The gem also adds \MemCacheStoreCAS\ patching for Dalli, \CacheHash\ for optimized key hashing, and an \Encoder\ with ActiveSupport::Notifications for hydration/dehydration events.
_lib/identity\cache · high confidence
Refactored caching architecture and updated error handling
The library has been restructured to replace the monolithic \lib/identity\_cache.rb\ with a modular design featuring separate files for caching strategies, associations, and key generation. The \MemoizedCacheProxy\ and \BelongsToCaching\ modules have been moved into the new namespace structure. Additionally, the \AlreadyIncludedError\ class has been changed from inheriting from \Exception\ to \StandardError\, which improves safety by preventing accidental interruption of system-level exceptions.
lib · high confidence
Refactored caching internals into dedicated classes for associations, attributes, and indexes
The caching logic in \lib/identity\_cache/cached\ has been reorganized into specific classes (\Cached::Association\, \Cached::Attribute\, \Cached::PrimaryIndex\, etc.) to improve modularity. This change introduces a new \Cached::Prefetcher\ module that handles association loading, including support for the Rails 7.0 preloader API and batch fetching for polymorphic \belongs\_to\ associations. It also adds deferred expiration for records and attributes to reduce blocking during writes, and optimizes database queries for cached attributes by grouping common conditions.
_lib/identity\cache/cached · high confidence
Test coverage
8 commits adding/updating tests in test/fixtures; Added test coverage for IdentityCache core components; Added unit tests for cached association classes; Expanded test infrastructure with multi-database support and new fixtures.
Dependencies
New CI gemfiles for latest release, minimum supported, and Rails edge versions
The project now includes three dedicated Gemfiles to streamline testing across different dependency configurations: \Gemfile.latest-release\ pins development tools like Rubocop and uses the latest released versions of ActiveRecord and database drivers; \Gemfile.min-supported\ enforces the minimum supported versions for ActiveRecord (7.0.0) and other dependencies like memcached\_store and dalli; and \Gemfile.rails-edge\ tests against the main branch of the Rails repository. These files allow the CI pipeline to explicitly validate compatibility with the newest releases, the oldest supported versions, and upcoming Rails changes.
gemfiles · high confidence
Update dependencies and drop support for older Ruby and Rails versions
The gem now requires Ruby 3.0+ and Active Record 7.0+, removing support for older versions. Development dependencies have been updated, including RuboCop to 1.61 and rubocop-shopify to 2.9, while runtime dependencies like ar\_transaction\_changes are bumped to 1.1. The gemspec has been modernized with improved metadata and author information.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 62.
Lenses
- Code Health 99
- Architecture 100
- Maturity 50
- Readiness 67
- Security 65
Changes since last survey
- 300 commits — 243 feature/other, 57 fixes
By area
- (root) — 96 commits
- (repo) — 78 commits
- lib/identity_cache — 53 commits
- .github/workflows — 16 commits
- test/fetch_multi_by_test.rb — 7 commits
- test/helpers — 7 commits
- test/test_helper.rb — 7 commits
- lib/identity_cache.rb — 6 commits
- test/fetch_test.rb — 6 commits
- test/cache_invalidation_test.rb — 5 commits
- test/cache_fetcher_test.rb — 2 commits
- test/identity_cache_test.rb — 2 commits
- test/index_cache_test.rb — 2 commits
- test/prefetch_associations_test.rb — 2 commits
- .github/dependabot.yml — 1 commit
- .github/probots.yml — 1 commit
- gemfiles/Gemfile.min-supported — 1 commit
- gemfiles/Gemfile.rails-edge — 1 commit
- performance/cache_runner.rb — 1 commit
- test/attribute_cache_test.rb — 1 commit
Notable commits
- fix: Avoid rubocop errors by skipping the version of rubocop with a bug (#496)
- fix: Bump bugfix version of ruby in dev.yml
- fix: CI: Use ruby/setup-ruby to fix testing of ruby 3.0 (#487)
- fix: Fix Active Record 7.2 deprecation warnings
- fix: Fix Active Record's connection_pool_list deprecation warning
- fix: Fix ActiveRecord::Associations::Preloader#preload call on rails edge (#478)
- fix: Fix Naming/InclusiveLanguage rubocop offenses
- fix: Fix Style/ParallelAssignment
- fix: Fix Style/PreferredHashMethods
- fix: Fix Style/RedundantReturn
- fix: Fix Style/SafeNavigation
- fix: Fix Style/SpecialGlobalVars
- fix: Fix Style/SymbolProc
- fix: Fix Style/TrailingCommaInArrayLiteral
- fix: Fix Style/TrailingCommaInHashLiteral
- fix: Fix Style/ZeroLengthPredicate
- fix: Fix IdentityCache.fetch_read_only_records default value
- fix: Fix another Active Record deprecation
- fix: Fix broken prefetch_associations of a polymorphic cache_belongs_to (#461)
- fix: Fix class name in AssociationError message (#557)
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Shopify/identity_cache was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 9b6db8c06b7abd49c23d5cb3dd45489725f19820 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.