Jan 22, 2017

Django vs Rails Performance

When choosing a framework to work with, it’s important to pay attention to performance. Young developers often end up doing django vs ruby on rails performance comparison.

This article is aimed for beginners, who are trying to choose the path to follow.

Contestants overview



Django is a web framework, first released in 2005. It was created to speed-up development of news websites, but evolved since then to a general purpose framework. You could’ve heard about some applications built on Django: Instagram, Bitbucket, Pinterest. As of January 2017, there are 1350 contributors to django on github.

Known for having «batteries included», Django provides built in ORM (and db migrations facilities), Admin UI, Authentication, Session management and other tools.

Core architectural principles on Django are heavily influenced by core principles of python - «explicit is better than implicit», «readability matters». The code is easy to write, easy to read and it’s always obvious how things will work when you run it.

Ruby on Rails


Ruby on Rails (RoR) was released in 2008. It was created in 37 signals to power their projects. RoR quickly gained traction and became even more popular than Django (even though was release later). RoR powers some popular websites, for example: AirBnB, Basecamp, Github, Fiverr. As of January 2017, there are 3224 contributors to Rails on github.

Just like Django, RoR provides all the base tools a developer might need to build a database driven application.

RoR follows "convention over configuration» principle, which means that you have to write less code than in Django, for example, but it’s not always immediately obvious why things work the way we work and how to modify it.

Rails vs Django comparison table

This table shows the state of rails vs django in 2017, at the time of writing this article.

Created in20082005
Github stars  
Average salary (Middle engineer)$88 544$86 801
Upwork jobs (at the time of writing article)512281
Configuration principleConvention over configurationExplicit is better than implicit
PatternModel View ControllerModel Template View
ModelsRuby on Rails has a generic ORM that allows managing database operations and migrations in Ruby. The same code works on all supported database backends. Model definition is spread across multiple files: 1. Model file, which defines business logic and validation rules 2. Migrations files, which contain definitions of incremental changes to database structure 3. Schema file, which contains a reference to current database structureDjango's ORM is similar in terms of features, but the code is organized differently: 1. Model file contains business logic, database structure and validation rules. 2. Migrations files are generated automatically as model file is updated and contain incremental db changes.
Templates<%= link_to "Show", book %>Show
RoutingBy default Rails routes URLs to controller methods. For example POST request to /geocoder will route to create action of Geocoders controller. This behaviour can be modified with configuration file.Django requires each endpoint to be explicitly defined in python code. Each endpoint is defined as url(r'^articles/([0-9]{4})/$', views.year_archive)
JavascriptRails has built in static compilation pipeline that use coffeescript by default.Django serves static files as they are by default. Popular third-party applications add compilation and compression options.

Web framework performance

When I just started learning web development, it seemed obvious to me that raw language speed and framework optimization level are the most important parts to website performance, I even tried switching to Haskell just because it’s «fast». Now, 10 years later, it seems pretty obvious to me that framework and language speed just don’t matter in overall application performance and success.

Just by looking at the overview above we can see since Bitbucket is based on Django and Github is based on Rails and both of them are equally fast, then probably you can take any framework and build a high-loaded site that is fast enough. Still, let’s try to understand why framework speed doesn’t matter, what actually matters and what to use for your first application.

What impacts application performance

Let’s try to follow request’s lifecycle and specify what tools are involved in the process.

Request path

Load balancer

High loaded application will probably have multiple servers. Load balancer is the tool that will route the request to a needed backend. One of the most popular examples is HAProxy. SSL decryption can be also performed at this step.

Web accelerator

Accelerators are used to compress and cache responses and then quickly serve responses from cache. Most of requests will be returned here from cache, blazingly fast. Popular web accelerator is Varnish.

Web server

Nginx most probably, will serve static files and route dynamic requests to underlying application server. Note that nginx is capable to doing load balancer’s and web accelerator’s job to some extent, so it might be enough for you to just configure nginx correctly.

Application server

Application server converts http request to an object that our web framework will understand. For example, Unicorn for Rails, Gunicorn for Django.

The framework

Now at last we are running our code. In order to generate a response, our framework will have to do following: authenticate user make requests to database to pull information for all part of the page process returned data and render html

In reality, multiple levels of our application level cache kick in. Only if cache is empty on all levels, we’ll go to the database.


Memcached or Redis. Our application will try to serve user’s page from cache first. If it’s not available - it will pull page fragments from cache. For fragments that are not in cache, it will get cached database responses and render that particular fragment of html.


Almost all of the websites and applications are database-driven. Waiting for database to fulfill query will take significant part of entire response time, so choosing database wisely and making queries correctly will speed-up response significantly.

Framework impact

It looks like if cache is not empty, ruby or python won’t even have to run. If it has to run, it only has to run for the fragment of the page, which is not in cache. When running, part of that time will be just waiting for the database response. Framework’s speed impact is not that important for the overall response time.

Architecture impact

When there is nothing in cache and application has to make all the db queries and render everything, it takes up to 2 seconds (including all the db queries).

Fully cached response is 10-20ms. Partially cached response will take 200ms

Optimizing database structure and queries can reduce waiting time by 90%.

As you can see, architectural decisions can change response time drastically.

Raw speed!

Ok, fine, ruby/python will run for just a fraction of total response time. Let’s measure speed difference between python and ruby during that running time - that’s exactly when raw language speed really shines.

As of January 2017, based on results from benchmarks game (, on average Python is slower than Ruby by 0.7%

TaskPython 3 (sec)Ruby (sec)

At this point you can imagine how catastrophic for your application’s performance it would be to choose a «slower» framework.

Very funny

It might have been a little bit too long joke, but hopefully I’ve made my point - when choosing between RoR and Django, forget about speed. It’s more important how fast you can learn, how easy it is to find a job, does language matches your way of thoughts.

These frameworks while similar, have different philosophy, which is easy to notice when you start using them. Just spend a month playing with each of them and go with the one that was easier. Really. Choosing the easier way is not cheating in this case.

Subscribe for the news and updates

More thoughts
Apr 11, 2024Technology
Test Analysis at the Feature Level

In the previous article, we learned about test analysis for a product in general, and now we are ready to go further and look at test analysis for specific features.

Apr 18, 2023Technology
TDD guide for busy people, with example

This quick introduction to TDD is meant to show the implementation of this practice with a real-life example.

Feb 12, 2020Technology
5 Best Payment Gateways For 2020

We reviewed the best payment gateways in 2020. Here’s our comparison of their features, advantages, and disadvantages.

May 22, 2017Technology
Web Application Security: 10 Best Practices

Protection of WEB App is of paramount importance and it should be afforded the same level of security as the intellectual rights or private property. I'm going to cover how to protect your web app.

Mar 2, 2017Technology
API versioning with django rest framework?

We often handling API server updates including backwards-incompatible changes when upgrading web applications. At the same time we update the client part, therefore, we did not experience any particular difficulties.

Mar 6, 2010TechnologyManagement
Supplementing settings in settings_local

For local project settings, I use old trick with settings_local file:try:from settings_local import \*except ImportError:passSo in we can override variables from I didn't know how to supplement them. For example how to add line to INSTALLED_APPS without copying whole list.Yesterday I finally understood that I can import settings from settings_local:# settings_local.pyfrom settings import \*INSTALLED_APPS += (# ...)