mod_python vs. mod_wsgi

61 views
Skip to first unread message

Brot

unread,
May 6, 2008, 3:45:55 PM5/6/08
to Django users
Hello,

today webfaction announced (http://blog.webfaction.com/django-setup-
improvements) that they have now a one-click django/mod_wsgi
installer.

What's your opinion with mod_wsgi? Is it better than mod_python?
What's the advantages/disadvantages?

Bernd

Jorge Vargas

unread,
May 6, 2008, 4:36:01 PM5/6/08
to django...@googlegroups.com
On Tue, May 6, 2008 at 3:45 PM, Brot <schl...@gmail.com> wrote:
>
> Hello,
>
> today webfaction announced (http://blog.webfaction.com/django-setup-improvements) that they have now a one-click django/mod_wsgi

> installer.
>
> What's your opinion with mod_wsgi? Is it better than mod_python?
> What's the advantages/disadvantages?
they are several resources around the net with this information and in
general it is up to you.

some people say (including the webfaction post) that currently
mod_wsgi is a bit faster.

IMO it just depends on whether you are using wsgi and the support your
platform has for it.
>
> Bernd
> >
>

Adam Fast

unread,
May 6, 2008, 5:18:27 PM5/6/08
to django...@googlegroups.com
Strangely enough, this link is now dead...and it's not mentioned at
the top of their blog either. Maybe they pulled the plug?

Bernd

unread,
May 6, 2008, 5:35:46 PM5/6/08
to django...@googlegroups.com
This is the correct link:
http://blog.webfaction.com/django-setup-improvements

This feature is still available in the control panel :-)

Adam Fast

unread,
May 6, 2008, 5:43:09 PM5/6/08
to django...@googlegroups.com
I'll check in the panel, but I get this when going to that URL (and
mentioned going to the main blog to find it, it's not there either):

"Not Found

The requested URL /django-setup-improvements was not found on this
server.:".....404 error.

David Zhou

unread,
May 6, 2008, 5:45:19 PM5/6/08
to django...@googlegroups.com
It works for me. Here's the body of that post:

* Support for mod_wsgi: Setting up a default Django app with mod_wsgi
is now an option in our one-click installer. So if you prefer mod_wsgi
over mod_python you will no longer have to install it manually. I just
ran a simple benchmark using "ab -n 5000 -c 2" against a default
Django site using mod_wsgi and the same using mod_python. Both were
using 2 Apache worker processes. mod_wsgi was slightly faster (1400
req/sec vs 1250 req/sec) and was using slightly less memory (10MB per
Apache worker process vs 12MB). Note that you can also setup a
standalone mod_wsgi application in our control panel (without Django).

* Support for the latest trunk: When you create a Django app you now
have the option to use the latest trunk.

* More django docs: We've added some more knowledge base entries at https://help.webfaction.com/django
and we'll keep on adding more.

Jorge Vargas

unread,
May 6, 2008, 6:47:49 PM5/6/08
to django...@googlegroups.com
On Tue, May 6, 2008 at 5:43 PM, Adam Fast <adam...@gmail.com> wrote:
>
> I'll check in the panel, but I get this when going to that URL (and
> mentioned going to the main blog to find it, it's not there either):
>
> "Not Found
>
> The requested URL /django-setup-improvements was not found on this
> server.:".....404 error.

yea I got that for a while, but then refesh and it went away. I guess
we caught them with their server rebooting :)

Bojan Ordev

unread,
May 6, 2008, 7:33:54 PM5/6/08
to django...@googlegroups.com
The https one doesn't seem to work but the https one works:

https://blog.webfaction.com/django-setup-improvements

Graham Dumpleton

unread,
May 7, 2008, 2:27:10 AM5/7/08
to Django users
On May 7, 7:45 am, David Zhou <da...@nodnod.net> wrote:
> It works for me. Here's the body of that post:
>
> * Support formod_wsgi: Setting up a default Django app withmod_wsgi
> is now an option in our one-click installer. So if you prefermod_wsgi
> over mod_python you will no longer have to install it manually. I just
> ran a simple benchmark using "ab -n 5000 -c 2" against a default
> Django site usingmod_wsgiand the same using mod_python. Both were
> using 2 Apache worker processes.mod_wsgiwas slightly faster (1400
> req/sec vs 1250 req/sec) and was using slightly less memory (10MB per
> Apache worker process vs 12MB). Note that you can also setup a
> standalonemod_wsgiapplication in our control panel (without Django).

In terms of performance, although mod_wsgi performs a lot better than
mod_python:

http://code.google.com/p/modwsgi/wiki/PerformanceEstimates

that isn't where your bottlenecks will be. As such, any gain is still
swallowed up in the overall request times.

Thus how much improvement you see in performance will really depend on
your application.

