{"id":15064595,"url":"https://github.com/mezis/level2","last_synced_at":"2025-10-08T18:24:17.762Z","repository":{"id":56881030,"uuid":"60539347","full_name":"mezis/level2","owner":"mezis","description":"Multiple caching levels for Rails. Kinda like your CPU's L1/L2 caches.","archived":false,"fork":false,"pushed_at":"2023-07-26T13:53:03.000Z","size":28,"stargazers_count":19,"open_issues_count":2,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-30T06:57:27.121Z","etag":null,"topics":["activesupport","cache","gem","ruby","ruby-on-rails"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mezis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-06T15:32:42.000Z","updated_at":"2024-09-30T23:00:32.000Z","dependencies_parsed_at":"2024-08-22T23:19:08.359Z","dependency_job_id":null,"html_url":"https://github.com/mezis/level2","commit_stats":{"total_commits":25,"total_committers":1,"mean_commits":25.0,"dds":0.0,"last_synced_commit":"ae0ae6fae2add370eae90e956a2f22faa5766cfc"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/mezis/level2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezis%2Flevel2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezis%2Flevel2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezis%2Flevel2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezis%2Flevel2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mezis","download_url":"https://codeload.github.com/mezis/level2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mezis%2Flevel2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273553213,"owners_count":25126058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activesupport","cache","gem","ruby","ruby-on-rails"],"created_at":"2024-09-25T00:22:09.557Z","updated_at":"2025-10-08T18:24:12.705Z","avatar_url":"https://github.com/mezis.png","language":"Ruby","readme":"# Level2 [![Build Status](https://travis-ci.org/mezis/level2.svg)](https://travis-ci.org/mezis/level2) [![Gem Version](https://badge.fury.io/rb/level2.svg)](https://badge.fury.io/rb/level2)\n\nA gem for tiered Rails caching.\n\nThis lets you \"stack\" Rails caches: you can use a smaller, faster cache for the\nhotest cached items, and a larger, slower cache for more — mimicking how\nmicroprocessors commonly have a small, ultrafast L1 cache and slower L2 and L3\ncaches.\n\nA common idiom is to use Rails's\n[`memory_store`](http://guides.rubyonrails.org/caching_with_rails.html#activesupport-cache-memorystore)\nas the first level, and\n[`mem_cache_store`](http://guides.rubyonrails.org/caching_with_rails.html#activesupport-cache-memcachestore)\nor\n[`redis_store`](https://github.com/redis-store/redis-store/wiki/Frameworks-Configuration)\nas the second.\n\nIf your production setup has multiple Ruby processes per server, and some free\nmemory on servers, it can be more sensible to run one `mem_cache_store` per\nserver plus a shared one.\n\n## Behaviour\n\n- When reading a cache key, try reading from the first level first, then go down\n  the list: if a key is in L1 and L2, the value in L1 will be returned —\n  honouring expiry.\n- Higher levels of cache are populated when reading: if a key is in L2 but not\n  L1, it will be added to L1.\n- When writing a key, it is written to all levels.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'level2'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install level2\n\n## Usage\n\nLevel2 is configured like any other Rails cache store. Its array of options are passed to\nthe same store lookup.\n\nExample:\n\n```ruby\n# in config/application.rb\n\nconfig.cache_store = :level2, {\n  L1: [ :memory_store, size: 32.megabytes ],\n  L2: [ :mem_cache_store, 'host1.example.org:11211' ]\n}\n```\n\nFrom thereon,\n\n- `Rails.cache.read` and `.fetch` will read from `L1` and fall back to `L2` if\n  the key is absent from `L1`.\n- On L1 misses and L2 hits, L1 will be populated.\n- `Rails.cache.write` and `.fetch` will write to both stores.\n\nWhile discouraged, it is possible to write directly to a given cache level:\n\n```ruby\nRails.cache.write('foo', 'bar', only: :L2)\n```\n\nThis can be useful in cases where `L1` is a non-shared cache (e.g. in-memory\ncache) and `L2` is shared (e.g. Redis, Memcached); and you want to keep the\nability to bust the cache manually.\n\n\n## Notifications\n\nLevel2 enriches\n[`ActiveSupport::Notifications`](http://edgeguides.rubyonrails.org/active_support_instrumentation.html#active-support).\n\nEvent payloads will include a `:level` field. On cache hits, this will indicate\nwhere the hit comes from; on misses, or any other event, the field may be\npresent but the value is unspecified.\n\nExample:\n\n```ruby\n# in an initializer\nActiveSupport::Notifications.subscribe 'cache_read.active_support' do |*args|\n  event = ActiveSupport::Notifications::Event.new(*args)\n  if event.payload[:hit]\n    Rails.logger.info \"Hit from #{event.payload[:level]}\"\n  end\nend\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run\n`rake spec` to run the tests. You can also run `bin/console` for an interactive\nprompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To\nrelease a new version, update the version number in `version.rb`, and then run\n`bundle exec rake release`, which will create a git tag for the version, push\ngit commits and tags, and push the `.gem` file to\n[rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at\nhttps://github.com/mezis/level2.\n\n\n## License\n\nThe gem is available as open source under the terms of the [MIT\nLicense](http://opensource.org/licenses/MIT).\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmezis%2Flevel2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmezis%2Flevel2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmezis%2Flevel2/lists"}