Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by email or phone:


+972 52-548-6969

, @ Q j

Posts: 6,691 | Comments: 48,561

filter by tags archive

NH ProfQuery Duration

time to read 1 min | 154 words

One of the more popular requests for NH Prof was to be able to track query duration not only for select statements, but for all statements. It took a bit of work, I’ll admit, far more than you would probably assume from the screen shot, but it is here:


What you can see now is that the duration is divided into the time a query took in the database and the total time a query took. For the most part, there wouldn’t be much of a difference between them, but it is occasionally interesting to see the difference. It is also a far more accurate measure than the one that we used to have.

This is available from build #349, and using NHibernate’s trunk or 2.1.x branch.

An end to the Mac era

time to read 2 min | 243 words

Well, it is about time that I get myself a new machine. My laptop is 1.5 years old, and it is starting to creak around the edges, not to mention my envy when I see what new systems can do.

But the most important decision I made was that I don’t intend to get a Mac as my new laptop. I own two Macs, and I am a very happy user of them, but after using them for so long, I can no longer really justify the Mac tax in comparison to the feature set that I am getting from it. This is particularly important when I consider the next laptop that I want to have.

This time, I am going to play the spoiled child and get myself a real monster:

  • Quad Core CPU
  • 8 GB RAM
  • 256 SSD HD

I am still considering whatever to get a 17” or a 15” screen. I am leaning both ways at the moment, but I’ll probably end up with the 15”.

One thing that I would really like to have is a mousepad that is similar to the Mac’s. I find that this is about the most natural way of working with the mouse now, and trying to use other mousepads, especially without having the two finger scrolling is just painful.

Anyone can put in a good recommendation?

NH ProfExposing the data that you already have

time to read 1 min | 119 words

One of the things that drove me mad with NH Prof is that at times it was hard to visually see when a session went to the database a lot or hit the cache frequently. I mean, you most certainly had that information if you drill into the session itself, but there is really no excuse for not giving that information to the user directly.

Hence, the following screen shot:


I am back to working on NH Prof full time, and I love the way everything is set up. Time to feature is ridiculously low.

NH ProfGetting big, and bigger

time to read 2 min | 201 words

Well, at least now I have proof positive that all the architecture work that we did in order to ensure that NH Prof will scale better actually works. The following screenshot shows an example that used to crash NH Prof, it loading an 80 MB file with over 200,000 individual events to scan and process.


The fun part is that this is run through the entire pipeline, but without involving the UI, so we get the ability to process all those events without having to wait for the UI. If you remember, we had to invest a lot of time making sure that this sort of scenario will work properly.

Now, it takes 85 seconds for this to load, which I consider pretty reasonable, it means about 2,350 events per second, which isn’t a high number, but is plenty fast enough overall, considering the amount of work that I have to do in order to do things like calculate alerts, format the SQL, and do all the other things that NH Prof has to do.

NHibernate - <natural-id/>

time to read 3 min | 415 words

A natural id is a way to refer to a unique field of an object as a substitute of the real entity identifier. A good (and typical) example of that would be with the User entity. We have the user name and the user id, both are unique, but the user id is usually something that is generated by our application and has no relation to the a human being. In other words, user #123814 doesn’t mean anything to me, while user ‘ayende’ has a meaning to us.

There are many reasons for choosing this approach, but the most common one is that we want a small primary key, since it is duplicated to all related tables (especially important for things like user, which is associated with just about everything).

So far, it doesn’t seem really interesting, right? Why am I boring you with talking about this?

Well, it is all about the second level cache and optimizing access to it. Let us take a look at how we set it up:

<class name="User"
	<cache usage="nonstrict-read-write"/>
	<id name="Id">
		<generator class="identity"/>
	<natural-id mutable="false">
		<property name="Username"/>

And now we are going to query it:

using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
			.Set("Username", "Ayende"))


<natrual-id/> is used almost exclusively for documentation purposes. That means that internally the query above will be translated to:

