Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#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:

  1. A deployment check that the cache used in production is not locmemcache
  2. The default cache backend used in global_settings be changed to DummyCache

Since (2) is probably highly backwards incompatible, I think (1) is preferable.

Change History (10)

comment:1 by Adam Johnson, 7 years ago

Cc: me@… added

comment:2 by Tim Graham, 7 years ago

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.

comment:3 by Claude Paroz, 7 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 Aymeric Augustin, 7 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 Tim Graham, 7 years ago

Component: Core (Cache system)Documentation
Summary: Default CACHES uses Locmem which isn't suitable for productionDocument limitations of the Locmem cache backend
Triage Stage: UnreviewedAccepted

Some limitations are already documented in Local-memory caching.

comment:6 by Adam Johnson, 7 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 Aymeric Augustin, 7 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.

comment:8 by Tim Graham, 7 years ago

Has patch: set

PR from Adam.

comment:9 by Tim Graham <timograham@…>, 7 years ago

Resolution: fixed
Status: assignedclosed

In 755406f:

Fixed #27641 -- Doc'd default local-memory caching in deployment checklist.

comment:10 by Tim Graham <timograham@…>, 7 years ago

In f5e0e15e:

[1.10.x] Fixed #27641 -- Doc'd default local-memory caching in deployment checklist.

Backport of 755406f5ff888e91bacb26f63cbddf7c036793ca from master

Note: See TracTickets for help on using tickets.
Back to Top