Repoze Blog

2007-10-29 00:00:00-05:00

In the Fitting Room: Trying on WSGI Servers

There's a funny rumor going around that somehow repoze is tied in some way to the ZServer implementation in Zope2 (or maybe its the somewhat equivalent zope.server implementation in Zope3.

Nothing could be farther from the truth: one of the driving goals for repoze is to allow interoperation with any WSGI-conformant server implementation, as well as conforming middleware. In particular, we wanted to take advantage of Graham Dumpleton's mod_wsgi, as well as the servers provided by other Python web frameworks such as the CherryPy server. In fact, this site consists of multiple WSGI applications running under mod_wsgi, as a proof of the concept.

Kicking the Tires

Back before we had actually released anything, We did some preliminary benchmarking of the various WSGI servers available.

Benchmark paste.ini File


debug = True


use = egg:Paste#test


use = egg:Paste#http

host =

port = 8080


use = egg:PasteScript#wsgiutils

host =

port = 8080


use = egg:repoze.zope2#zserver

host =

port = 8080


use = egg:Paste#cherrypy

host =

port = 8080

Twisted Starter Script

# Twisted.web2 WSGI application setup

from twisted.application import service

from twisted.application import strports

from twisted.internet import reactor

from twisted.web2 import channel

from twisted.web2 import server

from twisted.web2 import wsgi

from twisted.web2.channel import http

from paste.deploy import loadapp

my_app = loadapp('config:/home/tseaver/tmp/repoze-twisted/etc/zope2.ini',


resource = wsgi.WSGIResource(my_app)

site = server.Site(resource)

application = service.Application('web')

service = strports.service('tcp:8080', channel.HTTPFactory(site))


Best-Case Test

On my box, I get the following:

Twisted.Web2 ~700 req/s
wsgiutils ~900 req/s
paste ~1500 req/s
zope.server ~1500 req/s
cherrypy ~2200 req/s

I ran the twisted server with the attached server descriptor:

  $ bin/twistd -ny bin/twisty.py

The others I ran under paster:

  $ bin/paster --server-name= --app-name test etc/zope2.ini

The endpoint in each case is egg:Paste#test (I wanted 'pony', but Chris talked me out of it).

Zope Quickstart

Running against the Zope quickstart page (editing the name in 'twisty.py', switching --app-name to 'zope'):

Twisted.Web2 ~160 req/s
wsgiutils ~165 req/s
paste ~220 req/s
zope.server ~225 req/s
cherrypy ~240 req/s

Tests run against all settings via:

  $ ab -n 1000 -c 10 http://localhost:8080/


The original mailing list thread where we tried this stuff out:

posted at: 00:00 | permalink