Request War

This contest started as a fun chat with an employee at HackerRank and how it ended up with a coding contest. One of the engineers from our team, Aditi Tayal, has recently started learning to build a web app using Mysql and Redis. She built a simple task manager and shared this link with me https://aditiflaskcrudapptutorial.herokuapp.com/.

My first instinct is to figure out how well the app scales and does it have any security issue. I built a small script to insert tasks at a rapid rate and she wrote a code to delete the entries I made. Soon, we were trying to figure out which code runs faster. And ended up planning for a contest to see which script runs fast.

Task list before the contest.
Task list after the contest. I am going to assume that “slap him” was not meant for me.

The rules of the contest were as follows

  1. The script/code we write will run for 120 seconds. We will use timeout to make sure the code runs exactly for 120 seconds
  2. We will run the script from my personal server in linode.com, so that we there is no unfairness because of home internet speed.
  3. The script which can make the maximum number of insert within the 2 minutes wins.
  4. We still haven’t figured out what the winner is going to get.

My initial plan was to write a script using go (something which I’ve been planning to learn for a while), but ended up just using ab

My only worry is that since this is a single web server with not many scaling options if I hit the server with a very high concurrency, it might end up chocking. So, I ended up running ab with multiple concurrent options.

Concurrency LevelTotal TimeRequest countRequests per secTime per requestConnection Times
     ConnectProcessingWaitingTotal
50137.5461200087.2411.462218353352570
100131.481200091.2710.9572198718701090
200126.3041200095.0110.525218186918682087
250119.74712000100.219.979219225022492469
300126.9551200094.5210.58222290429033125
30078.36912000153.126.531220170817071928
30080.17912000149.666.682222175117501973
30075.94112000158.026.328222164316431865
30076.48212000156.96.373222165516541876
30079.31112000151.36.609220170717071928
30091.52912000131.117.627220203220312252
350108.37612000110.739.031221288928883110
400114.42412000104.879.535222350235013724
40089.53712000134.027.461223270627062929
400114.0912000105.189.507223352335223746
400121.5051200098.7610.125223377037693993
40086.61512000138.547.218223261126112834
40096.38812000124.58.032222293529343157
500102.69712000116.858.558226297429734201
50095.55912000125.587.963226365036493875
600104.15112000115.228.679230484848475078
700115.3512000104.039.613239626762666506
750118.04912000101.659.837240663466346874
800115.70912000103.719.642245725972597505
900110.16912000108.929.181248764476437892
1000119.04112000100.819.92256903390339289

The only number to worry about is time taken. Here is the plot of the time taken to hit 12K requests vs concurrency level.

Looking at the graph above, guessing 300 concurrency is the best.

Results

We ran the script thrice for 2 minutes. Each of the run was a completely different where thing were good, bad and finally evil.

Fair Run

I let her script run for 2 minutes. A very fair game. I didn’t do anything to disrupt the overall timings or anything at all. In this one, I was able to run 12923 rows. Aditi was able to get only 12140 (though the script had a few extra print commands in it). When we ran the same script in her machine, she was able to hit close 11k+, and my ab script reached only 8k. We both mutually decided to consider the first result which ran in my Linode server and agreed that I won the contest. We may do a re-run soon after we fix some issues in our code.

Unfair Run

It is hard to be fair in a game, where you have so many ways to break the rules. This time, I was running another script to fetch the data while she ran her script to insert new records. The reads were hit at a high rate, that the simple SQLite server couldn’t handle both the reads and writes. And all I had to run was

ab -n 10000 -c 500 https://aditiflaskcrudapptutorial.herokuapp.com/

Evil Run

Taking the unfair game to the next level, this time I tried to be pure evil. I was running another script to actually delete the rows she was adding while she ran her script. In fact, she even wrote this 3 line python script, which made the job a lot easier for me. This was fun 🙂 The only catch is to delete only a few rows so that she doesn’t get suspicious.

import requests
for i in range(1, 5000):
  content = requests.get('https://aditiflaskcrudapptutorial.herokuapp.com/delete/'+str(i))

Overall, this was a fun experiment. Even though I won, what matters the most is that we learned a bunch of things about ab, timeout, and how a single web-server behaves under pressure.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.