Gorm Vs. Xorm (part 1)

And the state of ORM’s in GoLang

Sumit Agarwal
4 min readAug 29, 2020
Image Source: Google

With this one, I continue to explore GORM through the series of articles. In the past, I have talked about my learnings about GORM and shared plugins like audit and batch upsert. In this article, I want to share the experiences I had while using two different ORMs, GORM(MySQL) and XORM(Oracle) namely, for handling two different databases.

I also took this opportunity to explore the overall state of ORMs in Golang and will try to throw some light on it. So, let’s get started.

First, I would like to explain how I ended up using two ORMs, even worse, two ORMs for the same project. It all started with a simple use-case where I wanted to power the UI using MySQL database, as GORM was already widely being used in my organization for all MySQL-related work, I went with the flow. #mistake

Slowly, as the requirements evolved I had multiple use cases where I wanted to interact with Oracle databases as well. That’s when the actual problems began, I came to realize GORM doesn’t support Oracle dialect(until recently). Hence, I ended up using XORM.

Coming back to the topic of discussion for this article, whether GORM or XORM? Primarily I will use 3 factors two compare the two ORMs:
1. Popularity
2. Benchmarking
3. Features Supported

1. Popularity

Data collated from GORM and XORM Github repositories

At the time of writing of this article, a google search for ORMs in GoLang shows GORM as the first item and XORM is not even on the first page of results, go ahead try it. I understand that doesn’t sound like a very objective comparison. So, if we consider the GitHub stats as a parameter for popularity, undoubtedly GORM has an edge over here. But is it actually that good? Let’s do some benchmarking.

2. Benchmarking

For this benchmarking, I have used a simple MySQL table with five data types (int, string, bool, double, and time) in 5 columns as I suppose these are the primary types used for most use cases. Also, to keep things simple I kept away from indexing and keys at the DB level.

Note: all the benchmarking code was run locally and no network latencies have been taken into account separately.

1X Load benchmarking:

Minimal Load

10X Load benchmarking:

10X Load

50X Load benchmarking:

50X Load

If you closely observer the numbers in the three different loads above, you see the following pattern:

  1. Undoubtedly the raw queries are the best. But they have their own downsides due to which the ORMs came into existence in the first place. So we will not brainstorm on it.
  2. Insert: XORM is the clear winner over here with GORM taking almost 1.3 times more time as compared to XORM.
  3. Batch-Insert: Since GORM doesn’t even support this functionality, we can safely say XORM has an upper hand on this.
  4. Update: Again XORM has clearly shown that it is better than GORM by performing the same tasks on the same payload in under less than 33% time of what GORM takes.
  5. Read: GORM has performed somewhat better in the case of the read operation, XORM took 1.06 times more time than what was taken by GORM.
  6. Bulk-Read: Here also, GORM took lesser time to perform read as compared to XORM.

Overall, we can safely say for now that XORM has better performance when it comes to DML operations and GORM is good when your application is READ heavy. So if I am designing an application that is write-heavy, then my choice would be XORM. Having said that, so far, XORM also looks like an overall better choice because its read operations are not so bad as compared to GORM, whose update operations are 3 times more time-consuming.

You can find the code used for benchmarking here.

Will soon add part 2 outlining the feature differences between the two, where I will also explore the other GoLang ORMs. Thanks, hope you find this useful in your decision-making for ORMs.

ORM HATE!

--

--

Sumit Agarwal

I am a software developer at heart who likes to travel and has a profound interest in design, art, and literature.