#27641 closed Cleanup/optimization (fixed)
Document limitations of the Locmem cache backend
Reported by: | Adam Johnson | Owned by: | Adam Johnson |
---|---|---|---|
Component: | Documentation | Version: | 1.10 |
Severity: | Normal | Keywords: | |
Cc: | me@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The default CACHES that Django uses is defined in global_settings
as:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } }
Django also enforces that you have a cache called 'default' defined: https://docs.djangoproject.com/en/1.10/ref/checks/#caches
LocMemCache
only works within a single process and thus is not suitable for even the smallest application deployments these days, which nearly always use multiple web worker processes under uWSGI/gunicorn. (For example, this uWSGI Heroku tutorial has config for 4 processes).
The way Django uses caching is to assume there's a single cache for the whole application which could lead code to break in unexpected ways in production.
I'd like to suggest either:
- A deployment check that the cache used in production is not locmemcache
- The default cache backend used in
global_settings
be changed toDummyCache
Since (2) is probably highly backwards incompatible, I think (1) is preferable.
Change History (10)
comment:1 by , 8 years ago
Cc: | added |
---|
comment:2 by , 8 years ago
comment:3 by , 8 years ago
I do agree with Tim. I'm deploying many small single-process apps using Apache/mod_wsgi and I *think* using locmem cache is fine (even if I'm using memcache in several of these instances).
comment:4 by , 8 years ago
The way Django uses caching is to assume there's a single cache for the whole application
This is correct, hovewer, considering the contract of Django cache backends -- keys can be evicted arbitrarily -- I believe that in (most) (reasonable) cases the effect of separate workers using separate caches is lower performance (cache hits / N for N workers) and increased resource usage (memory * N for N workers). This is annoying but not always worth the effort of setting up or paying for a separate cache server. I have used the locmem cache successfully in production for modest optimizations such as template caching.
I'd rather handle this in the documentation.
One surprising and little know characteristic of the locmem cache backend is that it's bounded to 300 keys by default. Even for caching medium-size objects (let's say 8kB), that's quite low (limited to 2,4MB). I'm not sure the docs mention it sufficiently clearly. If we explain the downsides of using the locmem cache in production, it would be a good place to mention that this setting likely needs tuning.
comment:5 by , 8 years ago
Component: | Core (Cache system) → Documentation |
---|---|
Summary: | Default CACHES uses Locmem which isn't suitable for production → Document limitations of the Locmem cache backend |
Triage Stage: | Unreviewed → Accepted |
Some limitations are already documented in Local-memory caching.
comment:6 by , 8 years ago
considering the contract of Django cache backends -- keys can be evicted arbitrarily
The contract of cache.delete()
though is that the value is gone, but it can't be with per-process caches - that's the main confusion I'm worried about.
Actually thanks for linking Tim, the docs do already say quite a lot. The last paragraph makes it obvious that it's probably not suitable:
Note that each process will have its own private cache instance, which means no cross-process caching is possible. This obviously also means the local memory cache isn’t particularly memory-efficient, so it’s probably not a good choice for production environments. It’s nice for development.
My main concern is for projects that don't realize they're using caching and thus don't read the caching docs, that's why I suggested a deploy check since it's unavoidable. I think it would be best to include a bit more under the the `CACHES` section in the deployment checklist, and also a sentence about the low default size on the caching page.
comment:7 by , 8 years ago
Yes, while my argument seems correct for a single requests, separate caches could create incorrect results for sequences of requests.
Adding a link from the deployment checklist to the paragraph that describes the limitations sounds like a good idea.
I'm not sure about adding a system check which would require simple sites to silence that check if they don't care about caching. Maybe you can write to the DevelopersMailingList to get some other opinions. I think it might be enough to enhance the deployment checklist with a note about this issue.