Similarly, although mod_wsgi itself has a smaller memory footprint
than mod_python, that again isn't going to be that noticeable in the
context of a Python web application which is 40MB or more in size. In
other words, what is a few hundred kilobytes to a megabyte between
friends.

In the past mod_python has got a really bad rap for causing really
bloated processed. This is actually mostly a load of garbage. True
there were memory leaks in some older versions, and you incurred a
couple MB penalty if your Python didn't provide a shared library
linked into the correct place (also an issue with mod_wsgi), but the
problem of fat processes when using mod_python has always simply been
that most Python applications are fat. It all just seemed to be a
bigger problem than it was because people ran Apache with single
threaded prefork MPM and as such Apache had to create a lot more of
those fat processes, causing overall system memory to be gobbled up
quite quickly.

As I understand Webfaction, they are using mod_wsgi in embedded mode,
so for WSGI applications, it just acts as a slightly newer (arguably
better) version of mod_python. The only difference with mod_wsgi is
that if running multiple WSGI applications it defaults to allocating a
separate Python sub interpreter within the process for each, whereas
mod_python has one Python sub interpreter per virtual host and so if
multiple applications they all run together unless you do something to
change that. This would be an issue with Django if you wanted to run
multiple instances on the one site. That is, with mod_python you would
need to fiddle with PythonInterpreter directive to isolate them,
whereas with mod_wsgi they would be isolated by default.

The features of mod_wsgi which many would I am sure say are the most
useful, ie., its fastcgi like daemon mode with ability to run daemons
as separate user and to restart WSGI applications by touching the WSGI
script and thereby not restarting the whole of Apache, most likely
aren't even being used in the WebFaction setup. This is because the
Apache instance already runs as the user and you also have control
over Apache anyway to restart it when you want. In other words, most
of the reasons for running mod_wsgi in daemon mode aren't an issue to
begin with.

The only thing that mod_wsgi would still give you through its daemon
mode is the ability to isolate WSGI applications into their own
processes so they do not interfere with each other. As I understand it
though, WebFaction has limits on the number of persistent processes
you have, thus am not sure you can effectively use daemon mode in
their environment without hitting these limits.

Thus, if what I understand about WebFaction is correct, there possibly
isn't much different between using mod_python and mod_wsgi in their
environment, except if using mod_wsgi you can say you are trendy
because it is newer and shinier. :-)

Graham

Pigletto

unread,
May 8, 2008, 3:16:02 PM5/8/08
to Django users
> The only thing that mod_wsgi would still give you through its daemon
> mode is the ability to isolate WSGI applications into their own
> processes so they do not interfere with each other. As I understand it
> though, WebFaction has limits on the number of persistent processes
> you have, thus am not sure you can effectively use daemon mode in
> their environment without hitting these limits.
There are no limits for a number of long running processes at
Webfaction.

Is there a kind of mod_wsgi setup that allows to considerably reduce
memory usage in comparision with apache prefork mode?

Graham Dumpleton

unread,
May 8, 2008, 8:41:16 PM5/8/08
to Django users
On May 9, 5:16 am, Pigletto <pigle...@gmail.com> wrote:
> > The only thing thatmod_wsgiwould still give you through its daemon
> > mode is the ability to isolate WSGI applications into their own
> > processes so they do not interfere with each other. As I understand it
> > though, WebFaction has limits on the number of persistent processes
> > you have, thus am not sure you can effectively use daemon mode in
> > their environment without hitting these limits.
>
> There are no limits for a number of long running processes at
> Webfaction.
>
> Is there a kind ofmod_wsgisetup that allows to considerably reduce
> memory usage in comparision with apache prefork mode?

If you mean compared to Apache prefork and mod_python then answer is
yes.

Even without using mod_wsgi though, one can do better than prefork
with mod_python by using Apache worker MPM instead. Because Apache
worker MPM processes are multithreaded you don't need as many to be
running and so less copies of your application in memory.

Of course, your application has to be multithread safe. If you are
also trying to use PHP on same server, that can be a big problem as
not all PHP code and/or third party packages for it may be thread safe
depending on what versions you use.

If using mod_wsgi, you have two choices. Use it in embedded mode but
use Apache worker MPM. This will comparable results to mod_python,
although memory footprint of mod_wsgi by itself will be slightly less.

Whether you use Apache worker MPM or not, when using mod_wsgi you can
also use it in daemon mode. This is similar to fastcgi in the sense
that your web application is run in separate process(es), but mod_wsgi
will handle all the management of those processes, starting them up
and restarting them as necessary.

For a description of the various process/thread combinations when
using Apache/mod_wsgi read:

http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading

Examples of using daemon mode described in section 'Defining Process
Groups' of:

http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines

Also refer to the rest of that documentation, documentation about
configuration directives and integration guide for Django as well.

Graham

Pigletto

