5 reasons not to use a micro ORM

If you haven’t come across the concept of a “micro-ORM,” it refers to a currently fashionable category of data mapping tools which take a minimalist approach to mapping between the database and object worlds. Typically the focus is on materializing a data reader row to a class. That’s the key functionality although features do vary. A developer would typically write inline SQL for the query they wish to run. They are fairly simple, and that’s their point — to not have the weight of a fuller featured ORM.

We do get asked by people who have started to hear about micro-ORMs: when would I choose a product like LightSpeed over a micro-ORM? Both address the same basic job of mapping between SQL data and in-memory objects, so why use one rather than the other? So here are some of the times we think you’d want to use a fully fledged object-relational mapper.

1. You’re not Stack Overflow

Stack Overflow has become the ‘go to’ reference site for micro-ORMs. I mean, if Stack Overflow built a micro-ORM to squeeze out the performance they needed, that means they’ve got to be good, right? But I’ll let you in on a secret: you’re not Stack Overflow.

Stack Overflow is a huge site under extremely heavy load. That makes their performance tradeoffs entirely different from most sites or applications. Most developers, as long as they’re not introducing any performance killers, should be focusing on productivity, not on micro-optimising performance. Rather than handwriting SQL and forgoing additional benefits like validation, integrated migrations and many more nice-to-have features to gain the benefits of needing a smaller server farm, most companies find developer productivity is where they can save more money.

2. You’re not building a throwaway app

Some folks feel that it’s quicker to get up and running with a micro-ORM than with a full ORM. And if it’s quicker to get up and running, that means the micro-ORM is more productive than the full ORM, right?

Well, maybe. Some ORMs do require quite a bit of configuration or repetitive mapping. We’d like to think that LightSpeed isn’t one of those. We reckon that with LightSpeed you can be up and running in less than a minute. Plus you can actually gain time by having LightSpeed create the database schema for you, rather than having to jump across into a database tool.

But fair enough, it does take longer to install LightSpeed than to pull down a micro-ORM via NuGet. So if you’re only going to be spending ten or fifteen minutes on your application, then that might be decisive. But for most realistic applications, the productivity benefits of a full ORM rapidly overtake the time savings of running an installer.

3. You want a domain model

A lot of micro-ORMs are just a class for materializing a database row into an object – either to a concrete class, or to an anonymous type. ORMs like LightSpeed, NHibernate, LLBLGen etc offer far more than just object materialization. If you want to express business logic, have validation, etc. then you either want a higher-end ORM or you want to spend your time writing a lot of tedious boiler plate code. And you probably have better things to do with your time than write tedious boilerplate code.

A domain model also pays off when you’re not the only one working on the project. Encapsulating business logic and validation in the domain model ensures that the business rules apply wherever the objects are used — you’re not relying on everyone remembering to apply the latest rules to their bits of the project. That’s one of the reasons we stopped using DataTables in the first place, remember?

4. You like LINQ

Most micro-ORMs do not include a LINQ provider. Most in fact require that you write the SQL yourself. That isn’t in itself a bad thing, it’s just taste and portability concerns and, frankly, most people don’t move database engine anyway. However, a LOT of .NET developers like LINQ. Many, many more than like SQL. Intellisense, compile-time type checking and compile-time syntax checking combine to make you more productive and to catch errors earlier.

And if you like LINQ, then you’ll want an ORM with a good LINQ provider. That means the LINQ actually translates to SQL, not a supposed LINQ provider that actually pulls all of your data into memory and then uses LINQ to Objects — that will throw away any performance gains you thought you’d be getting from the micro-ORM — and then some.

5. Your data usage pattern isn’t dominated by isolated records

There’s some great performance benchmarks out there for micro-ORMs. Unfortunately, there are a bunch of, well, less great ones too — benchmarks that don’t test real world situations.

