How slow is MediatR really?

  Рет қаралды 60,201

Nick Chapsas

Nick Chapsas

2 жыл бұрын

Check out my courses: dometrain.com
Become a Patreon and get source code access: / nickchapsas
Hello everybody I'm Nick and in this video I will investigate a claim around the library MediatR and how it can affect your application's performance. This video will also introduce you to performance measuring and memory profiling techniques.
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasGitHub
Follow me on Twitter: bit.ly/ChapsasTwitter
Connect on LinkedIn: bit.ly/ChapsasLinkedIn
Keep coding merch: keepcoding.shop
#csharp #dotnet #mediatr

Пікірлер: 103
@nickchapsas
@nickchapsas 2 жыл бұрын
Something that I forgot to mention in the video is that, when you add some IO into the mix (database call, api call etc) the difference will get even smaller because the IO will loadbalance it out of the equation.
@jimbob1xghtnm
@jimbob1xghtnm 2 жыл бұрын
Yeah is was wanting to make this comment as well. As realistic as you tried to make it, it is still not really reflecting real-world scenarios. Would love to see an addition to this where some real work is being done, eg calling a DB or external service
@PajakTheBlind
@PajakTheBlind 2 жыл бұрын
And this is not even the beginning of looking for performance - first you need to figure out exactly what part of pipeline slows you down. You can make an educated guess that more often than not it will be the IO. But you may have a really non-performing middleware/container and so on. Unless you find the real culprit it's pointless to sacrifice the architectural cleanliness vs. performance. Thanks for the video.
@Petoj87
@Petoj87 2 жыл бұрын
This is something you should say in all your performance related videos. But great video always something new to learn :)
@GhostTyper
@GhostTyper 2 жыл бұрын
However, the gap also may get bigger, if you don't have the SSL overhead.
@JesseTemple
@JesseTemple 2 жыл бұрын
We use MediatR in a production environment with good results, but I never got this far down into the weeds about it. This was a very interesting video, thanks!
@jradplowman
@jradplowman 2 жыл бұрын
Nick your videos are pure gold. Your presentation and pacing are perfect. Also your approach is so easy to follow! Thanks again for the great content.
@kjbetz
@kjbetz 2 жыл бұрын
Great thorough tests, explanations, and video! Thank you!
@pablocom
@pablocom 2 жыл бұрын
Super interesting how it affects in terms of memory allocation, thanks again Nick!
@ergis8004
@ergis8004 2 жыл бұрын
Very informative video. Learned about the profiling tool too. :)
@arkord76
@arkord76 2 жыл бұрын
Thank you for this extraordinary example!
@RENAUDADAM
@RENAUDADAM 2 жыл бұрын
Hey Nick, awesome to see a video on this content! As always really well done :). I agree that the benefits of MediatR generally speaking outweigh the performance cost. That said, the memory allocation issue related to the service can almost be completely removed by making the service a singleton, if your use case permits. It would be interesting if MediatR also allowed you to register handlers as singletons.
@nickchapsas
@nickchapsas 2 жыл бұрын
Singleton is almost never a viable option bacause it heavily depends on whether you want to support scoped services in the handlers, which is almost always the case, since the API request itself is scoped.
@tiebird
@tiebird 2 жыл бұрын
Registring as Singleton will create a memory leak in most cases. Variables injected with a shorter lifetime will never be collected because the root will still exist. While it is possible, I think you will get into all sorts of trouble 🙂
@RENAUDADAM
@RENAUDADAM 2 жыл бұрын
@@tiebird That is interesting! I never thought that a singleton would create a memory leak. How would this happen?
@RENAUDADAM
@RENAUDADAM 2 жыл бұрын
@@nickchapsas That is completely fair. Good point 😊
@tiebird
@tiebird 2 жыл бұрын
@@RENAUDADAM like earlier mentioned, you register a service/class as a Singleton. Every service/class that is injected in to the constructor of this Singleton will never be disposed in the lifetime of the application. As long as the root object exists, this means the Singleton object in this case, underlying objects will not be disposed by the automatic garbage collection. Therefore, you will see your .NET Core ServiceCollction grow larger and larger. It can be pretty hard to find these kind of memory leaks if you don't know what you're looking for. Memory consumption can rise fast if you call some kind of repository frequently.
@thomas5540
@thomas5540 2 жыл бұрын
Thank you for putting so much effort into it. I learned a lot from this video. I'm gonna stick with Mediatr :-)
@bormokov
@bormokov Жыл бұрын
very good evidences bro, thanks for best clarifications
@ThiagoFer93
@ThiagoFer93 2 жыл бұрын
I feel like most developers are always seeking the best practices overall and forget to ask what is the best for their situation, which can lead to hard to handle cannon that is used to kill an ant. It all comes to the problem you need to solve. In my company, we have some smaller applications that use MediatR. We never faced performance issues and my team just like to work with this library, because how the code feels cleaner and outweighs the performance "cost". It works for us in that situation and we are happy with maintening it.
@davidmartensson273
@davidmartensson273 2 жыл бұрын
I agree, cleaner better code is almost always beneficial, and my experience is that cleaner code can lead you to find better optimizations that saves even more or code that scales better. Getting 5 % more speed with more complex code, or double the performance by adding another instance due to easier to scale code :)
@gettoecoding1058
@gettoecoding1058 2 жыл бұрын
100% agree with you !
@Pookzob
@Pookzob 2 жыл бұрын
And happy developers that can easily change code saves money as well. Good for you!
@mrpankajrawat
@mrpankajrawat 2 жыл бұрын
100% agree. 80% of the time, we use only 20% of application. Martin fowler refactoring books also suggested the same.. we should focus on writing clean code and fix performance issue when needed.
@rtzzz9772
@rtzzz9772 Жыл бұрын
it is my experience that there are other ways to keep your code "clean" and remain testable without the complexity, and clutter, that this pattern inherently introduces.
@amrosamy8232
@amrosamy8232 2 жыл бұрын
Perfect demo 👌
@josepvg
@josepvg 2 жыл бұрын
Thanks for a great video. I think when you add some IO bound code to the sample this overhead becomes minimum and I also think in 99% of cases doing such low level optimization as using services instead of the Mediatr makes the code more complex. It is then much more difficult to maintain, bugfix and refactor for high level optimization
@airjordanx
@airjordanx 2 жыл бұрын
your content is good. thanks
@RusslanK
@RusslanK Жыл бұрын
Hi Nick! Thanks for the nice videos & material you make & provide to the public :) I have never used MediatR library before, however I believe there is another, that might be negative, impact in using this pattern in such a generic way as the library provide. How can you control the lifetime of the handler's instance? Does every time you send a message through the mediator instantiate a new instance of the handler? What happens if you send the message from a loop?
@manishwalde3424
@manishwalde3424 2 жыл бұрын
You are awesome Nick 👍🏼
@gettoecoding1058
@gettoecoding1058 2 жыл бұрын
Very very cool video ! Super interesting.
@HenriqueGraca
@HenriqueGraca 2 жыл бұрын
Great content!
@denys-p
@denys-p 2 жыл бұрын
Honestly, I like this video much more than many others. Mostly because of conclusion “always measure and then make decisions”. It would be nice to see even more realistic example - some json (de)serialization, maybe call to DB, some calculations and data transformations, logging, DI. Where are bottlenecks etc?
@diadetediotedio6918
@diadetediotedio6918 Жыл бұрын
I think many people have a hard time understanding that not everything is about raw performance, if that were the case we would only write with low-level languages like ASM, C or Rust. We use high-level languages because we want to increase the readability of our code as much as possible and reduce human error at the maximum possible rate, the objective with this is to make the product something agile to develop and with a low error rate. If you worry too much about performance trying to cut costs, you will end up impacting your bottom line and making those lower costs less valuable in and of themselves.
@user-do8um3sd6q
@user-do8um3sd6q 2 жыл бұрын
Hello Nick! Cool demo! What program you use to create your videos? I mean this great feature when you can stop demo at any time and draw lines to highlight useful moments on screen.
@nickchapsas
@nickchapsas 2 жыл бұрын
It's called ZoomIt
@user-do8um3sd6q
@user-do8um3sd6q 2 жыл бұрын
@@nickchapsas Thank you!
@sunilanthony17
@sunilanthony17 Жыл бұрын
Hi Nick, I'm a bit confused here and I was wondering if you could help me. Both methods use the MediatR framework. Calling it directly just means that you're NOT using MediatR injecting dependency, you're just creating an instance of the object and then calling the Method directly?
@kblyr
@kblyr 2 жыл бұрын
MassTransit also has an implementation of the Mediator Pattern, I have a feeling that there will be a huge difference in terms of performance, but I'm too lazy to benchmark it to see the difference. Is there a chance you can make a video for that?
@kblyr
@kblyr 2 жыл бұрын
By the way, I'm currently experimenting with MassTransit's Mediator
@olegchernyakov3167
@olegchernyakov3167 Жыл бұрын
Hi Nick, Thank you for your free content really appreciate it. I am wondering how will the Fastenpoints perform against mediator, I guess that the Fastenpoints also allocate ram in order to map the objects. Thank you.
@nickchapsas
@nickchapsas Жыл бұрын
They are way more efficient
@nothingisreal6345
@nothingisreal6345 2 жыл бұрын
I think from a performance perspective this doesn't matter that much. After all realistically processing a request will do MUCH more memory allocation (DB query, Read/Write XML, create in memory data structures). But I do think that there is a tendency to add more and more indirections into C# projects. And every level of indirection adds more complexity. While the original author of a code might be familiar with all these advance concepts and remember about all the introduced indirections and abstractions someone who needs to maintain the code later will have a very hard time to figure out how things in a code base depend on each other, especially if introducing such an indirection happens in a code file that isn't obviously linked to the code file that depends on it. You must know that e.g. the Mediator package has been added. You must know that this one line of code in the Program.cs is responsible for the coupling. You must know that the service runs transient. All this adds complexity without delivering any direct business value. It is all pluming. This is the wrong direction IMHO.
@roko567
@roko567 2 жыл бұрын
Do you think these issues could be solved by writing documentation?
@nkrapivnitskiy
@nkrapivnitskiy 2 жыл бұрын
​@@roko567 so we use MediatR which causes increase of indirections into our project. these indirections create us a problem to solve by documentation... which is also a problem because documentation is something that we have to keep updated and if you have outdated documentation it can be even worse than total absence of documentation Also MediatR makes a great job of hiding code smells. e.g. if you have a controller with 10+ services you can see that something somewhere went wrong and you should do refactoring. While with MediatR you have only instance of IMediatr and miss that your code is not as great as it seems I see these pros and cons about using MediatR + less dependencies in costructors + nice and easy in-process pub-sub implementation + way to decorate your calls with logging and etc - indirect usage of methods/services - slower navigation across code base - hiding code smells I agree that there are cases when usage of MediatR is great. But I doubt that it should be used in every single API project.
@GeorgeZarogkikas
@GeorgeZarogkikas 2 жыл бұрын
Nick great presentation !!! But it is also great the comments that this video triggered, if someone read them can gain some more knowledge
@Dustyy01
@Dustyy01 2 жыл бұрын
Really nice and deep insights. Sadly most people just believe what others say without trying it out first.
@Sebazzz1991
@Sebazzz1991 2 жыл бұрын
Do one SQL query or lazy load too many, then optimize that away, and you've gained much more than replacing MediatR.
@MetalKid007
@MetalKid007 2 жыл бұрын
I didn't think the slowness complaint was the basic Mediatr setup. I think it was more when you start adding things to its pipeline/middleware (decorators) that it started to become a problem.
@alexandredanelon
@alexandredanelon 2 жыл бұрын
Is the Activator call can cause this little overhead in mediatr?
@gabrielilie4460
@gabrielilie4460 2 жыл бұрын
It will be interesting to run this test with the MediatR request being of type record or struct or maybe record struct to see how that impacts allocation.
@nickchapsas
@nickchapsas 2 жыл бұрын
It can't be a struct because it needs to inherit from the IRequest interface
@metlic5209
@metlic5209 2 жыл бұрын
But the problem with MediatR is when you have a large amount of request handlers, notification handlers and behaviors, of course calling a single request handler is closely comparable to direct method call.
@peteruelimaa4973
@peteruelimaa4973 2 жыл бұрын
The same applies to normal DI though.
@hyts2k
@hyts2k 4 ай бұрын
@@peteruelimaa4973 I think that the performance of MediatR relay on performance of DI container, the much request and handdler you are using the much slow will be.
@dantenotavailable
@dantenotavailable 2 жыл бұрын
I'm always weirded out by people micro-benchmarking in C#. "Oh... you'll get 3.8% better performance if you don't use mediatr"... Sure, and i'll get an order of magnitude improvement if I use Go or Rust. I'm using C# in the first place because, to a certain degree, I'm prioritizing development time performance over runtime performance. And yeah i'd echo the point you made in the pin that i'd like to see this test re-run with EF... i'm definitely expecting that the differences would shrink to basically nothing as soon as you hit a database (particularly if you're performing the correct async rituals). For me... bottom line is that, at worst, Mediatr is taking away 4% of performance, probably less in a real example, and the very fact that i'm using C# means that 4% in return for objectively cleaner architecture is a good deal.
@vasiliioleinic
@vasiliioleinic 2 жыл бұрын
And try and throw some middleware (native) / mediatr pipeline behaviours that do logging and some other useful stuff and it gets really crazy :)
@breedingbubbles
@breedingbubbles Жыл бұрын
I'm a fan of MediatR and agree that it's all relative to what you gain plus, as others have commented, one bad SQL query makes all of this irrelevant. However, just in terms of MediatR overhead, a more likely scenario is probably a controller calling a method in a service class and that method calling multiple other methods in that same class - compared to the controller calling a MediatR class and that class calling multiple other MediatR classes. I haven't done the test, but I suspect the difference will be far greater in a case like that. Otherwise you have to duplicate common code in each MediatR class and that's not good.
@mischavreeburg3956
@mischavreeburg3956 2 жыл бұрын
Having looked at the mediatr codebase, I believe the performance issue can be alleviated by Introducing object pooling for the request handler and the notification handler. This will reduce the overall memory used and thus reduce GC time.
@nickchapsas
@nickchapsas 2 жыл бұрын
MediatR is as efficient as it can go with the handlers while respecting .NET's DI scopes. Both scoped and transient use the service provider to retrieve the service, which is exactly the same as injecting them and singletons are cached. All of them come from a dictionary. There isn't much to optimize past that, since a lot depends on how elaborate your pipeline is (pre/post processors etc)
@rtzzz9772
@rtzzz9772 Жыл бұрын
It was quite obvious that with all the additional plumbing that Mediatr and CQRS in general require there was going to be some performance impact. I think 8% is not terribly significant. However, we have to remember why CQRS is really in place. The theory is that it improves readability, testing paradigms, and keeps a cleaner more manageable architecture. You can make a case for that I think. In my situation, our company builds enterprise applications for large companies and government with 10's of thousands of potential concurrent users possible. In that scenario, we have been hard-pressed to think that all of the extra plumbing (dozens and dozens of extra nearly empty classes and interface points), that this requires gives a tangible benefit. It does keep code out of the WebAPI controllers which is great. But there are a number of other scenarios including just a straight N layer interface that do the same thing and do not degrade performance. This pattern and some of the others like it then are relegated to really specific situations that most projects do not need. I very much appreciate the quantifiable info that Nick has provided, it further confirms for me in my mind, that Mediatr outside of some very specific situations, is purely an academic exercise.
@adbirdk
@adbirdk 2 жыл бұрын
Can you try and do this with Blazor and Fluxor compared to a home made Blazor with Invoke? Right now Fluxor is making it so much easier to work with UI state.
@Dragonite594
@Dragonite594 2 жыл бұрын
What do you recommend instead of using MediatR write own solution ?
@nickchapsas
@nickchapsas 2 жыл бұрын
Just don't use MediatR
@rotacioskapa4251
@rotacioskapa4251 2 жыл бұрын
Can you make a vid about Dataflow (Task Parallel Library) ?
@viktoralferov2874
@viktoralferov2874 2 жыл бұрын
At the beginning you think about a performance. In the middle you think about an architecture. In the end you try to think about the performance keeping in mind the architecture. After the end - you want to use the ECS. But if you are a senior - you have to know and have love to use the MediatR, the benefits in Enterprise is huges.
@cutefunnyanimals5876
@cutefunnyanimals5876 Жыл бұрын
Better than unit of work + service + repository?
@kfajny1998
@kfajny1998 2 жыл бұрын
Nice
@regestea
@regestea Жыл бұрын
is MassTransit MediatR ok? because using the cqrs pattern without MediatR is not that simple for me and everyone is using MediatR
@ibnfpv
@ibnfpv 2 жыл бұрын
Greate content!
@stepanmyroniuk2502
@stepanmyroniuk2502 2 жыл бұрын
record please video about your pc setup
@IvanRicardoLopes
@IvanRicardoLopes 2 жыл бұрын
I think for most corporative applications, that performance difference would not be a big deal.
@vgmikhailov
@vgmikhailov Жыл бұрын
If we add a least some noticeable business logic to the test apps then the overhead of creating little mediator messages will disappear and will be minor comparing to other allocations related to DB, MessageBus, what ever could be in the logic. So for me such testing has very little value or I would say it actually hurts because ppl with insufficient qualification will make decisions based on this or at least will be biased doing own selection of the approach.
@pbolduc
@pbolduc 2 жыл бұрын
I think the first benchmark was not fair. You are using a single instance of the service/handler, effectively a singleton for the non-mediator test. But for the mediator test, you are using DI to allocate the handler on each iteration. Was it medator or DI allocating the order of magnitude more memory? Each benchmark should be required to resolve the handler 'service'.
@nickchapsas
@nickchapsas 2 жыл бұрын
The comparison is being fair to how you would use MediatR in your app. You wouldn't resolve the handler. You would resolve IMediatr. On that front they are both singletons. They handler is out of bounds since mediatr is doing the instantiation internally. It can be overriden, but that was never what we're testing.
@pbolduc
@pbolduc 2 жыл бұрын
@@nickchapsas Guess it is fair, I rewrote it as I suggested but the relative performance and memory allocations were inline with what you showed. I should have validated my assumption before my original comment. Thanks for all the great videos.
@LilPozzer
@LilPozzer 2 жыл бұрын
How's your command line called ??? It looks so utterly insane
@nickchapsas
@nickchapsas 2 жыл бұрын
I’m using Microsoft Terminal and oh-my-posh
@franckdesbrosses6463
@franckdesbrosses6463 2 жыл бұрын
Interesting, as usual, but I've never used MediatR as "dry" as that. For instance, the pipeline model is so much worthy, and appart from the obvious "cleaner code" standpoint, I'd bet the impact wouldn't be as important if you'd have to put your behavior logic in all your services...
@nickchapsas
@nickchapsas 2 жыл бұрын
Check the pinned comment
@RaWMajkeL
@RaWMajkeL 2 жыл бұрын
How do you comment that fast
@Myuuiii
@Myuuiii 2 жыл бұрын
Notification squad
@Moqqot
@Moqqot 2 жыл бұрын
applications should almost always prioritize speed before other. So the question should be is this safe enough. If true then go speed
@JacobNax
@JacobNax 2 жыл бұрын
Hi Nick Have you considered opening a discord community? Would also be an opportunity for your potential patreon subscribers
@nickchapsas
@nickchapsas 2 жыл бұрын
Hey Jacob. I have but I don't want the Discord server to end up being total chaos since I don't have time to moderate it so for now, I'm just part of the official C# Discord server
@simply3065
@simply3065 2 жыл бұрын
pre 301 squad :D
@giovani5586
@giovani5586 2 жыл бұрын
Even slower due to slow code navigation 😴😴😴
@koktbarilla2568
@koktbarilla2568 2 жыл бұрын
I was blinded around 7:30 min in, could not watch the rest of the video, RIP
@b03tz
@b03tz 2 жыл бұрын
Hahahahahaha :)
@Myuuiii
@Myuuiii 2 жыл бұрын
Slower than me posting a comment
@RaWMajkeL
@RaWMajkeL 2 жыл бұрын
Cmon
@insert-name1500
@insert-name1500 2 жыл бұрын
OMG. I can't believe Nick is using 69 and 420 as test values 🤣🤣🤣.
@calvinmolina6910
@calvinmolina6910 2 жыл бұрын
👍👍👍👍👍!! You really need Promo>SM!!!
@chswin
@chswin 2 жыл бұрын
Lol! MediatR … like to “mediate”; sounds like politics… We usually save that for our meetings not our code. ;)
@brandonpearman9218
@brandonpearman9218 2 жыл бұрын
Poorer performance is an objective number but besides that MediatR is an extra dependency to maintain and align with the team, its an added layer of complexity which you dont NEED. I dont feel like it makes code "clean", Its just a popular style at the moment off the back of the popularity of events. Basically teams which dont have event queues can play play events with MediatR lol jk
@prom3theu581
@prom3theu581 2 жыл бұрын
In reality that’s not the case. Look at it this way. The complexity of your unit testing is dramatically reduced. You only need to test your handlers instead of mocking and testing controllers and contexts etc. In that example case, why would you go out of your way to indirectly test parts of .net outside the domain of your project? We don’t want to mock controllers, we don’t Want to create a dummy context. Why should we? We only want to test our code. Hence, the handlers And this example works all over. Not only this but it allows associates all the way through senior to work on core parts of the system in isolation because you’re only working on a single request contract / response object implementation. If anything I think it makes it easier to maintain your code base while also keeping it simpler Now the question is, is mediatr the best. I dunno. If it’s the only thing you have in a service maybe but if you’re also using something like masstransit then you can use Chris Patterson’s in memory mediatr which does the same thing Mediatr is my go to unless I’m using MAssTransit then I use a combination of the MAssTransit bus with in memory bus similar to SendLocal in Nservicebus.
@krajekdev
@krajekdev 2 жыл бұрын
MediatR behaviors are the secret sause, which used effectively, does contribute to clean extensible architecture. I would not agree that this is not NEEDED.
@brandonpearman9218
@brandonpearman9218 2 жыл бұрын
@@prom3theu581 yeah i agree with you regarding the tests but you dont need mediatr for any of that. Ie thats not a legit reason to use mediatr, hence why i say its just the popular thing nowadays days.
@brandonpearman9218
@brandonpearman9218 2 жыл бұрын
@@krajekdev yes id agree behaviors is a good reason for mediatr. But in my experience most companies that use mediatr dont use behaviors and have no need for it(that could be argued but the fact that they never used them shows it was not needed). But yes if you have a strong need for behaviors, i would endorse mediatr for that case. But thats why i say it just a popularity contest, everyone uses something because its shiney and not because they actually need it or even know what it does. Some things have become "always use it because it fits every project".
@krajekdev
@krajekdev 2 жыл бұрын
@@brandonpearman9218 agreed 100%, cheers
@tcfialho
@tcfialho 2 жыл бұрын
Irrelevant
What is Span in C# and why you should be using it
15:15
Nick Chapsas
Рет қаралды 250 М.
8 await async mistakes that you SHOULD avoid in .NET
21:13
Nick Chapsas
Рет қаралды 310 М.
Did you believe it was real? #tiktok
00:25
Анастасия Тарасова
Рет қаралды 56 МЛН
ОСКАР vs БАДАБУМЧИК БОЙ!  УВЕЗЛИ на СКОРОЙ!
13:45
Бадабумчик
Рет қаралды 6 МЛН
Smart Sigma Kid #funny #sigma #comedy
00:25
CRAZY GREAPA
Рет қаралды 28 МЛН
Clean ASP.NET Core API using MediatR and CQRS | Setup
22:39
Nick Chapsas
Рет қаралды 319 М.
The Blazor Competitor is Here!
15:08
Nick Chapsas
Рет қаралды 66 М.
The Only Unbreakable Law
53:25
Molly Rocket
Рет қаралды 319 М.
🚀  TDD, Where Did It All Go Wrong (Ian Cooper)
1:03:55
DevTernity Conference
Рет қаралды 553 М.
Event Sourcing in 1 Hour with Marten in .NET
1:13:42
CodeOpinion
Рет қаралды 18 М.
High-performance logging in .NET, the proper way
15:56
Nick Chapsas
Рет қаралды 71 М.
What are record types in C# and how they ACTUALLY work
15:36
Nick Chapsas
Рет қаралды 118 М.
How to write "smarter" enums in C#
12:56
Nick Chapsas
Рет қаралды 133 М.
You DON'T want an In-Memory Event Bus like MediatR
11:20
CodeOpinion
Рет қаралды 22 М.
Did you believe it was real? #tiktok
00:25
Анастасия Тарасова
Рет қаралды 56 МЛН