unread,
May 9, 2008, 2:09:12 AM5/9/08
to Django users
> If you mean compared to Apache prefork and mod_python then answer is
> yes.
Yes

> Even without using mod_wsgi though, one can do better than prefork
> with mod_python by using Apache worker MPM instead. Because Apache
> worker MPM processes are multithreaded you don't need as many to be
> running and so less copies of your application in memory.
I've tried MPM worker. Indeed memory usage is much lower with this
setup,
but I had a lot of strange errors that were possibly related to
thread safety. For example template loader stated that template
doesn't exist, but in fact template was there. I've found a ticket
for this, with a patch, but after applying it I've received other
errors,
that I was not able realize why they happen and I was not
able to find any possible thread safety problems within error related
code, eg.:

(...)
File "/xyz/django/template/__init__.py", line 785, in render
output = force_unicode(self.filter_expression.resolve(context))
File "/xyz/django/template/__init__.py", line 518, in resolve
obj = self.var.resolve(context)
AttributeError: 'FilterExpression' object has no attribute 'var'

I'm not 100% sure that these errors are because of multithreading,
but I suppose they are. As my apache stopped working twice in the
last 2 days I've decided to switch back to prefork immediately
without further investigation.

> Whether you use Apache worker MPM or not, when using mod_wsgi you can
> also use it in daemon mode. This is similar to fastcgi in the sense
> that your web application is run in separate process(es), but mod_wsgi
> will handle all the management of those processes, starting them up
> and restarting them as necessary.
Thanks for all the links, I've already set up one application using
wsgi
in deamon mode at Webfaction :)
It works, setup was easy, memory usage seems to be lower, but it is
only one application so far. Now I have to setup virtual hosts and
other
applications with wsgi and see how it works altogether and in which
configuration.

--
Maciej Wisniowski

Graham Dumpleton

unread,
May 9, 2008, 2:48:15 AM5/9/08
to Django users
Obviously be aware that in daemon mode you will still have multithread
issues to contend with if they run with multiple threads. To avoid it
you would need a config such as:

... processes=5 threads=1

Ie., use prefork model with mod_wgsi daemon mode. This isn't going to
get you much if anything over running prefork MPM and using embedded
mode though as you still need to have sufficient processes to handle
request. At least with embedded mode Apache will create additional
child processes to meet demand, where as with mod_wsgi daemon mode
that number of processes is fixed.

Anyway, if you see the same sorts of issues as you did with
mod_python, perhaps bring them up again as maybe can work out where
the multithread issues may be.

Graham

Graham Dumpleton

unread,
May 9, 2008, 2:58:49 AM5/9/08
to Django users

> > Whether you use Apache worker MPM or not, when using mod_wsgi you can
> > also use it in daemon mode. This is similar to fastcgi in the sense
> > that your web application is run in separate process(es), but mod_wsgi
> > will handle all the management of those processes, starting them up
> > and restarting them as necessary.
>
> Thanks for all the links, I've already set up one application using
> wsgi
> in deamon mode at Webfaction :)
> It works, setup was easy, memory usage seems to be lower, but it is
> only one application so far. Now I have to setup virtual hosts and
> other
> applications with wsgi and see how it works altogether and in which
> configuration.

BTW, you might keep an eye on the following thread:

http://groups.google.com/group/modwsgi/browse_frm/thread/aae1bf2787e393f3

I've been a bit busy and so have been answering the original question
in bits and pieces. The thread brings together various aspects of
using mod_wsgi. The discussion is mainly targeted at how one may use
it for a small scale shared hosting system, but covers issues such as
virtual hosts, and in time some more detail on running multiple
applications across multiple daemon process groups, so may be
relevant.

Graham

Pigletto

unread,
May 11, 2008, 6:04:12 PM5/11/08
to Django users
> Obviously be aware that in daemon mode you will still have multithread
> issues to contend with if they run with multiple threads. To avoid it
> you would need a config such as:
>
> ... processes=5 threads=1
>
> Ie., use prefork model with mod_wgsi daemon mode. This isn't going to
> get you much if anything over running prefork MPM and using embedded
> mode though as you still need to have sufficient processes to handle
> request. At least with embedded mode Apache will create additional
> child processes to meet demand, where as with mod_wsgi daemon mode
> that number of processes is fixed.
>
> Anyway, if you see the same sorts of issues as you did with
> mod_python, perhaps bring them up again as maybe can work out where
> the multithread issues may be.
Thanks for all the help and for wonderful wiki at mod_wsgi site :)

Today I've finished my production setup and my application(s) is now
running Apache in MPM Worker mode and mod_wsgi with daemon process.
Daemon is set up as:

WSGIDaemonProcess procgroup user=usr group=usr processes=2 threads=1
maximum-requests=500 inactivity-timeout=300 stack-size=524288 display-
name=%{GROUP}
WSGIRestrictStdout Off # some print statements in my app and
modules...