If you’re going to be guided by benchmarks, make sure that the benchmark you’re using reflects how your application uses data. For example, suppose your application issues multiple queries to the database, some of which could result in the same entity being returned. Most micro-ORMs don’t use an identity map, so they’ll trundle off to the database and materialise a new copy of the entity. Most full ORMs, by contrast, will see that the entity is already in memory, and save themselves the query and/or the materialisation. And, by the way, they’ll give you handy object identity behaviour instead of you having to write code to test if Instance A represents the same record as Instance B. A typical full ORM is built to have a higher level view of how real world applications are built, and can gain significantly on the performance front by performing these optimizations.

Of course, your application may have special performance characteristics that mean a micro-ORM plus custom performance strategies will perform better than a general-purpose ORM tuned for a typical mix of applications. Stack Overflow is a great example — its performance requirements are so extreme that it’s worth the effort of building that stuff in a way that works for them. You have to ask yourself whether your application justifies that custom construction cost.

And one reason *to* use a micro-ORM

Choosing between a micro-ORM and a higher end ORM shouldn’t be a religious decision. There are certainly places where a micro-ORM makes sense — when you don’t need domain logic, you want to work very intimately with the database, the application is very limited or ad hoc in its scope… an example might be a simple bulk data transfer application, where things like an identity map and validation don’t add any value. We use micro-ORMs at Mindscape when they make sense, and it’s given us an appreciation of their value as well as where they come up short.

So what do you reckon? Are these the key points to consider when deciding between a full and a micro-ORM? What are your reasons for using or not using a micro-ORM?

Tagged as LightSpeed