using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
		.Add(Restrictions.Eq("Username", "Ayende"))


Well, almost. There is one subtle different between the two. When querying on <natural-id/>, we also bypass the usual expiration check in the second level cache implemented by NHibernate.

That means that even if we changed the underlying table, NHibernate will not automatically expire the results in the cache for this query, it will still consider it valid, because it assumes that like primary keys, there isn’t really a reason to perform an expiration check on natural ids.

NH ProfNHibernate Profiler vs. Sql Profiler

time to read 1 min | 149 words

I recently got a question, asking why someone should pay for NH Prof if SQL profiler is available for (effectively) free?

The answer is actually very easy to answer. I run the following scenario through both NH Prof and SQL Profiler:

using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
			.Set("Username", "Ayende"))


using (var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
			.Set("Username", "Ayende"))


Here is what NH Prof gave me:


And here is what I got from SQL Profiler:


I think that I have rested my case, pretty conclusively.

NH ProfArchitectural Overview

time to read 2 min | 382 words

I am pretty fond of the way NH Prof is architected.  At a very high level, it looks like this:


The first part isn’t really that interesting, the main challenge is to get the data from your application to the profiler in as speedy and performant way as possible. We are using a binary protocol based on Protocol Buffers with TCP Sockets as the communication mechanism.

Next we have the listener and the message processors. That is where a lot of the magic actually happens, we do first level analysis on the incoming log messages and transform them into higher level concepts. At this point, we are only dealing with a single message, we have no overall picture, but a lot of work is actually happening at this layer.

It is there that I normalize the differences between all the NHibernate versions that I support and make sure that the other layers work on a common object model.

The next stage is the model building, where I am actually taking all the information and start putting it together, it is there where concepts such as sessions, and statements in session start making sense, it is there that I actually apply analytics to provide you with the alerts. It is a pretty complex piece of code, taken together, but each individual part is pretty simple.

Next, we have the view model, which is another representation of the model in a format that is applicable for showing to the user, I have spoke before about moving from a push to a pull model, in order to allow the UI to remain performant. That has been one of the major challenges in that area. Well, that and making sure that we have good UX.

The interesting part about this architecture is that a new feature is usually something that happen either in the listeners and the model building (when it match the current model that we have) or a vertical slice across the entire layer, when we need to express some new concept.


time to read 1 min | 87 words

Notice: I am not going to respond to comments to this post.

Just an interesting observation, there are Bad Things currently happening in Iran. And overall, the only response that we see is a mumble here and there. Compare it to the reaction of the world to any incident in Israel in the last four decades, and I think that you can see the problem.

As far as the world is concerned, it looks like the Iranians are second class people.

What happens in DevTeach...

time to read 1 min | 132 words

Tends to leave lasting impressions.

You might have noticed that I have been sort of quite lately, I have been in DevTeach last week, and I more or less had zero time to do anything that wasn't actually DevTeach. I can honestly say that this is, hands down, one of the conferences that I most enjoyed period.

We spent so much time in the Hotel's bar that the bartenders knew us all by name.

I don't think that I can really do justice to the last week with any recap, let me just point out that most of it was recorded on Twitter, and that there really isn't any way to explain if you weren't there.

It was busy, full of fun and exhausting, and I was half grateful and half sad when it was over.


  1. RavenDB 4.1 Features: MongoDB & CosmosDB Migration Wizards - about one hour from now
  2. If you stay in the office any longer, I’ll start charge you rent - about one day from now
  3. You know too much - 2 days from now

There are posts all the way to Aug 21, 2018


  1. RavenDB 4.1 features (12):
    04 Jul 2018 - This document is included in your subscription
  2. Reading the NSA’s codebase (7):
    13 Aug 2018 - LemonGraph review–Part VII–Summary
  3. Codex KV (2):
    06 Jun 2018 - Properly generating the file
  4. I WILL have order (3):
    30 May 2018 - How Bleve sorts query results
  5. Inside RavenDB 4.0 (10):
    22 May 2018 - Book update
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats