Is neo4j really as good as it says it is? Maybe not.

There’s a long introduction. For the interesting juice, click here

Whatever new technology comes along, it is accompanied with a “great deal.” I don’t just mean an above normal coverage, I mean a big promise that you’re getting a great deal by using/switching/adopting/etc.

In neo4j’s case, it was no different.

During our Information Management course, we had to dig into graph databases and neo4j was right there waiting for us. In the process (of digging), we were sucked right in. All information we read were pointing in just one direction — neo4j is awesome.

And maybe it was. But there was a problem — why wasn’t there “another side of the story” anywhere? All strong comparisons were posted to prove that neo4j was better in doing certain tasks than the most common RDBMS out there — MySQL.

The Midterm

After spending 6 weeks digging into neo4j and believing all the resources we read (and we read a lot! Online resources, literature, etc.) we showcased to our class that neo4j was amazing. However, our Professor was not convinced. Instead, she asked us: could there be a neglected side to all this?

We set journey to at least try and duplicate these data to see if they had any truth to them. We came across this blog post by Jörg Baach, with exactly the same goal as us — seeing if it was the entire truth. Baach had posted the code he used for his tests, which we based our work on. (His original work could be found here.)

The information that we wanted to duplicate and at least have a go at were retrieved from Baach’s post, and this paper as well.


Our code is on github:

The work we did consisted of four main tasks:
1. Installing the appropriate software (and tuning as necessary)
2. Generating the appropriate data
3. Importing the generated data in both database engines
4. Running and reporting the tests

Installing database engines

We installed neo4j as normal, and used the properties provided by Baach to further tune the setup. This set of properties added indexing features and increased the buffer size of neo4j. Refer to Baach’s blogpost for information on how to tune both MySQL and neo4j further.

The requirements are, however:
– Python (with MySQLdb module)
– Neo4j and MySQL (obviously)

Generating the appropriate data

To generate the data, we ran ``:

$ python 1000

This created a `data/pickle.1000` file that included 1000 friends information, with 50 outgoing relationships each. This was stored so we’d have identical information in both cases. (You can change the 1000 to any number you desire, but keep in mind the time factor.)

Importing the data

To import the data, we ran ``

$ python mysql 1000
$ python neo4j 1000

Running and reporting

After warming the cache, we run the tests and reported times with the `` script

$ python mysql 1000 3
$ python neo4j 1000 3

The 3 in this case is the number of hops the script would need to test against. The query is ran 10 times with different starting points and average time is reported. The sample query is printed out in the first run for reference.


The reported results were as follows — the paper reported:

        MySQL     neo4j
S0      19.56     8
S1      33        12.65
S2      111.334   19.57
S0      281.38    10
S1      333.96    17
S2      620.56    21

This set of results clearly showed neo4j outperforming MySQL in every criteria tested. Baach, however, reported the exact opposite:

        MySQL     neo4j
S0      0.000     0.010
S1      0.001     0.018
S2      0.072     0.376
S0      0.000     0.010
S1      0.002     0.017
S2      0.082     0.484

His results showed MySQL in fact outperformed neo4j (he even reports his python implementation was even faster than both!) We reported results that were quite different than both:

        MySQL     neo4j
Our Results
S0      0.0050    0.0417
S1      0.0357    0.1503
S2      1.3740    1.1313
S3      64.547    ∞


The following remarks could be made about the obtained results

  • H0: MySQL has great indexing capabilities, allowing it to outperform neo4j up to two levels of relation hops
  • H1: neo4j’s graph traversing powers come to use starting to query more than three levels of relationship hops
  • neo4j is extremely resource intensive. This might be the reason behind it not reporting results for four levels of relationship traversal. We speculate it would outperform MySQL if it did complete.
  • Needless to say, tuning plays a great role in the execution times. Further tuning would be needed to produce more robust results

Twitter Bootstrap Callouts

Callouts are used on the Bootstrap docs to highlight important contents (hence; callouts). Unfortunately, they are not shipped with base bootstrap.

To add (and use) Twitter bootstrap callouts, here is the additional markup you need

 * Callouts
 * Not quite alerts, but custom and helpful notes for folks reading the docs.
 * Requires a base and modifier class.

