How Fast Is Your Framework?

By | November 20, 2006

UPDATE (2007-01-01): I have conducted a new series of benchmarks; see them here. The numeric results below should be considered as outdated, although the history, methodology, and approach are still valid.

Wherein I relate the results of benchmark testing on three (plus one)four frameworks: Cake, Solar, Symfony, and Zend Framework(plus Cake). Anger-inducing broad-brush overview: Solar is 4x faster than Zend, and almost 2x faster than Symfony. Read on for all the nuances and caveats.

UPDATE: Have updated the Cake results, now that I’ve figured out how to turn off database access.

UPDATE 2: Added note about “views” in Zend Framework, also added list of loaded files and classes for each framework.


“Figures don’t lie, but liars can figure.” — Anon.

Recently I became curious how many requests-per-second the Solar framework could handle. This was related to the recent Mashery launch; we needed to be ready to receive a ton of visitors to the site (I won’t disclose those numbers at this time ;-).

Most Mashery applications are built on top of the Solar framework, but when benchmarking those applications, I needed to know what the theoretical limit to responsiveness was, as imposed by the Solar framework.

After that, I figured it would be interesting to know the theoretical limits to responsiveness imposed by other frameworks, in particular Cake, Symfony, and the Zend Framework. This blog entry reports my findings.

Goals and Caveats

The purpose of this is not to say that one framework is better than another, or to engage in one-upmanship. The results do not say whether an application will run faster or slower on a particular framework; bad application code will slow you down dramatically on any framework. Similarly, use of full-page caching will bypass the framework completely, raising the responsiveness to something closer to the web-server’s maximum.

Instead, the purpose of this is to tell you what the maximum possible responsiveness of the framework will be under the simplest and most straightforward conditions, while using the framework’s controller and view components. Anything you add as application code will only reduce its responsiveness from there.

In addition, these results do not constitute an endorsement or indictment of any particular framework; they all have different strengths and weaknesses. I think the ones I tested are the most full-featured, in that they provide full-up MVC separation, make good use of development patterns, and offer an existing set of plugins or added functionality like caching, logging, access control, authentication, form processing, and so on.

Finally, it is entirely possible that I have missed some important speed-enhancing technique with one or more of the frameworks. If so, it is due to ignorance on my part, not maliciousness. I have done my best to honestly and fairly represent each of the frameworks here, and I would be very happy to hear what I can do to speed up any of the frameworks I benchmark below.


For each of the frameworks tested, I attempted to use the most-minimal controller and action setup possible, effectively a “Hello World!” implementation using the stock framework components and no configuration files (or as few as the framework would let me get away with). This was the only way I could think of to make sure the tests were identical on each framework.

The minimalist approach has a number of effects:

  • It negates most “if you cache, it goes faster” arguments. The “view” in each case is just a literal string “Hello World!” with no layout wrapper. (For Symfony and Cake, this meant editing the layout files to only echo the view output.)

  • It negates the “but the database connection speed varies” argument. Database access is not used at all in these benchmarks. (I could not figure out how to turn off database access in Cake, which is why I don’t include it as a peer in the results.)

  • There’s no application code to execute; the controller actions in each framework are empty and only call the view, which itself is only the literal “Hello World!” text. This shows us the maximum possible throughput; adding application code will only reduce responsiveness from this point.

Technology and Setup

All the benchmark tests were run on this hardware (admittedly underpowered):

  • Macintosh Mini G4 with 1G RAM and 7200 RPM hard drive
  • Stock installation of Apache 1.3.33
  • Custom compiled PHP 5.2.0
  • APC 3.0.11 enabled with shm_size of 30 and stat turned on

Each framework benchmark uses the following scripts or equivalents …

  • Bootstrap file
  • Default configs (or as close as possible)
  • Front-controller or dispatcher
  • Page-controller or action-controller
  • One action with no code, other than invoking a View processor
    • No authentication, no access control, no filters, no database, etc.
    • (although Cake kind of forces the database on you, so it’s not a full peer in this report)
  • Static view with only literal text “Hello World!”
    • No PHP, helpers, layout, escaping, etc.

… so the benchmark application in each case is very small.