24 Responses to “5 reasons not to use a micro ORM”

  • There’s a lot of words and here-say here which does highlight your natural bias towards using a heavy-weight ORM. Unfortunately there’s not a lot of real-world examples to justify your reasoning, so instead of just ‘telling us its better’ why don’t you provide some typical real-world examples that shows us when it’s better to use a heavy ORM?

  • Personally I don’t see the point in Micro-ORM’s, other than being a nifty little project that someone can come up with in their own time. They don’t really offer much more than ADO.NET supports out of the box other than a wrapper around creating a connection/command/reader, all of which you could write up yourself pretty quickly.

    Not to mention you can use AutoMapper : https://github.com/AutoMapper/AutoMapper
    to map IDataReader results to an object.


    A method that works great, that I use for mapping DataSets from Analysis Services to the same business objects used for NHibernate.

    Having said that, I don’t buy that StackOverflow is an exception to the scalability rule that they need to re-invent the wheel by using a Micro-ORM.

    Each Stack Exchange site has a different database, or, atleast a database table for each site.

    Their latest Questions on Stack Overflow are up to 8 million, while Server Fault is up to 330,000.

    Thats a drop in the barrel compared to sites out there which run on ORM’s with 10’s of millions of rows.

    Where I work we use NHibernate on databases that exceed 1TB with tables exceeding 2 billion rows, although we don’t suffer from the amount of network traffic StackOverflow does, we have no issue returning results in ~1 ms.

    In cases where an ORM gets in the way, such as bulk inserting, we just revert back to good old ADO.NET for that.

    Micro-ORMs are the new NoSQL… except NoSQL makes sense.

  • By ‘typical real-world examples’ I mean actual code: i.e.

    – What’s a real-world example that shows the productivity benefits of using a Heavy ORM?
    – What’s an example that shows where a Heavy ORM would perform better?

  • >> Personally I don’t see the point in Micro-ORM’s…

    Well there are also many others that don’t see the need for Heavy ORMs which is why I’m asking for tangible clarity on when using one makes sense. I just see a lot of opinion here and I think real code examples would go a long way into providing much needed clarification.

    Also Micro ORM’s actually provide much better APIs than the underlying DataReader that’s suggested, a good overview of .NET Micro ORMS showcasing their APIs are visible at:

    Many of them actually have more succinct and terse APIs than their Heavy Weight companions. I think it’s a bit dismissive to right them off completely, a lot of them have unique features which make them productive in their own right.

    >>Having said that, I don’t buy that StackOverflow is an exception to the scalability rule that they need to re-invent the wheel by using a Micro-ORM.

    Note: Striving for performance isn’t just for scalability, it’s primarily about achieving instant response times and it’s been shown that LINQ providers (especially ones without using compiled queries/LINQ expressions) cause noticeable overheads. Examples of this overhead can be found on Dapper’s benchmarks (where most Heavy ORMs perform comparatively poorly):

    >> Where I work we use NHibernate on databases that exceed 1TB with tables exceeding 2 billion rows

    I think everyone touching a database knows it’s not the size of the db that affects ORM performance, it’s how many rows that’s fetched back. I really don’t see how this proves NHibernate can handle 1TB tables w/ 2B+ rows – unless it actually iterates over the entire table at acceptable performance, is that what’s being suggested here?

  • The problem I have with heavier ORMs is that they are full of features I’ll never use. This leads to abstraction laid upon abstraction just to make the whole thing “fit”. Like every other aspect of architecture I am in favour of composing my approach rather than taking something that is designed to be the one true answer (monolithic) and trying to make it work for me.

    Wanting domain objects doesn’t make the microORM pointless – it allows you to compose a Domain model and lifecycle yourself using the tools and techs you want rather than “making do” with what your heavyweight ORM would offer. Sure there is a bit more work involved but it likely balances out with the fuzzy time wasting that comes with understanding big ORMs and their Domain Models. At least from my experiences.

    There are times I have used microORMs, times I’ve used EF (yes a lot of the time it is simply good enough) and times I’ve went with CSLA and iBatis. It’s horses for courses. However the further up the ORM scale you go you begin to introduce more and more accidental complexity into what should be a simple solution. That makes me wary of them. Much in the same way I stay away from large products like Sharepoint – I am not a product configurator I am an engineer – I don’t want to fight with other peoples assumptions about how my solution should work.

    My $0.02.

  • I’ll ignore 1 (just too easy ;p), but: in my previous work, I’ve still seen a **lot** of code that uses ADO.NET (or sometimes entlib) to talk to the database, using TSQL that has been written by the devs (either directly or indirectly), and then mapped back onto the objects.

    THIS IS NOT UNCOMMON. Let’s not make it hard to do, eh?

  • Phillip, the number of rows is not the reason reason Stack Overflow use a ‘micro ORM’. The reason is because they are handling millions of users per day, probably hundreds of millions of queries executed, all against a single database server. They need to optimize their queries, not rely on what the ORM spits out.

  • Hi, thanks for this article.

    I’m currently evaluating ORMs for my next project. You talk about the quality of benchmarks not testing real-world scenarios.

    Do you have any links to benchmarks you think are a true reflection of real-world scenarios?

  • I have seen the dataobjects.net guys dogfood their ORM on the new project 9facts.com

    I really think, there is many benefits in comprehensive ORMs. The idea of preventing some repetitive tasks and benefit from Linq and other features.

  • @Phillip – The reason Stack Overflow uses/built a Micro-ORM is entirely around performance. The size of the database isn’t the issue, that’s *entirely* a SQL-side scaling problem with respect to speed. The cost we’re troubled with in serving ~40 million requests a day on the network (as of this comment) means we issue quite a few queries, and the cost we saw with Linq2SQL was both generating the SQL query from the expression tree and much, much worse: materialization of the result set. To be clear: query speed on the SQL side was never the issue here, though Dapper allows us more flexibility there to write many query cases easier/faster.

    We’re not talking about a small 1% cost for the materialization here, we were routinely seeing inexplicable 500ms+ operations on very simple queries. We can reproduce this pretty reliably by just reverting any number of the L2S queries converted to dapper in our repo. When we can get that down to <2ms with identical results, of course we're going to go that way, when you multiply that by millions it really adds up to a lot of wait time, and pages being that slow is crazy from our perspective…performance is a feature.

    If you want to test or contribute to performance comparisons, we keep them all open source on dapper's homepage: http://code.google.com/p/dapper-dot-net/ You can see the time benefits there (or, download and test yourself). We always appreciate new tests, suggestions, bug reports, etc. As it relates to this article: unfortunately we can't host the LightSpeed libraries in the dapper repo due to their terms, and as a result can't add them to the downloadable/runnable performance test suite.

  • Some good points, but perhaps you could have mentioned cost and portability of license in your comparison :)
    There are many awesome products out there, like Lightspeed, but if you want to use & distribute them in an MIT project and have anyone of your contributing developer-base work with the product to contribute sourcecode, not all of them fit.

    On another topic, it would be great if you guys picked up the baton of ormbattle and added Lightspeed to the test suite. The site is a bit out of date but there are reasonable recent results here http://code.google.com/p/ormbattle/source/browse/Output-LINQ.txt

  • > Choosing between a micro-ORM and a higher end ORM shouldn’t be a religious decision.

    Agree wholeheartedly. They’re both tools in the toolbox.

    I think if you need to be close-to-the-metal, you use ADO.Net or a micro-orm. You accept more tedium for more control.

    If you want more of the out-of-the-box benefits of an ORM, go that route.

    Choosing a lightweight solution doesn’t mean you can’t do DDD or validation or caching or have identify maps though… it just means you have to deal with them yourself. Maybe you feel that’s an unreasonable solution and I wouldn’t argue with your opinion.

    > In cases where an ORM gets in the way, such as bulk inserting, we just revert back to good old ADO.NET for that.

    Beautiful. A micro-orm is just ADO.Net + Automapper really though. There’s not much of a philosophical difference here IMO.

  • @Alex Norcliffe Thanks for your comments. This wasn’t an exhaustive comparison, more a cutely worded response to questions we receive quite often. We obviously bridge two worlds as software developers — commercial and open source – where the two can work together but in terms of our readers, they’re often from the commercial side.

    We used to be part of ORMBattle, but we requested removal. The numbers looked very wrong to our own measurements and when we were told ‘you can just get the source and try it for yourself!’, the code couldn’t even compile. Given it was built by a competitor we became quite dubious that things were a little rigged. We tried repeatedly to get the tests into the state that they were used to generate the numbers being shown (even if just relatively) however never could. We gave up and requested removal. We might post some numbers on other benchmarks but, honestly, they appeal to some folks, and turn others off a lot because they are quite often arbitrary. We do use the Dapper benchmark internally, and we do very well in that (floating about the point of Peta Poco at last test, which is pretty damn quick for a full ORM).

    Just a quick note also, we now have the ability to provide exclusion licenses for open source projects with LightSpeed. This means you can ship LightSpeed Express with open source projects but the entity count limit is not included (which effectively makes it the full edition for your project). More about this soon :-)

  • @Jake Thanks for your comment. Honestly – not really. You could look at taking something like a popular open source website, load it up with data and run performance tests over it which might give a better indication. The issue with benchmarks is often the people writing them are focused on what is valuable to them — in the case of micro ORMs this is often object materialization & hydration speed. For us it might be reducing queries to the database. That’s all handy but what the end users are looking to gauge may not be represented by these micro benchmarks.

  • @James Hughes Thanks for your comment. Sure there’s features you might not use but that’s not a reason to ignore a fully ORM. I’d say it’s a reason to evaluate the quality of the API. For example, I think we’ve done a pretty good job at making sure that features you don’t need aren’t in your face or causing you extra burden, but I know some products (not just ORMs, just frameworks in general) where that’s not the case.

    There’s always an edge case, but I’m not a believer in developers spending time having to manually build up basic infrastructure like common life cycle functions, or domain driven aspects of their models. There’s bigger problems to solved typically. I take you point of not being a product configurator — in fact it’s one of the reasons we started Mindscape, we were not liking the way the services space seems to be moving more in that direction — but you can still engineer amazing code on top of an ORM. I’m not sure if you’ve tried LightSpeed but I’d love to hear your impressions if you did :-)

    Thanks again for your feedback.

  • @Jeff Van Dusseldorp Thanks for your comment. Sorry if the post seems to suggest that micro ORMs don’t allow DDD or other concerns. The point was more that in this day writing some of those things by hand is almost entirely a waste of your precious time. Sure, you could do it, but why would you? It’s like when I see folks extolling the benefits of POCO’s and avoiding base classes and then having to add thousands of lines of boiler plate cruft to each entity — it offends my sense of productivity and pragmatism to see developers wasting their smarts on such things.

    Of course, with everything, it’s not black and white – there are cases for almost every possible solution.

  • @Marc Gravell Thanks for your comment :-) There is absolutely a lot of code like that out there and people still writing code that way. It makes sense in certain situations. Your point of ‘mapped back into objects’… In my opinion, micro ORM if fuller featured ORM typically make that easy (well, maybe not so easy with NHibernate… *ducks* :-) A lot of the rest comes back to personal and project preferences.

    Thanks again for your comment.

  • I use both. I use a regular ORM (LightSpeed) for 90% of the application and for areas that are performance sensitive or have queries that can’t be written using LINQ I use a microORM (Dapper.NET) calling a stored procedures.

  • @Nick Craver – Thanks for your response. I completely understand your reasoning around the performance of L2S. I’ve seen similar things using the LINQ provider with NHibernate, something that for the most part goes away when using QueryOver/Criteria.

    @David – you seem very defensive, but hide your identity. :( your last point makes no sense at all.

    @Craig – As Nick said, it’s not really the query thats generated by the ORM that’s the issue, it’s the performance hit generating the query.

    Most project, maybe 90% + of all projects people work on are never going to be serving up the amount of data/requests StackOverflow does, there’s no reason to not use an ORM to start off with, just like StackOverflow, and when scalability becomes an issue, begin to tune the application, if it’s fixing indexes in your DB, introducing caching in some parts for static data, removing the ORM in some parts for ADO.NET or a Micro-ORM. Worrying about that stuff on day one is a waste of time and the productivity gained from using an ORM is worth taking a slight performance hit for.

    In my opinion.

  • Hi @Phillip,

    I’m not sure I subscribe to the fact that full ORMs are *more productive* than Micro ORMs which IMO has a better chance of working as you’d expect: i.e. less chance to be bitten by some magical/quirky behavior or mis-configuration that’s out-of-sync with your C# classes (since most Micro ORMs operate on POCO’s that map 1:1 with RDBMS tables).

    My rationale for developing my own Micro ORM was actually to *be more productive* (that’s even with the expense of developing it) since I can dispense with any configuration and code-gen overhead and simply use clean POCO’s to interface with databases. Using clean POCO’s it’s nice as it stands a better chance for re-usability in contexts outside of an RDBMS. There’s actually no Heavy ORM I’ve used where I can easily call an external service, map the results to a POCO and persist it to an RDBMS as I’d expect it to (i.e. with complex property types stored in schema-less text blobs), without the productivity overhead of intialization and configuration of a full ORM. As a bonus I get to enjoy a runtime perf bonus – so at a min, in this use-case where you want to persist adhoc external data you don’t have control over – it’s a major productivity and perf win.

    At work when we struggle to get Linq2Sql to behave how we want we now simply fallback to using a Micro ORM and call the RDBMS using SQL we expected the LINQ provider to generate but for some reason doesn’t. We used to spend hours researching obscure behavior – now we just use a Micro ORM without a second thought.

    Based on my experience with Heavy ORMs in the past (and currently at work) I no longer choose to use a ‘Heavy ORM’ for my own personal projects. Opting instead to use a Micro ORM or a NoSQL solution.

  • […] 5 reasons not to use a micro ORM – The team over at MindScape discuss why you might not want to use a Micro-ORM, and choose a traditional full blown ORM like their own LightSpeed ORM. Interesting discussion on this subject in the comments of this one. […]

  • I also use both. Currently switching out part of an application to use CQRS – makes sense to query readonly tables (aka viewmodel) via dapper.NET rather than LightSpeed. The rest of the app which actually does writes and needs an intelligent domain model I use LightSpeed…

  • Do you work for LightSpeed by any chance…

  • @Ollie Riches Thanks for your comment. Work for Mindscape, sure. I don’t think I was making much secret of that given it’s on our site though :-)

  • Leave a Reply


Join our mailer

You should join our newsletter! Sent monthly:

Back to Top