Your source of geek knowledge

Y

Latest stories

Event Sourcing: the not-so-simple bi-temporal basics

E

It’s time for bi-temporal event sourcing in part eight of my event sourcing series. In this post, I’ll stick to the basics – at least I hope so. 😅 Bi-temporal event sourcing means that we have two timestamps associated with an event: The first timestamp tells us when the event entered the system, or when the system acquired the knowledge. We call this the application timestamp. The second timestamp states when the event takes effect – the effective timestamp. This is...

Build a profiling harness before you benchmark

B

TL;DR: Before writing a benchmark, build a small profiling harness that makes the code path visible. Run it in Release mode, keep unrelated work out, add clear profiler snapshot points, and collect both memory and CPU evidence. Production code is a terrible place to start a performance investigation. There is too much happening at once. Not because production code is bad. Because it is alive. It has real configuration, real input/output, logging, retries, dependency injection, serialization...

Stop guessing: the performance loop for production code

S

TL;DR: A benchmark can tell you whether code got faster. It cannot tell you whether the code mattered. For that, use a loop: profile with a profiling harness, improve a hot path, benchmark and compare, profile again, then ship and observe production. The first benchmark I wrote looked deceptively easy. A class. A few attributes. A method. Run BenchmarkDotNet and get a table. It looked a lot like unit testing, which made me dangerously confident. That confidence did not survive contact with real...

Azure Service Bus: Earn the redesign

A
A picture explaining the earn the redesign lifecycle form the post

TL;DR: Micro-optimizations are not a substitute for design work. They are how you earn the right to redesign. In the Azure Service Bus SDK, repeated work in the Body property first led to smaller allocation fixes. Once those fixes exposed the shape of the problem, a small internal redesign made the code faster, clearer, and easier to reason about. “This code is bad. We should rewrite it.” Most developers have heard that sentence. Many have said it. I have too. The problem is not...

Small optimizations, large systems: tightening the Event Hubs partition key hash loop

S

TL;DR: After temporary allocations were removed from the Azure Event Hubs partition-key encoding path, the Jenkins lookup3 hash loop itself became the next interesting place to look. Tightening that loop reduced CPU overhead, but it also raised the bar for review, portability, and correctness. I like performance work most when it starts with a boring question: why is this small method showing up so much? That question came up while looking at the Azure Event Hubs client. Event Hubs is built for...

Small optimizations, large systems: removing allocations from Event Hubs partition key hashing

S

TL;DR: Small code paths become expensive when cloud workloads execute them millions of times. The Azure Event Hubs partition key resolver is one of those paths. By removing temporary allocations from the partition-key encoding path, the Azure Event Hubs SDK reduced garbage collection pressure on a publishing hot path. I like performance work most when it starts with a boring question: why is this small method showing up so much? That question came up while looking at the Azure Event Hubs client...

Event Sourcing: compensation – the simple way out when things go wrong

E

In the fifth part of this event sourcing series, I’ll show you how we use compensation of events to handle failed commands and events that should never have happened. Sometimes, things go wrong – a command fails because the database is overloaded, there is a bug in the code for some edge case, the system is out of memory, the infrastructure misbehaves, etc. Or a user did something that should never have happened, like importing the wrong data set. When this happens, we want the...

Recent Posts