Back
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

django_zW6WQ5I.png

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_Logo.svg.png

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.

 RailsDjango
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.

Cache

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.

Database

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 (http://benchmarksgame.alioth.debian.org/u64q/ruby.html), on average Python is slower than Ruby by 0.7%

TaskPython 3 (sec)Ruby (sec)
binary-trees126.0758.72
spectral-norm180.01141.49
n-body836.27723.69
pidigits3.413.14
fasta113.03108.36
reverse-complement2.934.03
k-nucleotide72.35101.95
fannkuch-redux501.72710.58
mandelbrot250.62463.95
regex-redux14.8728.80

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
Jul 21, 2022Technology
Codemirror: unit-testing codemirror react components

One of our recent projects includes the functionality of an inline code editor. This code editor needed to be highly extensible and have custom features. To address this, we chose Codemirror v6 due to its peculiar architecture - it is highly customizable, and all the additional features are provided into codemirror engine as Extension objects.

Aug 27, 2020Technology
5 tips for designing database architecture

Designing database architecture is a challenging task, and it gets even more difficult when your app keeps getting bigger. Here are several tips on how to manage your data structure in a more efficient way.

Jun 14, 2017Technology
How to Deploy a Django Application on Heroku?

In this article I'll show you how to deploy Django with Celery and Postgres to Heroku.

Mar 12, 2017Technology
Creating a chat with Django Channels

Nowadays, when every second large company has developed its own instant messenger, in the era of iMessages, Slack, Hipchat, Messager, Google Allo, Zulip and others, I will tell you how to keep up with the trend and write your own chat, using django-channels 0.17.3, django 1.10.x, python 3.5.x.

Mar 3, 2017Technology
Flask vs Django. Which Is Better for Your Web App?

There are two most popular web frameworks in Python. There is the Django with lots of intelligent defaults and the Flask micro framework with complete freedom in the choice of modules. Let’s see, what django vs flask is in 2017.

Feb 28, 2017Technology
How to write an API in Django

There is such a term as Remote Procedure Call (RPC). In other words, by using this technology, programs can call functions on remote computers. There are many ways to implement RPC.