/* Common styles for all types */
.bs-callout {
  margin: 20px 0;
  padding: 20px;
  border-left: 3px solid #eee;
.bs-callout h4 {
  margin-top: 0;
  margin-bottom: 5px;
.bs-callout p:last-child {
  margin-bottom: 0;
.bs-callout code {
  background-color: #fff;
  border-radius: 3px;

/* Variations */
.bs-callout-danger {
  background-color: #fdf7f7;
  border-color: #d9534f;
.bs-callout-danger h4 {
  color: #d9534f;
.bs-callout-warning {
  background-color: #fcf8f2;
  border-color: #f0ad4e;
.bs-callout-warning h4 {
  color: #f0ad4e;
.bs-callout-info {
  background-color: #f4f8fa;
  border-color: #5bc0de;
.bs-callout-info h4 {
  color: #5bc0de;

About Being #ForeverAlone

People are horrible.

They’re unpredictable, and unless you live in heaven, they’re usually full of shit. People are boring. Not just the boring kind, but the fun kind too. Everything eventually is boring. People have different schedules. And different tastes. And they object and have opinions. They argue and make it awkward. They don’t get all your jokes. And some even bother you. Granted, unintentionally if they’re nice. But they do.

In my conversations with fellow humans, I like to indulge in the look of shock when I mention I go to the movies alone. More times than I had been with people, as a matter of fact. This is just one of the things in life I enjoy doing alone. I enjoy that same look on movie clerks when I book seats for a movie and I unapologetically pick just one spot. Heck, I once really thought I needed to reward myself so I booked two movies back-to-back.

Continue reading

The Barrel With Few Strings

I once took part in a soft skills course that illustrated our brain keeps memories in a barrel kind of fashion. A lot of everything is stored in sequence, once you remember something or pull on any string, a whole bunch of things come floating up for easier access.

When I was 18 years old my friends and I had been hanging out at a regular internet cafe, play Medal Of Honour among other games (I always won), and just casually have a chat when we’re waiting for our next course or something.

The place clerk has got to have had a very rough love life because for as long as I could remember, he used to play the above song. Day and night. It was just always on.

And for the string/barrel theory mentioned above, whenever I remember anything from the old times, for whatever reason, this song comes right up and I play it in my head a million times.

He Stopped

Red star is my house. Yellow star is the bus stop. Blue star is where the magic happened.

For those of you unaware of the matter, transportation timings in Europe is a very serious matter. If a bus is scheduled for 10:32, 10:32 people start wondering what’s wrong if the bus isn’t at least in eye-sight. It’s top-notch. It lets everyone plan their days right and gives everyone the ability to get things done in decency if they choose to play by the rules.

To make sure that’s the way it is, everything has to go by the book. The bus driver doesn’t wait at a certain bus stop for more than 20 seconds. Literally. Even if someone comes storming down a road so they could make it on time, a driver can simply drive away. Most drivers even don’t stop if they’re not signaled to stop from someone on the bus or if nobody is even in the bus stop already. It saves a few extra seconds which is good for traffic.

I have a single bus stop next to my place. If I miss a bus I usually have to wait for 15 minutes for the next bus but because it was a public holiday I’d have to wait for about 45 minutes for the next ride. My appointment was at 20 past and it was still a minute or two past so I thought I had time to go, forgetting that I had to take the bus at 6 past. So when it was 4 past, it was an ugly scene at our household.

I threw on my pants, a shirt, a jacket, and with no time to even wear shoes, ran out with just my slippers (it’s cold at night. Not a good idea.) I live on the third floor so I had to jump 3 steps at a time down the stairs. I made it to the front porch by 5 past. 1 minute to go. It’s a 3 minute walk to the bus stop and I didn’t even know which side of the street I had to wait at.

I ran like my life depended on it.

I saw the bus presumably driving by, so I ran even faster, but realised there was no way to make it to the bus stop on time. So I stopped. I looked further ahead and spotted the same bus number coming to the other direction bus stop. That would have to be the right one (I was going in that directions thereabouts so that made better sense.) But no one was in the bus stop and it was definitely not going to wait unless someone was going off. I ran more, getting closer but not close enough for him to even see me but I’m running down the street that the bus will be taking so I’m hoping he’d see me and wait for me. I’m really pulling in closer!

He doesn’t see me.

Nobody is even coming off. He’s not even going to stop at the bus stop.

He drives away from the bus stop, and I slow down one last time. As I do, he takes the turn into the street I’m running down, and finally notices me pulling to almost a complete halt.

He realises I was trying to catch him. And I didn’t.

He stops. Not at a bus stop. But in the middle of the street. He stops for me to get on. He pulls over, and waves for me to come on in quickly.

My legs come back on again but my brain is still in shock of what is happening. I see the people on the bus all looking at me and they too are in quite the shock. I turn around the bus and get on.

I go to the front and thank him, still breathing louder than my voice.

Contrary to popular belief, Germans are not emotionless robots. Some of them are really nice people.

Mahmoud Sakr, kamasheto, Mahboud, and everything in between

%d bloggers like this: