Martin Stühmer

I’m Martin, a software architect and developer from the Stuttgart region who’s been building .NET systems since the Framework 2.0 days. Nearly 20 years later, I’m still here—not because I’m stubborn (well, not only), but because the .NET ecosystem keeps delivering value when you cut through the hype and focus on fundamentals.

My work centers on a simple premise: quality isn’t optional, and buzzwords don’t ship features. As Director Consulting Services at CGI, I work with teams building cloud-native solutions on Azure and modern .NET. I help organizations navigate technical decisions using Risk and Cost Driven Architecture (RCDA)—a methodology that brings systematic risk and cost analysis to architecture choices instead of relying on “best practices” pulled from conference slides.

What I Actually Do

Enterprise Architecture & Development: I design and build systems that need to scale, perform, and stay maintainable after the consultants leave. My focus spans the full stack—from Azure infrastructure and DevOps pipelines to .NET application design, performance optimization, and the unglamorous work of making legacy systems coexist with modern approaches. I’ve worked with teams ranging from startups to global enterprises, always with the same goal: shipping production-ready software that solves real business problems without accumulating crippling technical debt.

The work involves hard choices—choosing boring, reliable technologies over exciting new ones when stability matters more than innovation. Designing for the team you have, not the team you wish you had. Building systems that can evolve incrementally instead of requiring big-bang rewrites. It’s less glamorous than conference keynotes make it sound, but it’s what keeps production systems running.

Training & Knowledge Transfer: As a Microsoft Certified Trainer and IHK-certified instructor, I train developers and architects who want depth, not surface-level tutorials. Whether it’s cloud architecture, modern .NET features, or pragmatic testing strategies, my goal is equipping teams to make informed decisions rather than following trends blindly.

My training approach comes from spending years cleaning up messes created by applying “best practices” without understanding context. I don’t teach dogma—I teach judgment. Students learn to evaluate trade-offs, understand when to break rules, and recognize that most software engineering advice comes with implicit assumptions about scale, team structure, and business constraints that may not match their reality.

Open Source Contributions: I maintain several NuGet packages focused on solving real problems I’ve encountered in production systems. Code quality, testability, and developer experience drive these projects—not feature counts or GitHub stars. Each package exists because I’ve repeatedly solved the same problem across different projects and decided the ecosystem needed a better solution than copying code between repositories.

These contributions aren’t just code dumps—they’re maintained, documented, and tested because I actually use them in production. When you depend on one of my packages, you’re getting something that’s survived contact with real-world requirements, not a weekend experiment that seemed like a good idea at the time.

Writing & Teaching: Through this blog, I share perspectives on software engineering that challenge conventional wisdom when warranted. Topics range from .NET evolution and Azure patterns to technical debt management, quality practices, and why “Clean Code” has become empty lip service in many organizations. If you’re looking for balanced, experience-driven insights rather than cheerleading for the latest framework, you’re in the right place.

I write about topics that matter for teams shipping production software—the messy middle ground between academic computer science and “move fast and break things” startup culture. Expect posts that question whether you actually need that microservices architecture, analyze .NET performance characteristics with benchmarks not hand-waving, and explore how to incrementally improve legacy codebases without grinding development to a halt.

My Technical Philosophy

After nearly two decades, here’s what I’ve learned:

  • Fundamentals over frameworks: Languages, patterns, and principles outlast specific tools
  • Quality over velocity: Analyzers, tests, and code reviews prevent more bugs than heroic debugging sessions
  • Context over dogma: “Best practices” depend on team size, domain complexity, and business constraints
  • Pragmatism over purity: Perfect architecture that ships in six months loses to good-enough architecture that ships in six weeks
  • Evidence over opinion: Measure performance, validate assumptions, benchmark alternatives

I’m skeptical of buzzword-driven development, hostile to cargo-cult practices, and allergic to “because everyone else does it” as technical justification. But I’m also pragmatic—sometimes the boring, proven approach is exactly what your production system needs.

The Journey: From Framework to Modern .NET

