{"id":13415556,"url":"https://github.com/noripyt/django-cachalot","last_synced_at":"2026-03-27T02:44:24.684Z","repository":{"id":21191297,"uuid":"24499768","full_name":"noripyt/django-cachalot","owner":"noripyt","description":"No effort, no worry, maximum performance.","archived":false,"fork":false,"pushed_at":"2026-01-27T17:57:54.000Z","size":1600,"stargazers_count":1406,"open_issues_count":27,"forks_count":156,"subscribers_count":25,"default_branch":"master","last_synced_at":"2026-01-27T20:14:09.465Z","etag":null,"topics":["cache","django","performance","python"],"latest_commit_sha":null,"homepage":"http://django-cachalot.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/noripyt.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2014-09-26T13:08:06.000Z","updated_at":"2026-01-27T17:57:59.000Z","dependencies_parsed_at":"2024-01-06T09:56:18.811Z","dependency_job_id":"bab5c0d1-4670-4622-ba13-d4e3f1e5b2a7","html_url":"https://github.com/noripyt/django-cachalot","commit_stats":{"total_commits":613,"total_committers":33,"mean_commits":"18.575757575757574","dds":"0.14029363784665583","last_synced_commit":"c955d1bbeefad4844a7728bf66ee1c9c6e64d3bf"},"previous_names":["bertrandbordage/django-cachalot"],"tags_count":51,"template":false,"template_full_name":null,"purl":"pkg:github/noripyt/django-cachalot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noripyt%2Fdjango-cachalot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noripyt%2Fdjango-cachalot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noripyt%2Fdjango-cachalot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noripyt%2Fdjango-cachalot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noripyt","download_url":"https://codeload.github.com/noripyt/django-cachalot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noripyt%2Fdjango-cachalot/sbom","scorecard":{"id":694291,"data":{"date":"2025-08-11","repo":{"name":"github.com/noripyt/django-cachalot","commit":"f5609f0e571bf85361f9796b1f2f709e192161d1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/main-ci.yml:1","Warn: no topLevel permission defined: .github/workflows/publish.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":5,"reason":"Found 16/30 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main-ci.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/main-ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main-ci.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/main-ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main-ci.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/main-ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/noripyt/django-cachalot/publish.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:81","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:82","Warn: pipCommand not pinned by hash: .github/workflows/main-ci.yml:67","Warn: pipCommand not pinned by hash: .github/workflows/main-ci.yml:68","Warn: pipCommand not pinned by hash: .github/workflows/publish.yml:23","Warn: pipCommand not pinned by hash: .github/workflows/publish.yml:24","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   6 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"42 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2014-5 / GHSA-296w-6qhq-gf92","Warn: Project is vulnerable to: PYSEC-2011-2 / GHSA-3jqw-crqj-w8qw","Warn: Project is vulnerable to: PYSEC-2012-3 / GHSA-59w8-4wm2-4xw8","Warn: Project is vulnerable to: PYSEC-2012-4 / GHSA-5h2q-4hrp-v9rr","Warn: Project is vulnerable to: PYSEC-2014-6 / GHSA-625g-gx8c-xcmg","Warn: Project is vulnerable to: PYSEC-2015-8 / GHSA-6565-fg86-6jcx","Warn: Project is vulnerable to: PYSEC-2021-98 / GHSA-68w8-qjq3-2gfm","Warn: Project is vulnerable to: PYSEC-2012-2 / GHSA-78vx-ggch-wghm","Warn: Project is vulnerable to: PYSEC-2015-9 / GHSA-7fq8-4pv5-5w5c","Warn: Project is vulnerable to: PYSEC-2015-4 / GHSA-7qfw-j7hp-v45g","Warn: Project is vulnerable to: PYSEC-2011-9 / GHSA-7wph-fc4w-wqp2","Warn: Project is vulnerable to: GHSA-7xr5-9hcq-chf9","Warn: Project is vulnerable to: PYSEC-2014-2 / GHSA-89hj-xfx5-7q66","Warn: Project is vulnerable to: GHSA-8x94-hmjh-97hq","Warn: Project is vulnerable to: PYSEC-2016-2 / GHSA-c8c8-9472-w52h","Warn: Project is vulnerable to: PYSEC-2016-3 / GHSA-crhm-qpjc-cm64","Warn: Project is vulnerable to: PYSEC-2014-4 / GHSA-f7cm-ccfp-3q4r","Warn: Project is vulnerable to: PYSEC-2016-16 / GHSA-fp6p-5xvw-m74f","Warn: Project is vulnerable to: PYSEC-2011-8 / GHSA-fwr5-q9rx-294f","Warn: Project is vulnerable to: PYSEC-2015-5 / GHSA-gv98-g628-m9x5","Warn: Project is vulnerable to: PYSEC-2015-20 / GHSA-h582-2pch-3xv3","Warn: Project is vulnerable to: PYSEC-2011-5 / GHSA-h95j-h2rv-qrg4","Warn: Project is vulnerable to: GHSA-hmr4-m2h5-33qx","Warn: Project is vulnerable to: PYSEC-2015-6 / GHSA-jhjg-w2cp-5j44","Warn: Project is vulnerable to: PYSEC-2016-15 / GHSA-pw27-w7w4-9qc7","Warn: Project is vulnerable to: PYSEC-2015-10 / GHSA-q5qw-4364-5hhm","Warn: Project is vulnerable to: PYSEC-2011-4 / GHSA-rm2j-x595-q9cj","Warn: Project is vulnerable to: GHSA-rrqc-c2jx-6jgv","Warn: Project is vulnerable to: PYSEC-2014-1 / GHSA-rvq6-mrpv-m6rm","Warn: Project is vulnerable to: PYSEC-2014-7 / GHSA-rw75-m7gp-92m3","Warn: Project is vulnerable to: PYSEC-2019-16 / GHSA-vfq6-hq5r-27r6","Warn: Project is vulnerable to: PYSEC-2014-3 / GHSA-wqjj-hx84-v449","Warn: Project is vulnerable to: PYSEC-2011-3 / GHSA-wxg3-mfph-qg9w","Warn: Project is vulnerable to: PYSEC-2011-1 / GHSA-x88j-93vc-wpmp","Warn: Project is vulnerable to: PYSEC-2007-1","Warn: Project is vulnerable to: PYSEC-2008-1","Warn: Project is vulnerable to: PYSEC-2008-2","Warn: Project is vulnerable to: PYSEC-2009-3","Warn: Project is vulnerable to: PYSEC-2015-11","Warn: Project is vulnerable to: PYSEC-2015-7","Warn: Project is vulnerable to: PYSEC-2016-18","Warn: Project is vulnerable to: PYSEC-2022-304"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T03:12:49.121Z","repository_id":21191297,"created_at":"2025-08-22T03:12:49.121Z","updated_at":"2025-08-22T03:12:49.121Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31011862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T02:33:22.146Z","status":"ssl_error","status_checked_at":"2026-03-27T02:33:21.763Z","response_time":164,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cache","django","performance","python"],"created_at":"2024-07-30T21:00:50.271Z","updated_at":"2026-03-27T02:44:24.670Z","avatar_url":"https://github.com/noripyt.png","language":"Python","funding_links":[],"categories":["Third-Party Packages","Python","Caching","Django Utilities","Caching \u0026 Performance"],"sub_categories":["Caching","Tools"],"readme":"Django Cachalot\n===============\n\nCaches your Django ORM queries and automatically invalidates them.\n\nDocumentation: http://django-cachalot.readthedocs.io\n\n----\n\n.. image:: http://img.shields.io/pypi/v/django-cachalot.svg?style=flat-square\u0026maxAge=3600\n   :target: https://pypi.python.org/pypi/django-cachalot\n\n.. image:: https://img.shields.io/pypi/pyversions/django-cachalot\n    :target: https://django-cachalot.readthedocs.io/en/latest/\n\n.. image:: https://github.com/noripyt/django-cachalot/actions/workflows/ci.yml/badge.svg\n   :target: https://github.com/noripyt/django-cachalot/actions/workflows/ci.yml\n\n.. image:: http://img.shields.io/coveralls/noripyt/django-cachalot/master.svg?style=flat-square\u0026maxAge=3600\n   :target: https://coveralls.io/r/noripyt/django-cachalot?branch=master\n\n.. image:: http://img.shields.io/scrutinizer/g/noripyt/django-cachalot/master.svg?style=flat-square\u0026maxAge=3600\n   :target: https://scrutinizer-ci.com/g/noripyt/django-cachalot/\n\n.. image:: https://img.shields.io/discord/773656139207802881\n    :target: https://discord.gg/WFGFBk8rSU\n\n----\n\nTable of Contents:\n\n- Quickstart\n- Usage\n- Hacking\n- Benchmark\n- Third-Party Cache Comparison\n- Discussion\n\nQuickstart\n----------\n\nCachalot officially supports Python 3.8-3.14 and Django 4.2, 5.2, 6.0 with the databases PostgreSQL, SQLite, and MySQL.\n\nNote: an upper limit on Django version is set for your safety. Please do not ignore it.\n\nUsage\n-----\n\n#. ``pip install django-cachalot``\n#. Add ``'cachalot',`` to your ``INSTALLED_APPS``\n#. If you use multiple servers with a common cache server,\n   `double check their clock synchronisation \u003chttps://django-cachalot.readthedocs.io/en/latest/limits.html#multiple-servers\u003e`_\n#. If you modify data outside Django\n   – typically after restoring a SQL database –,\n   use the `manage.py command \u003chttps://django-cachalot.readthedocs.io/en/latest/quickstart.html#command\u003e`_\n#. Be aware of `the few other limits \u003chttps://django-cachalot.readthedocs.io/en/latest/limits.html#limits\u003e`_\n#. If you use\n   `django-debug-toolbar \u003chttps://github.com/jazzband/django-debug-toolbar\u003e`_,\n   you can add ``'cachalot.panels.CachalotPanel',``\n   to your ``DEBUG_TOOLBAR_PANELS``\n#. Enjoy!\n\nHacking\n-------\n\nTo start developing, install the requirements\nand run the tests via tox.\n\nMake sure you have the following services:\n\n* Memcached\n* Redis\n* PostgreSQL\n* MySQL\n\nFor setup:\n\n#. Install: ``pip install -r requirements/hacking.txt``\n#. For PostgreSQL: ``CREATE ROLE cachalot LOGIN SUPERUSER;``\n#. Run: ``tox --current-env`` to run the test suite on your current Python version.\n#. You can also run specific databases and Django versions: ``tox -e py312-django5.2-postgresql-redis``\n\nBenchmark\n---------\n\nCurrently, benchmarks are supported on Linux and Mac/Darwin.\nYou will need a database called \"cachalot\" on MySQL and PostgreSQL.\nAdditionally, on PostgreSQL, you will need to create a role\ncalled \"cachalot.\" You can also run the benchmark, and it'll raise\nerrors with specific instructions for how to fix it.\n\n#. Install: ``pip install -r requirements/benchmark.txt``\n#. Run: ``python benchmark.py``\n\nThe output will be in benchmark/TODAY'S_DATE/\n\nTODO Create Docker-compose file to allow for easier running of data.\n\nThird-Party Cache Comparison\n----------------------------\n\nThere are three main third party caches: cachalot, cache-machine, and cache-ops. Which do you use? We suggest a mix:\n\nTL;DR Use cachalot for cold or modified \u003c50 times per minutes (Most people should stick with only cachalot since you\nmost likely won't need to scale to the point of needing cache-machine added to the bowl). If you're an enterprise that\nalready has huge statistics, then mixing cold caches for cachalot and your hot caches with cache-machine is the best\nmix. However, when performing joins with ``select_related`` and ``prefetch_related``, you can\nget a nearly 100x speed up for your initial deployment.\n\nRecall, cachalot caches THE ENTIRE TABLE. That's where its inefficiency stems from: if you keep updating the records,\nthen the cachalot constantly invalidates the table and re-caches. Luckily caching is very efficient, it's just the cache\ninvalidation part that kills all our systems. Look at Note 1 below to see how Reddit deals with it.\n\nCachalot is more-or-less intended for cold caches or \"just-right\" conditions. If you find a partition library for\nDjango (also authored but work-in-progress by `Andrew Chen Wang`_), then the caching will work better since sharding\nthe cold/accessed-the-least records aren't invalidated as much.\n\nCachalot is good when there are \u003c50 modifications per minute on a hot cached table. This is mostly due to cache invalidation. It's the same with any cache,\nwhich is why we suggest you use cache-machine for hot caches. Cache-machine caches individual objects, taking up more in the memory store but\ninvalidates those individual objects instead of the entire table like cachalot.\n\nYes, the bane of our entire existence lies in cache invalidation and naming variables. Why does cachalot suck when\nstuck with a huge table that's modified rapidly? Since you've mixed your cold (90% of) with your hot (10% of) records,\nyou're caching and invalidating an entire table. It's like trying to boil 1 ton of noodles inside ONE pot instead of\n100 pots boiling 1 ton of noodles. Which is more efficient? The splitting up of them.\n\nNote 1: My personal experience with caches stems from Reddit's: https://web.archive.org/web/20210803213621/https://redditblog.com/2017/01/17/caching-at-reddit/\n\nNote 2: Technical comparison: https://django-cachalot.readthedocs.io/en/latest/introduction.html#comparison-with-similar-tools\n\nDiscussion\n----------\n\nHelp? Technical chat? `It's here on Discord \u003chttps://discord.gg/WFGFBk8rSU\u003e`_.\n\nLegacy chats:\n\n- https://gitter.im/django-cachalot/Lobby\n- https://join.slack.com/t/cachalotdjango/shared_invite/zt-dd0tj27b-cIH6VlaSOjAWnTG~II5~qw\n\n.. _Andrew Chen Wang: https://github.com/Andrew-Chen-Wang\n\n.. image:: https://raw.github.com/noripyt/django-cachalot/master/django-cachalot.jpg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoripyt%2Fdjango-cachalot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoripyt%2Fdjango-cachalot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoripyt%2Fdjango-cachalot/lists"}