<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Katabench engineering blog</title><description>Practical field notes on C#, .NET performance, EF Core, software architecture, security, testing, and deliberate practice.</description><link>https://katabench.com/</link><language>en-us</language><item><title>Aspire Service Discovery: Names, Ports, Replicas</title><link>https://katabench.com/blog/aspire-service-discovery</link><guid isPermaLink="true">https://katabench.com/blog/aspire-service-discovery</guid><description>Learn how Aspire service discovery turns logical names into endpoints with WithReference, HttpClient resolution, health checks, and replica load balancing.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>Circuit Breaker Pattern in .NET with Polly</title><link>https://katabench.com/blog/circuit-breaker-pattern-dotnet</link><guid isPermaLink="true">https://katabench.com/blog/circuit-breaker-pattern-dotnet</guid><description>Build a circuit breaker in modern .NET with Polly and HttpClient resilience. Tune the failure window, compose retries safely, and prove recovery.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>Message Queue vs Event Bus: Choose the Topology</title><link>https://katabench.com/blog/message-queue-vs-event-bus</link><guid isPermaLink="true">https://katabench.com/blog/message-queue-vs-event-bus</guid><description>Compare message queues, event buses, and pub/sub by delivery topology. Choose competing workers or fan-out, then design retries and ordering honestly.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>Mutation Testing in C# with Stryker.NET</title><link>https://katabench.com/blog/mutation-testing-csharp</link><guid isPermaLink="true">https://katabench.com/blog/mutation-testing-csharp</guid><description>Mutation testing in C# plants controlled bugs and asks whether your tests notice. Learn Stryker.NET, triage survivors, and set useful CI gates.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Testing &amp; Refactoring</category><author>The Katabench team</author></item><item><title>Path Traversal Vulnerability in ASP.NET Core</title><link>https://katabench.com/blog/path-traversal-aspnet-core</link><guid isPermaLink="true">https://katabench.com/blog/path-traversal-aspnet-core</guid><description>A path traversal vulnerability lets user input escape a trusted directory. See the unsafe C# patterns, the containment check, and tests that prove it.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Security &amp; Reliability</category><author>The Katabench team</author></item><item><title>C# String Concatenation Performance, Measured</title><link>https://katabench.com/blog/string-concatenation-performance-csharp</link><guid isPermaLink="true">https://katabench.com/blog/string-concatenation-performance-csharp</guid><description>Choose between +, interpolation, StringBuilder, and direct writes in modern C#. Fix repeated copying, then verify the result with allocation benchmarks.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>Structured Logging in .NET: Write Logs You Can Query</title><link>https://katabench.com/blog/structured-logging-dotnet</link><guid isPermaLink="true">https://katabench.com/blog/structured-logging-dotnet</guid><description>Learn structured logging in .NET with ILogger message templates, named fields, scopes, correlation IDs, safe data handling, and query-first design.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>CancellationToken in ASP.NET Core: stop doing work nobody wants</title><link>https://katabench.com/blog/cancellation-token-aspnet-core</link><guid isPermaLink="true">https://katabench.com/blog/cancellation-token-aspnet-core</guid><description>A disconnected client does not make your database query disappear. Learn how RequestAborted flows through ASP.NET Core, EF Core, and HttpClient, where cancellation should stop, and how to test it.</description><pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>Transactional outbox pattern in .NET: publish without losing messages</title><link>https://katabench.com/blog/transactional-outbox-dotnet</link><guid isPermaLink="true">https://katabench.com/blog/transactional-outbox-dotnet</guid><description>Saving data and publishing an event are two writes that can disagree. Build a transactional outbox with EF Core, a retrying publisher, and idempotent consumers so crashes do not lose business events.</description><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>Optimistic concurrency in EF Core: stop silent overwrites</title><link>https://katabench.com/blog/optimistic-concurrency-ef-core</link><guid isPermaLink="true">https://katabench.com/blog/optimistic-concurrency-ef-core</guid><description>Two users edit the same row and the last save silently wins. Use EF Core concurrency tokens, inspect the generated UPDATE, handle DbUpdateConcurrencyException, and test the race with two DbContexts.</description><pubDate>Mon, 27 Jul 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>AddSingleton vs AddScoped vs AddTransient: what each promises</title><link>https://katabench.com/blog/addsingleton-vs-addscoped-vs-addtransient</link><guid isPermaLink="true">https://katabench.com/blog/addsingleton-vs-addscoped-vs-addtransient</guid><description>AddSingleton vs AddScoped vs AddTransient in plain terms: what each lifetime promises, sensible defaults, and the captive dependency bug that ships.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>C# async await mistakes that pass code review</title><link>https://katabench.com/blog/async-await-mistakes-csharp</link><guid isPermaLink="true">https://katabench.com/blog/async-await-mistakes-csharp</guid><description>The C# async await mistakes that pass code review: async void, fire and forget tasks, missing CancellationToken plumbing, and blocking on .Result.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>Caching strategies: cache-aside, invalidation, and stampedes</title><link>https://katabench.com/blog/caching-strategies</link><guid isPermaLink="true">https://katabench.com/blog/caching-strategies</guid><description>Caching strategies from the cache-aside flow to the hard parts: invalidation owned by a human and stampedes tamed by single-flight and jitter.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>Code smells: a working catalog of six, with C# examples</title><link>https://katabench.com/blog/code-smells-csharp</link><guid isPermaLink="true">https://katabench.com/blog/code-smells-csharp</guid><description>Code smells are symptoms, not verdicts. Six worth knowing, with C# examples: the tell for each, why it hurts, and the refactoring move that clears it.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Testing &amp; Refactoring</category><author>The Katabench team</author></item><item><title>Connection pooling: why your app ran out of connections</title><link>https://katabench.com/blog/connection-pooling</link><guid isPermaLink="true">https://katabench.com/blog/connection-pooling</guid><description>Connection pooling explained from the failure end: what a connection costs, the three ways pools drain, and why the timeout blames the wrong request.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>Cyclomatic complexity: what the number actually tells you</title><link>https://katabench.com/blog/cyclomatic-complexity</link><guid isPermaLink="true">https://katabench.com/blog/cyclomatic-complexity</guid><description>Cyclomatic complexity counts the independent paths through a method. How to compute it by eye, what a score of 10 predicts, and how to reduce it for real.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Testing &amp; Refactoring</category><author>The Katabench team</author></item><item><title>.NET garbage collection explained: what gen 0, 1, and 2 cost</title><link>https://katabench.com/blog/dotnet-garbage-collection-explained</link><guid isPermaLink="true">https://katabench.com/blog/dotnet-garbage-collection-explained</guid><description>.NET garbage collection explained: why most objects die young, what gen 0, 1, and 2 collections cost, and why the large object heap hurts latency.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>How do database indexes work? B-trees, page by page</title><link>https://katabench.com/blog/how-database-indexes-work</link><guid isPermaLink="true">https://katabench.com/blog/how-database-indexes-work</guid><description>How do database indexes work? A B-tree is a small sorted structure with huge fanout, so a lookup reads a handful of pages instead of the whole table.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>Idempotency in API design: surviving the retry you didn&apos;t send</title><link>https://katabench.com/blog/idempotency-api-design</link><guid isPermaLink="true">https://katabench.com/blog/idempotency-api-design</guid><description>Every serious client retries. How the idempotency key pattern and a database unique constraint keep a retried payment from becoming two charges.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Security &amp; Reliability</category><author>The Katabench team</author></item><item><title>Rate limiting algorithms: how token buckets forgive bursts</title><link>https://katabench.com/blog/rate-limiting-algorithms</link><guid isPermaLink="true">https://katabench.com/blog/rate-limiting-algorithms</guid><description>Rate limiting algorithms compared: why fixed windows leak double the limit, how token buckets forgive bursts, and what a good 429 response returns.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Security &amp; Reliability</category><author>The Katabench team</author></item><item><title>Unit testing best practices: test behavior, not implementation</title><link>https://katabench.com/blog/unit-testing-best-practices</link><guid isPermaLink="true">https://katabench.com/blog/unit-testing-best-practices</guid><description>Unit testing best practices that survive refactoring: AAA structure, behavior-first assertions, a healthy test pyramid, and determinism over flakiness.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><category>Testing &amp; Refactoring</category><author>The Katabench team</author></item><item><title>Primitive obsession: the bug the compiler was begging to catch</title><link>https://katabench.com/blog/primitive-obsession-value-objects</link><guid isPermaLink="true">https://katabench.com/blog/primitive-obsession-value-objects</guid><description>When everything is a string, a decimal, or a Guid, the type system can&apos;t tell your arguments apart. Value objects in modern C#, the bugs they delete, and when they&apos;re overkill.</description><pubDate>Sun, 12 Jul 2026 00:00:00 GMT</pubDate><category>Testing &amp; Refactoring</category><author>The Katabench team</author></item><item><title>Sync over Async: Diagnose .NET Thread Pool Starvation</title><link>https://katabench.com/blog/sync-over-async</link><guid isPermaLink="true">https://katabench.com/blog/sync-over-async</guid><description>Learn how sync over async causes .NET Thread Pool starvation, spot it with dotnet-counters, capture blocking stacks, and fix ASP.NET Core latency.</description><pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>Skip and Take will betray you: offset vs keyset pagination</title><link>https://katabench.com/blog/offset-vs-keyset-pagination</link><guid isPermaLink="true">https://katabench.com/blog/offset-vs-keyset-pagination</guid><description>OFFSET pagination reads every row it skips, so page 2,000 costs 2,000 pages of work. Keyset pagination seeks straight to the next page. The SQL, the EF Core, the trade-offs.</description><pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>The LINQ query that ran twice: multiple enumeration and other deferred-execution traps</title><link>https://katabench.com/blog/multiple-enumeration-linq</link><guid isPermaLink="true">https://katabench.com/blog/multiple-enumeration-linq</guid><description>An IEnumerable isn&apos;t a list; it&apos;s a promise to do work later. Enumerate it twice and the work happens twice, including, with EF Core, the database query.</description><pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>ReDoS: the innocent regex that can take down your API</title><link>https://katabench.com/blog/redos-catastrophic-backtracking</link><guid isPermaLink="true">https://katabench.com/blog/redos-catastrophic-backtracking</guid><description>Catastrophic backtracking turns an email regex into a denial of service: 30 characters, nearly a minute of CPU. Why nested quantifiers explode and how .NET lets you defuse them.</description><pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate><category>Security &amp; Reliability</category><author>The Katabench team</author></item><item><title>Tutorial hell: why you can finish every course and still freeze at a blank file</title><link>https://katabench.com/blog/tutorial-hell</link><guid isPermaLink="true">https://katabench.com/blog/tutorial-hell</guid><description>Watching code get written trains recognition, not recall. Why tutorials feel like progress, why the skill doesn&apos;t transfer, and how to build a loop that does.</description><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><category>Engineering Practice</category><author>The Katabench team</author></item><item><title>Coding interviews are broken, but the skills they fumble are real</title><link>https://katabench.com/blog/coding-interviews-vs-real-skill</link><guid isPermaLink="true">https://katabench.com/blog/coding-interviews-vs-real-skill</guid><description>Whiteboard interviews measure the wrong slice of engineering. The case for practicing what predicts a good engineer: correct, fast, well-structured, secure code.</description><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><category>Engineering Practice</category><author>The Katabench team</author></item><item><title>The OWASP Top 10 through a C# lens</title><link>https://katabench.com/blog/owasp-top-10-csharp</link><guid isPermaLink="true">https://katabench.com/blog/owasp-top-10-csharp</guid><description>A practical tour of the OWASP Top 10 for .NET developers: the ASP.NET Core and EF Core patterns behind broken access control, injection, SSRF, and overposting.</description><pubDate>Wed, 24 Jun 2026 00:00:00 GMT</pubDate><category>Security &amp; Reliability</category><author>The Katabench team</author></item><item><title>SQL injection is still alive, and it&apos;s hiding in your C#</title><link>https://katabench.com/blog/sql-injection-still-alive</link><guid isPermaLink="true">https://katabench.com/blog/sql-injection-still-alive</guid><description>SQL injection is supposedly solved, yet it&apos;s still in the OWASP Top 10. The C# patterns that keep it alive in EF Core and ADO.NET, and how to kill them.</description><pubDate>Mon, 22 Jun 2026 00:00:00 GMT</pubDate><category>Security &amp; Reliability</category><author>The Katabench team</author></item><item><title>Architecture fitness functions: tests that fail the build when your layers rot</title><link>https://katabench.com/blog/architecture-fitness-functions</link><guid isPermaLink="true">https://katabench.com/blog/architecture-fitness-functions</guid><description>Architecture decays because nothing fails the build when the domain references the DbContext. Fitness functions with ArchUnitNET assert layering and dependency rules in CI like any test.</description><pubDate>Sat, 20 Jun 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>Hexagonal architecture in .NET without the dogma</title><link>https://katabench.com/blog/hexagonal-architecture-dotnet</link><guid isPermaLink="true">https://katabench.com/blog/hexagonal-architecture-dotnet</guid><description>Ports and adapters explained in plain C#: domain in the center, ports as interfaces, adapters as infrastructure. Why it beats layered spaghetti, and when it is overkill for a CRUD app.</description><pubDate>Thu, 18 Jun 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>Dependency inversion in C# is not about your DI container</title><link>https://katabench.com/blog/dependency-inversion-csharp</link><guid isPermaLink="true">https://katabench.com/blog/dependency-inversion-csharp</guid><description>The D in SOLID is the most quoted and least applied principle. Dependency inversion means depending on abstractions you own and pointing dependencies inward, not registering services.</description><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><category>Architecture &amp; Design</category><author>The Katabench team</author></item><item><title>A test-first playbook for refactoring legacy C# safely</title><link>https://katabench.com/blog/refactoring-legacy-csharp</link><guid isPermaLink="true">https://katabench.com/blog/refactoring-legacy-csharp</guid><description>How to refactor legacy C# without breaking it: write characterization tests first, then take small behavior-preserving steps (extract method, introduce a seam, replace conditional with polymorphism).</description><pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate><category>Testing &amp; Refactoring</category><author>The Katabench team</author></item><item><title>Green checkmarks are incomplete: grading C# beyond correctness</title><link>https://katabench.com/blog/green-checkmarks-lie</link><guid isPermaLink="true">https://katabench.com/blog/green-checkmarks-lie</guid><description>A green check can prove output without proving the solution scales. Learn how performance, allocation, query, and structure gates turn a result into actionable feedback.</description><pubDate>Wed, 10 Jun 2026 00:00:00 GMT</pubDate><category>Engineering Practice</category><author>The Katabench team</author></item><item><title>Clean code is a vibe until you measure it</title><link>https://katabench.com/blog/measuring-code-quality</link><guid isPermaLink="true">https://katabench.com/blog/measuring-code-quality</guid><description>Four code quality metrics you can actually automate in C#: cyclomatic complexity, nesting depth, method length, and duplication, with reasonable thresholds and a refactor that passes them.</description><pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate><category>Testing &amp; Refactoring</category><author>The Katabench team</author></item><item><title>EF Core habits that quietly wreck performance</title><link>https://katabench.com/blog/ef-core-performance-habits</link><guid isPermaLink="true">https://katabench.com/blog/ef-core-performance-habits</guid><description>Nine EF Core habits that pass every test and quietly tank performance in production: missing AsNoTracking, fetching whole entities, N+1, cartesian explosion, counting in memory, and more.</description><pubDate>Tue, 02 Jun 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>Your LINQ is fast; your query plan isn&apos;t</title><link>https://katabench.com/blog/ef-core-query-plans-indexes</link><guid isPermaLink="true">https://katabench.com/blog/ef-core-query-plans-indexes</guid><description>A perfectly written EF Core query can still do a sequential scan: no index, or a function on a column makes it non-sargable. How to read a query plan and fix it.</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>IQueryable vs IEnumerable: the one return type that decides where your query runs</title><link>https://katabench.com/blog/iqueryable-vs-ienumerable</link><guid isPermaLink="true">https://katabench.com/blog/iqueryable-vs-ienumerable</guid><description>Returning IEnumerable, or calling ToList too early, moves filtering and paging into C# memory. How one type change turns an indexed WHERE into loading a million rows.</description><pubDate>Tue, 19 May 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>The N+1 query problem in EF Core: the most expensive habit in .NET</title><link>https://katabench.com/blog/ef-core-n-plus-1</link><guid isPermaLink="true">https://katabench.com/blog/ef-core-n-plus-1</guid><description>An EF Core loop that looks innocent fires one query per row. It passes every unit test and dies in production. How N+1 happens, the SQL it generates, and the fix.</description><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate><category>Databases &amp; EF Core</category><author>The Katabench team</author></item><item><title>Deliberate practice for programmers: why a green check isn&apos;t feedback</title><link>https://katabench.com/blog/deliberate-practice-programmers</link><guid isPermaLink="true">https://katabench.com/blog/deliberate-practice-programmers</guid><description>Repetition doesn&apos;t make you better; deliberate practice does. It needs immediate, specific feedback at the edge of your ability, and most coding practice fails that test badly.</description><pubDate>Tue, 05 May 2026 00:00:00 GMT</pubDate><category>Engineering Practice</category><author>The Katabench team</author></item><item><title>How senior .NET engineers actually keep their edge</title><link>https://katabench.com/blog/how-seniors-practice</link><guid isPermaLink="true">https://katabench.com/blog/how-seniors-practice</guid><description>It isn&apos;t grinding more LeetCode for correctness. Seniors practice the things production grades: performance, data-access shape, design, and security. Here&apos;s the difference.</description><pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate><category>Engineering Practice</category><author>The Katabench team</author></item><item><title>The premature optimization myth: what Knuth actually said</title><link>https://katabench.com/blog/premature-optimization-myth</link><guid isPermaLink="true">https://katabench.com/blog/premature-optimization-myth</guid><description>The most-abused quote in software lets developers dodge thinking about performance entirely. Here&apos;s Knuth&apos;s real argument, and why finding the 3% requires an instinct you have to train.</description><pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>Span&lt;T&gt;, Memory&lt;T&gt;, and stackalloc: when zero-allocation C# is worth it</title><link>https://katabench.com/blog/span-memory-zero-allocation</link><guid isPermaLink="true">https://katabench.com/blog/span-memory-zero-allocation</guid><description>Span&lt;T&gt; and stackalloc let you parse and slice without allocating, but they have real limits. Here&apos;s when zero-allocation C# earns its keep and when it&apos;s overkill.</description><pubDate>Thu, 09 Apr 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>The allocation tax: why correct, O(n) C# can still be slow</title><link>https://katabench.com/blog/dotnet-allocations</link><guid isPermaLink="true">https://katabench.com/blog/dotnet-allocations</guid><description>In .NET, correct and algorithmically optimal code can still drag, because every needless allocation feeds the GC. Here&apos;s how to spot and cut allocation pressure in C#.</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item><item><title>Big-O isn&apos;t interview trivia: where complexity actually bites in production</title><link>https://katabench.com/blog/big-o-in-production</link><guid isPermaLink="true">https://katabench.com/blog/big-o-in-production</guid><description>Big-O gets crammed for interviews and forgotten. But quadratic C# passes your tests and melts in prod. Here&apos;s where it bites and how to make complexity an instinct.</description><pubDate>Wed, 18 Mar 2026 00:00:00 GMT</pubDate><category>.NET Performance</category><author>The Katabench team</author></item></channel></rss>