views:

699

answers:

7

I moved my first Django project from DjangoEurope to Webfaction, and that started an issue looking like a memory leak. With every single request memory usage of the server process goes up about 500kb. It never goes down. This goes on until Webfaction kills it for using too much memory.

I can clearly see this when I refresh the Django's admin interface in my browser (although this happens with every single page, not only with admin interface - I though admin interface would be a nice test case, because there are no my code directly there). With every browser reload the memory usage goes up couple hundreds kilobytes.

I test the memory using a command suggested by Webfaction:

ps -u publica -o rss,etime,pid,command

More about my setup:

  • Django 1.1 (stable)
  • Default Webfaction Django setup using Apache and mod_wsgi
  • DEBUG set to False
  • MySQLdb 1.2.2 from Webfaction, but after hearing it had some problems I tried version 1.2.3c. Didn't help.

Edit: I created an empty Django project - default Django configuration plus django.contrib.admin and fresh empty database (tried both with mysql and postgresql). I started reloading Django admin in my browser and watched memory usage. At first I saw the problem occurring - memory usage grew after every reload. But then it stabilized and stopped growing. That's consistant with how my original project behaved on Django Europe. Unfortunately on Webfaction it never seems to stabilize (or at least not within limits of memory available to my account). Any advice?

A: 

I have the same problems with webfaction.

The method I use, and which webfaction told me I should keep using, is run a cron job that checks the memory every 5 minutes or so, and restarts any apps that are getting out of control.

Out of 4 python apps on webfaction, I average 4 restarts per day.

Ryan Ginstrom
That sucks. On DjangoEurope everything worked fine. There have to be a real solution...
Ludwik Trammer
Sounds like something questionable with their environment if they're recommending to users to manually restart active processes.
jathanism
A: 

I've had issues with memory on Webfaction too - they didn't really crop up until I added my fifth application though. I tried a few tweaks to my apache configs, but what finally worked for me was just switching over to mod_wsgi.

barbara
I use mod_wsgi already :(
Ludwik Trammer
But are you using daemon mode of mod_wsgi, or are you trying to run everything in embedded mode of mod_wsgi? Even with WebFaction config keeping Apache server child processes down to 2, if using embedded mode will still take more memory than daemon mode with one process for Django instance.
Graham Dumpleton
@Graham - thanks. I upgraded mod_wsgi to 3.1 (from 2.5 provided by webfaction) and that seemed to help a little (for the first time I saw instances of memory usage actually going down a bit). Then I switched to a daemon mode, but haven't noticed much difference. I feel a little intimidated by the configuration options. I'e got my `ServerLimit` set to "2", `MaxRequestsPerChild` to "500", `WSGIDaemonProcess` to "[mydomain] processes=2 inactivity-timeout=1800 threads=15" and `WSGIRestrictEmbedded` turned on. Does this configuration make sense?
Ludwik Trammer
Oh, and could you post your suggestion about running in a daemon mode as separate answer (possibly with an example of sane values for configuration options)? I think it's the best answer so far and it's a shame it's buried in comments.
Ludwik Trammer
A: 
ClaudioA
I did start by carefully analyzing those tips. I do serve static files they way it is recommended (I checked at least five times during past two days ;]). I didn't know about the script. Thanks.
Ludwik Trammer
If you just have one application running, it's pretty easy to avoid problems. I think that they actually do restart your app every once in a while anyway. But when you get four apps in a single account, then it's pretty easy to start hitting your limit -- especially when webfaction is stingy with memory, and won't let you buy more than 240 MB or so per account.
Ryan Ginstrom
Mm.. didn't know that webfaction was limiting the memory that you can buy... thanks.
ClaudioA
+1  A: 

I'd suggest not to guess.

Take a look at http://code.google.com/p/django-dowser/, it is a very useful app for detecting memory leaks and figuring out what parts of your code are responsible for memory consumption.

Mike Korobov
A: 

Are both mod_python and mod_wsgi modules loaded into apache?

I know mod_wsgi doesn't like having mod_python in its building. Check its not loaded.

John Mee
One can use mod_python and mod_wsgi together fine, it isn't that mod_wsgi doesn't like it. You just loose a few configuration options for mod_wsgi as mod_python is responsible for initialisating Python, not mod_wsgi. Also, mod_python has memory leaks even if enabled in Apache but not used. That memory leak only becomes an issue if doing lots of Apache restarts and isn't something that occurs on every request.
Graham Dumpleton
+1  A: 

Check if the in-process memory cache backend is enabled, if yes, that could be the problem (new cache entries at each request).

Kedare
It isn't. I use memcached now (it uses it's own process, that grows separately), but turning off caching doesn't caching anything.
Ludwik Trammer
A: 

I'm afraid I haven't got any definite answers. Graham Dumpleton's tips were most helpfull, but unfortunately he didn't make an answer (just comments), so there is no way to accept his response.

Although I still haven't fully resolved the issue, here are some basic tips for other people having similar problems:

  • Read Webfaction's post about keeping memory usage down
  • Make sure the DEBUG setting is set to False
  • Don't use mod_python, use mod_wsgi
  • Make sure you use the most recent version od mod_wsgi (Webfaction tend to install older versions)
  • Don't use Django to serve static content
  • Try running mod_wsgi in a daemon mode (Webfaction installs it in embedded mode by default) [thanks Graham Dumpleton for the tip]
  • If you run in embeded mode, you can specify "inactivity-timeout=[seconds]" option. It will restart the process after [seconds] of inactivity, helping with increasing memory usage. Read this forum post for detailed instructions.
  • This script will help you monitor your memory usage easier, and more precisely [thanks ClaudioA for the tip]
Ludwik Trammer