Memory usage is in general lower than with mod_python :), but it is
still rather big in terms of limits on my shared account. Top memory
usage I've seen so far was that every process consumed about 55 MB of
memory, but
there are 5 django applications (5 virtual hosts defined) running
under this configuration. I've set this this way that every vitual
host uses same process group:
WSGIProcessGroup procgroup

I've also tried to set same Application group for virtual hosts but
this caused my apps to share settings and was unusable.

Thanks to inactivity-timeout and maximum-requests settings memory
consumptions usually remains at acceptable level, so I consider wsgi
setup much better than one with mod_python :)

Changing mod_python to wsgi was rather easy for me (great docs). Only
problem I had (that took me some time to realize what is happening)
was appending pathes to sys.path.
At first I used sys.path.append(...) in my .wsgi scripts, which caused
strange problems as I had PYTHONPATH set before to some unfortunate
value. So at last I used sys.path.insert(0, .....).

--
Maciej Wisniowski

Graham Dumpleton

unread,
May 12, 2008, 6:45:20 AM5/12/08
to Django users


On May 12, 8:04 am, Pigletto <pigle...@gmail.com> wrote:
> > Obviously be aware that in daemon mode you will still have multithread
> > issues to contend with if they run with multiple threads. To avoid it
> > you would need a config such as:
>
> >   ... processes=5 threads=1
>
> > Ie., use prefork model with mod_wgsi daemon mode. This isn't going to
> > get you much if anything over running prefork MPM and using embedded
> > mode though as you still need to have sufficient processes to handle
> > request. At least with embedded mode Apache will create additional
> > child processes to meet demand, where as withmod_wsgidaemon mode
> > that number of processes is fixed.
>
> > Anyway, if you see the same sorts of issues as you did with
> > mod_python, perhaps bring them up again as maybe can work out where
> > the multithread issues may be.
>
> Thanks for all the help and for wonderful wiki atmod_wsgisite :)
>
> Today I've finished my production setup and my application(s) is now
> running Apache in MPM Worker mode andmod_wsgiwith daemon process.
> Daemon is set up as:
>
> WSGIDaemonProcess procgroup user=usr group=usr processes=2 threads=1
> maximum-requests=500 inactivity-timeout=300 stack-size=524288 display-
> name=%{GROUP}
> WSGIRestrictStdout Off  # some print statements in my app and
> modules...
>
> Memory usage is in general lower than with mod_python :), but it is
> still rather big in terms of limits on my shared account. Top memory
> usage I've seen so far was that every process consumed about 55 MB of
> memory,

Such is life when using Python web applications, they can be quite
fat, and thus each process can consume a lot of memory. If thought
this is from 5 virtual hosts as you suggest below, that is actually
pretty good. Many people have single Django instances getting up to
40MB or more.

The only solution besides trimming your application memory usage
somehow, is to validate it is multithread safe and then use:

WSGIDaemonProcess procgroup user=usr group=usr threads=15

That is, default of one process with 15 threads.

This will halve your memory usage as only 1 process instead of 2. With
15 threads you also improve your ability to handle concurrent
requests.

Down side of using multithreading a memory constrained VPS, is that
with concurrent requests, there is a risk of memory usage spiking if
two requests come at same time which have a requirement for large
amount of transient memory.

> but
> there are 5 django applications (5 virtual hosts defined) running
> under this configuration. I've set this this way that every vitual
> host uses same process group:
> WSGIProcessGroup procgroup
>
> I've also tried to set same Application group for virtual hosts but
> this caused my apps to share settings and was unusable.

That is a limitation of Django, in as much as it relies on global
variables, staring with DJANGO_SETTINGS_MODULE in os.environ.

Good WSGI applications have configuration data come in through the
WSGI request environment. This means that it can be set on a per
request basis, making it somewhat practical to start having the
concept of hosting multiple instances of an application within same
Python interpreter context. The best example of an application able to
do this is Trac.

The benefit of being able to do this is that the different instances
can share the same common Python modules and it is necessary to be
loading multiple copies in different Python interpreter instances
within the same process as you have happening now.

> Thanks to inactivity-timeout and maximum-requests settings memory
> consumptions usually remains at acceptable level, so I consider wsgi
> setup much better than one with mod_python :)

At the moment, because you are running multiple Django instances
within the same process, but in different Python sub interpreters
(application groups), the benefit of inactivity-timeout may not be
getting realised. This is because a request against any instance will
keep all others in memory.

If instead you give each virtual host its own process(es), then the
inactivity-timeout will more readily be tripped and the process for an
instance recycled and brought back to base memory level.

The overhead of running each in its own process shouldn't be too much
more over current levels. But if some are infrequently used, average
memory usage across all could be somewhat less if some instances are
dormant.

Graham
Reply all
Reply to author
Forward
0 new messages