I used the Apache benchmark “ab” tool for measuring requests-per-second, on localhost to negate network latency effects, with 10 concurrent requests for 60 seconds. The command looks like this:

ab -c 10 -t 60 http://localhost/[path]

Benchmark Test Results

First, we need to see what the maximum responsiveness is without any framework code. The web server itself is capable of delivering a huge number of static pages: 808 req/sec (!!!) for a file with only “Hello World!” in it.

Document Path:          /helloworld.html
Document Length:        12 bytes
Requests per second:    808.95 [#/sec] (mean)
Time per request:       12.36 [ms] (mean)
Time per request:       1.24 [ms] (mean, across all concurrent requests)
Transfer rate:          238.69 [Kbytes/sec] received

Invoking PHP to “echo ‘Hello World!'” slows things down a bit, but it’s still impressive (remember, APC is turned on for all requests): 597 req/sec.

Document Path:          /helloworld.php
Document Length:        12 bytes
Requests per second:    597.61 [#/sec] (mean)
Time per request:       16.73 [ms] (mean)
Time per request:       1.67 [ms] (mean, across all concurrent requests)
Transfer rate:          107.00 [Kbytes/sec] received

Not too shabby for a consumer Macintosh Mini optimized for desktop use.


The Cake page-controller looks like this:

class HelloWorldController extends AppController {
    var $layout = null;
    var $autoLayout = false;
    var $uses = array();
    function index()

The page-controller automatically uses a related “index.thtml” view script.

Respresentative result from three “ab” runs on Cake 17 req/sec.

Document Path:          /cake/helloworld/index
Document Length:        12 bytes
Requests per second:    17.13 [#/sec] (mean)
Time per request:       583.67 [ms] (mean)
Time per request:       58.37 [ms] (mean, across all concurrent requests)
Transfer rate:          5.09 [Kbytes/sec] received


The Solar bootstrap file looks like this:

ini_set('display_errors', true);

require_once 'Solar.php';

$front = Solar::factory('Solar_Controller_Front');


The Solar page-controller code looks like this:

class Solar_App_HelloMini extends Solar_Controller_Page {
    public function actionIndex()

The page-controller automatically uses a related “index.php” file as its view script, and uses no layout.

Representative result from three “ab” runs on Solar 0.25.0: 45 req/sec.

Document Path:          /index.php/hello-mini/index
Document Length:        12 bytes
Requests per second:    44.78 [#/sec] (mean)
Time per request:       223.32 [ms] (mean)
Time per request:       22.33 [ms] (mean, across all concurrent requests)
Transfer rate:          16.75 [Kbytes/sec] received

Symfony (Stable and Beta)

The Symfony action controller code looks like this:

class worldActions extends sfActions
  public function executeIndex()

The action controller automatically uses a related “indexSuccess.php” file as its view script. However, there is a default “layout.php” file that wraps the view output and adds various HTML elements; I edited it to look like this instead:

<?php echo $sf_data->getRaw('sf_content') ?>

If there is some way to make Symfony not use this layout file, please let me know.

Representative result from three “ab” runs on Symfony 0.6.3-stable: 26 req/sec.

Document Path:          /symfony/web/world/index
Document Length:        12 bytes
Requests per second:    25.60 [#/sec] (mean)
Time per request:       390.70 [ms] (mean)
Time per request:       39.07 [ms] (mean, across all concurrent requests)
Transfer rate:          8.40 [Kbytes/sec] received

Representative result from three “ab” runs on Symfony 0.7.1914-beta: 24 req/sec.

Document Path:          /symfony/web/world/index
Document Length:        12 bytes
Requests per second:    23.94 [#/sec] (mean)
Time per request:       417.72 [ms] (mean)
Time per request:       41.77 [ms] (mean, across all concurrent requests)
Transfer rate:          7.86 [Kbytes/sec] received

Zend Framework (0.2.0 and incubator)

The Zend Framework bootstrap file looks like this:


    . PATH_SEPARATOR . './incubator/library'
    . PATH_SEPARATOR . get_include_path()

require_once 'Zend.php';
require_once 'Zend/Controller/Front.php';


The Zend Framework action controller code looks like this:

require_once 'Zend/Controller/Action.php';
class IndexController extends Zend_Controller_Action
    public function indexAction()
        include dirname(dirname(__FILE__)) . '/views/index.php';

Zend Framework has a couple of special cases:

  1. The front-controller can be used by itself or with a Rewrite Router. On advice of Matthew Weier O’Phinney, I used the front-controller without the router, which slows things down.

  2. Zend Framework is still in heavy development; again, on advice of Matthew Weier O’Phinney, I added the “incubator” directory to the include_path to be sure the most-recent code is being used.

  3. The Zend_View class apparently has some issues on PHP 5.2.0 that preclude its use, so I just do a plain “include” to get the view script. This is much faster than using a separate View class, but in normal use you would have a Zend_View instance here instead.

Even with that special treatment, the respresentative result from three “ab” runs on Zend Framework 0.2.0 is the lowest of the bunch: 11 req/sec.

Document Path:          /zf/index
Document Length:        12 bytes
Requests per second:    11.17 [#/sec] (mean)
Time per request:       895.28 [ms] (mean)
Time per request:       89.53 [ms] (mean, across all concurrent requests)
Transfer rate:          2.66 [Kbytes/sec] received

“This Is Stupid And Doesn’t Mean Anything!”

“There are three kinds of lies: lies, damn lies, and statistics.” — variously attributed to B. Disraeli, M. Twain, and others.

“A man’s got to know his limitations.” — Dirty Harry Callahan

I can hear the objections now:

  • “Not realistic!”
  • “Not comprehensive!”
  • “Doesn’t account for features that I like!”
  • “Who cares, I don’t need that level of responsiveness!”
  • “Doesn’t matter if Framework X is slower, I’m more productive with it!”

Yes, yes, you’re all correct. But when you get to the point when you have to scale across multiple servers, and you’re looking to squeeze out every possible request you can, it’ll be good to know what the realistic top-limit is.

Last caveat: they say “your mileage may vary.” In these cases, your mileage is almost certain to vary. The absolute numbers will be different from server to server. Data and output caching can help in many cases, but the moment you invoke the front-controller and page-controller, you’re going to hit these relative top limits no matter how much partial caching you use:

                  Req/Sec    % Relative
Cake              17         154%
Solar             45         409%
Symfony (avg)     25         227%
Zend Framework    11         100% (baseline)

And again, it only gets slower from there; these numbers were for the simplest possible “Hello World!” application in each framework.

Appendix: What Classes Get Loaded?

John Herren in the comments below asks how many files are loaded each time; below I give the counts as reported by get_included_files(), as well as the classes used by each framework in the benchmark application.

Cake (26)

34 files total, including these classes:

  1. Object
  2. CakeSession
  3. Security
  4. NeatArray
  5. Inflector
  6. Configure
  7. Dispatcher
  8. Router
  9. Controller
  10. Component
  11. View
  12. Helper
  13. ConnectionManager
  14. DataSource
  16. Model
  17. ClassRegistry
  18. AppModel
  19. HelloWorld
  20. AppController
  21. HelloWorldController
  22. SessionComponent
  23. DboSource
  24. DboMysql
  25. HtmlHelper
  26. SessionHelper


18 files total, including these classes:

  1. Solar
  2. Solar_Base
  3. Solar_Controller_Front
  4. Solar_Uri
  5. Solar_Uri_Action
  6. Solar_Request
  7. Solar_Controller_Page
  8. Solar_App_HelloMini
  9. Solar_Session
  10. Solar_View
  11. Solar_Struct
  12. Solar_View_Helper
  13. Solar_Class_Stack
  14. Solar_Path_Stack
  15. Solar_View_Helper_GetTextRaw

Symfony (43)

42 files total, including these classes:

  1. sfConfig
  2. sfToolkit
  3. Symfony
  4. sfConfigCache
  5. sfException
  6. sfComponent
  7. sfAction
  8. sfActions
  9. sfActionStack
  10. sfActionStackEntry
  11. sfContext
  12. sfController
  13. sfFilter
  14. sfExecutionFilter
  15. sfRenderingFilter
  16. sfFilterChain
  17. sfRequest
  18. sfResponse
  19. sfStorage
  20. sfUser
  21. sfView
  22. sfWebController
  23. sfFrontWebController
  24. sfWebRequest
  25. sfSessionStorage
  26. sfPHPView
  27. sfRouting
  28. sfDatabaseManager
  29. myFrontWebController
  30. myWebRequest
  31. sfParameterHolder
  32. sfWebResponse
  33. sfBasicSecurityUser
  34. myUser
  35. sfSecurityFilter
  36. sfBasicSecurityFilter
  37. worldActions
  38. sfCommonFilter
  39. sfFlashFilter
  40. sfValidatorManager
  41. sfOutputEscaper
  42. sfOutputEscaperGetterDecorator
  43. sfOutputEscaperArrayDecorator

Zend (28)

34 files total, including these classes:

  1. Zend
  2. Zend_Exception
  3. Zend_Registry_Exception
  4. Zend_Registry
  5. Zend_Controller_Front
  6. Zend_Controller_Exception
  7. Zend_Controller_Plugin_Abstract
  8. Zend_Controller_Request_Abstract
  9. Zend_Controller_Response_Abstract
  10. Zend_Controller_Plugin_Broker
  11. Zend_Controller_Router_Exception
  12. Zend_Controller_Request_Http
  13. Zend_Http_Exception
  14. Zend_Uri
  15. Zend_Uri_Exception
  16. Zend_Uri_Http
  17. Zend_Filter
  18. Zend_Filter_Exception
  19. Zend_Uri_Mailto
  20. Zend_Http_Request
  21. Zend_Controller_Request_Exception
  22. Zend_Controller_Router
  23. Zend_Controller_Dispatcher_Exception
  24. Zend_Controller_Action
  25. Zend_Controller_Action_Exception
  26. Zend_Controller_Dispatcher
  27. Zend_Controller_Response_Http
  28. IndexController

53 thoughts on “How Fast Is Your Framework?

  1. Evan Wired

    >it only gets slower from there

    True, but you don’t know what the slopes of each curve of complexity vs. performance are.

    The CodeIgniter community would probably like to see their numbers here, too, though you did stipulate “good development patterns” so…

  2. David

    I believe with cakephp you set the useTable property of your controller to false.


    class … {
    $useTable = false;

    I don’t know if this has any effect on your test, but it’s worth a shot i guess. I’m just now evaluating what framework to really look into, and Solar is one of the frameworks i have not looked into yet.

    But still though, i’m wondering what RoR could pull off on the same hardware, just for the fun of it.

  3. John Herren

    Sure, you can denounce these stats, but I certainly think they are interesting. I’d like to see a couple extra metrics with your example: number of files included, and maybe even stack traces.

    /me wonders if Paul will bite…

  4. pmjones Post author

    Hi Richard — I’d be curious to hear how Zend fares against Solar on your machine, to see if the relative performance numbers are similar. The absolute numbers are guaranteed to change, but I’m interested to know about the relative percentages.

  5. Derek

    Let me be that guy that always seems to crop up on any post about PHP frameworks to talk about Code Igniter ( Very lean, very light, and lightning quick. If you are still looking for a flexible framework that gets out of your way when you know what you’re doing, give it a shot.

  6. pmjones Post author

    Oh, and Richard, I’m doing this all on a Mac Mini; not exactly known for being highly performant. Like I said, the absolute numbers are not so key as the relative percentages are.

  7. Richard Thomas

    Yea I will rerun all the tests later when I get home, More interesting will be that im still running 5.1.6 on the machine I tested on, I am also using apache 2.

    I do have apc installed, but that made me think a second so I disabled it and reran the Zend test and only got 171 rps or around around 8% which is a lot closer to your results, maybe you can doublecheck apc is working for these tests.

  8. Bojan Zivanovic

    Very interesting.
    Could you add CodeIgniter to the tests?
    They put an accent on speed, so let’s see how fast they are…

  9. kenrick

    yeah paul I ran these same tests sometime last year when I was using Matthew’s CGIapp, which was alot faster than Cake and others out of the box, but still could use some speed improvements. I sent the result to Matthew and I know he made an effort to speed it up.

    really, it seems the more you include with php the slower things get. especially on a mac where I think there are some extra overhead and what not with extra stat calls on included files (youll have to google that, but i remember reading about it someplace, there is even a patch out there in the wild to deal with it).

    I think that while convenience is nice, there has to be a trade off for how quick you can make something compared to how fast something will actually run long term.

    In response to my speed issues with CGI App (i also had some other cosmetic issues, Matthew is a great developer so no slight on him at all) I ended up creating my own MVC thing, and have been using it real world for some time now with good results. The latest test of it is a single install thats answering for over 1300 sites (email me paul if yer curious), guess Ill have some good stats pretty soon to let me know about performance issues.

    Thanks for the tests though, I sometimes feel like people get bowled over by hype, and are responsible for the shutdowns by hosts for execeeding process limits when they install their cake/symfony/rails/you choose framework and don’t understand php/ruby enough in the first place to make sure there stuff is gonna work as expected.

    There is a reason Rasmus uses his no-framework framework.

  10. Chris D

    Hey Paul,

    Maybe it’s time for a new Mac.

    I just ran a helloworld.php on my baseline MacBook and got 1948 req/sec (without APC, btw)!

  11. Rob...

    Hi Paul,

    Can you post the code for the Solar test as I can’t work out the directories under my localhost/speed/solar root dir should be…



  12. Sylvain Gourvil

    Good works you have done there !

    Like derek said, Code Ingiter is also a very good framework for one reason.
    It is new so for the moment very light and the best asset is thaht it is easily and quickly updatable !!
    Take a look

  13. Pingback:

  14. Sylvio

    Thanks a lot for this benchmark

    You should test last Symfony version Alpha, this Alpha will replace the beta Soon and become final stable first version “1.0” in about a month.

    Last Symfony alpha versions are still more faster :
    watch on Symfony Blog :
    “How caching can speed up your application” :

    “On our test server (not as fast as a production server), an empty “Hello, world!” page takes about 12ms to render.”

  15. Philip Hofstetter


    very interesting results. I’d like to add one thing:

    Using no framework is certainly faster than using a framework. This is just plain common sense. As is that using static html is faster than a php page.

    Still: As a reader of this article, don’t conclude that frameworks are inherently slow and that you lose speed when using whatever framework you chose.

    You see: A framework provides a lot of features you have to add yourself otherwise. And while a framework can be (and often is) optimized for speed, your own code is not necessarily.

    The guys writing these frameworks are often interested in achieving the maximum speed for the features they are providing. This means that when you use a framework because you need feature X, there’s a good chance that when using the framework, you get a better performance at doing X compared to when you write it yourself.

    On the other hand, with higher abstraction comes higher run time. When you pick exactly the features you need and when these features only cover a small percentage of the features your framework provides, your solution will be faster due to less abstractions and less code.

    But then the question of maintainability kicks in: Can the application and your own framework be maintained and extended in the future without either losing speed or cleanness (and thus maintainability).

    Saying that frameworks are bad because they are slow is only seeing part of the truth.


  16. Richard Thomas

    Hey paul, the incubator really has a lot of code thats not fully tested yet and my performance tests show base 0.2.0 is around 3 times faster then using the incubator code, Could you rerun without the set_include_path?

    Still working with some issues with the benchmarking soon as I get them all done I will post.

  17. David Goodwin


    I get something like :

    static html: 1301/sec
    PHP with APC + Smarty caching : 52.90
    PHP without APC + Smarty Caching : 18
    PHP without APC or Smarty Caching : 16.57

    I’m using PHP5.1.2 on Ubuntu Dapper (x86-64) with 2gb of RAM.

    My homebrew framework includes quite a few files (propel, pear log, creole etc), which are I’m sure a bottleneck.

    Clearly, APC makes a big difference.

    Thanks for the blog post, it was interesting to read.

  18. Cake Fan

    There’s a few classes being included for CakePHP that shouldn’t be in this scenario:

    # HtmlHelper
    # SessionHelper

    These can be removed from your controller, via the $helpers array…

  19. JMSR

    I just see the light.
    I will never use a framework just for print a “Hello World!”… ;-)

  20. Jan

    Please include Code Igniter into this Benchmark. As people tell me it is supposed to be the fastest framework.

  21. Pah

    Before Code Igniter, please benchmark RoR, Django and TurboGears. I would do it myself, but I’m busy now. Thanks.

  22. Pingback: Canned !! -- my Atropine

  23. Pingback: Just a quick note »

  24. Pingback: PHP Framework Benchmark at AnnoMundi’s Weblog

  25. Mikko

    Hopefully this will open peoples eyes to the Solar framework. It is not just a speedy framework, the code and the design of it is pure elegance! For CI interested folks: Look at the code of CI and compare it to solar to see that CI is just hacks.

  26. Pingback: Arnolds worlds » Blog Archive » Without a framework: (M)VC

  27. Pingback: Paul M. Jones » Blog Archive » The Interesting Case of Diminishing Responsiveness

  28. Pingback: Paul M. Jones » Blog Archive » New Year’s Benchmarks

  29. pmjones Post author

    Hi “web design studio firenze” — without commenting on the quality of Code Igniter, it is my opinion that it is not in the same class or category as the other frameworks listed here. I say as much in the followup to this entry, here:

    Clearly I need to spell out my reasons for thinking so, as your point is one of the most commonly made. I will attempt to do so in another blog post, but I don’t know when.

  30. Shawn

    I would really love to see is a database based benchmark. The rationale is that the database component is just as key to a framework. The goal is to try to find out how much time requests get “stuck” in the framework especially if you’re using ORM.

    Thanks! And thanks for your work and contribution:)

  31. Pingback: Shall We Zen » links for 2007-04-17

  32. Pingback: Dr-Hamza’s Space

  33. Pingback: Dr-Hamza’s Space

  34. Pingback: Dr-Hamza’s Space

  35. Ben

    To prevent the layout.php from being loaded, put:


    in your exec function in actions.class.php or the specific action php file.

  36. Pingback: » Архив блога » Проблема выбора

  37. Pingback: » Архив блога » Проблема выбора

  38. Pingback: Feed My News Test » Blog Archive » PHP Frameworks and A Very Nice Application Flow Chart

  39. Pingback: Paul M. Jones » Blog Archive » New Year’s Benchmarks

  40. Marvin

    Thanks for the overview. This was very helpful to me since I was just asked to do exactly this task by myself…

    Regarding you symphony/layout-question:
    You can turn off the basic page-layout in the application config-file ‘apps/[appname]/config/view.yml’. The parameter is named ‘default.has_layout’ and is enabled by default.

  41. ken

    for symfony also, you can bypass entirely the view layer using this code

    getResponse()->setContent(‘Hello world’);
    return sfView::NONE;

    and setting these options in settings.yml will also improve performance

    use_database: off #by default this is on
    use_security: off #by default this is on
    use_flash: off #uses session if on
    escaping_strategy: off #defaults to on
    standard_helpers: [] #defaults to [Partial, Cache, Form]
    enabled_modules: [] #defaults to [default]

  42. Pingback: Paul M. Jones » Blog Archive » Labor Day Benchmarks

  43. Massimo

    I run the same test for web2py on a Ubuntu VM Machine running on the latest PoweMac (the VM machine use one core only). I used the built-in cherrypy WSGI server.

    This is the controller action:

    def index():
    return dict(message=”hello world”)

    This is the view:


    Total transferred: 10801080 bytes
    HTML transferred: 2500250 bytes
    Requests per second: 1578.29 [#/sec] (mean)
    Time per request: 6.336 [ms] (mean)
    Time per request: 0.634 [ms] (mean, across all concurrent requests)
    Transfer rate: 332.93 [Kbytes/sec] received

  44. Pingback: Paul M. Jones » Blog Archive » A Siege On Benchmarks

  45. Pingback: PHP Frameworks and A Very Nice Application Flow Chart « NVMIND

  46. Pingback: Paul M. Jones » Blog Archive » How Fast Is Your Framework? | Velocity Software Solutions (P) Ltd.

  47. Pingback: - – Work Wild Web @ BornToBeWeb

  48. Pingback: The need for speed!! | Canned Atropine!!

Leave a Reply

Your email address will not be published. Required fields are marked *