I started with .NET Framework 2.0 in an era when SOAP web services were cutting-edge and ORMs were controversial. I’ve lived through the rise and fall of Silverlight, WPF’s promise and reality, WCF’s complexity, and the awkward adolescence of ASP.NET Web Forms. I witnessed the .NET Core revolution—Microsoft’s bet-the-company move to open-source, cross-platform development that paid off spectacularly.

This long view shapes how I evaluate new technologies. When someone pitches the latest JavaScript framework as the future, I remember when that was Angular 1.0. When architectural patterns become trendy, I recall which ones survived the test of production systems and which ones became cautionary tales in architecture horror story sessions.

Modern .NET (.NET 6, 8, 9, and now 10) represents the maturation of Microsoft’s platform strategy—combining the stability and enterprise-readiness of .NET Framework with the performance and innovation of .NET Core. But experience teaches caution: every new feature, pattern, or framework comes with costs that conference talks rarely mention. My job is helping teams understand those costs before they commit.

What Drives My Work

Making Technical Debt Visible: Too many organizations treat technical debt as an invisible problem until it becomes an existential crisis. Through RCDA, quality metrics, and transparent architectural decision-making, I help teams quantify, prioritize, and systematically address debt. Not by stopping all feature work for mythical “cleanup sprints,” but by integrating quality improvements into the regular development flow.

Elevating Quality Standards: I’ve seen too many teams accept buggy, untested, unmaintainable code because “we need to ship fast.” This is a false choice. Static analyzers catch bugs in milliseconds. Well-structured tests prevent regressions automatically. Code reviews transfer knowledge and catch design flaws. These practices don’t slow teams down—they prevent the constant firefighting that actually kills velocity.

Bridging Strategy and Implementation: Many architects design ivory-tower systems that fall apart when real requirements and real developers get involved. Many developers focus solely on code without understanding business context. I work in the gap between these extremes—translating business needs into technical strategy, and technical constraints into terms business stakeholders can evaluate.

Published blogs

PackageDownload: NuGet's Forgotten Power Tool

PackageDownload: NuGet's Forgotten Power Tool

PackageDownload arrived in NuGet 4.8 to solve a niche but genuine problem: downloading packages without adding assembly references. It works. But its version syntax requirements and complete disregard for Central Package Management reveal the messy reality of platform evolution.
Configuration-First Health Checks for Modern .NET

Configuration-First Health Checks for Modern .NET

Let’s be honest: health checks are the broccoli of .NET projects. Everyone says they have them, but nobody’s excited to eat their greens. What starts as a humble SELECT 1 in a try/catch quickly explodes into a wild jungle of scripts, copy-pasted connection strings, and endpoints that only half the team remembers. Sure, it works—until it doesn’t. And when it breaks, it’s never at a good time.

Stop Parsing the Same String Twice: CompositeFormat in .NET

Stop Parsing the Same String Twice: CompositeFormat in .NET

Every time you call string.Format() with the same format string, .NET parses it again. And again. And again. CompositeFormat changes that: parse once, reuse forever. The result? Up to 30% faster formatting, fewer allocations, and a one-line code change. Here’s why this matters and how to use it.
How SearchValues Saved Us From Scaling Hell

How SearchValues Saved Us From Scaling Hell

While you’re busy optimizing database queries and adding cache layers, thousands of string searches per second are quietly eating your CPU budget. The problem isn’t visible in your APM dashboard because it’s distributed across every request. But it’s there. Compounding. Scaling linearly with load.

I discovered this the hard way when a log processing API started choking under production traffic. The bottleneck? String validation and sanitization. The fix? A .NET 8 feature that delivered a 5x performance improvement and let us shut down servers instead of adding them. And it’s gotten even better in .NET 9 and 10.

Clean Code: A Lip Service, Not a Standard

Clean Code: A Lip Service, Not a Standard

Clean Code is often praised but rarely practiced effectively. This article explores how misunderstood ideals and over-engineering harm .NET systems, how to recognize such failures early, and which C# best practices and official guidelines truly support maintainable software.