Union types are coming in C# 15.
I've wanted this one for years.
I've written a lot about the Result pattern. Take a method as small as GetUser(42). Its return type says User. You have to open the method to find out it throws if user 42 doesn't exist. That's a lot to hide in a lookup.
With a union, I can give GetUser a return type called UserResult with two cases. I can return a User or a NotFound. At the endpoint, I switch on the result. A User gets a 200. NotFound(42) gets a 404, and I still have the ID that was missing.
The part I'm most excited about comes later. Say we add a third case. The compiler can point me to the switch expressions that still handle only two. I get to fix those while the change is fresh in my head.
Here's how to get started with union types: https://t.co/a5dfwfONX7
Junior developer needs to know 6 architecture patterns.
Middle developer needs to know 18.
Senior developer needs to know 29.
Here's what to learn at each level 👇
👉 𝗝𝘂𝗻𝗶𝗼𝗿 𝗗𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿
Patterns that teach you structure and flow.
1. Monolith → one deployable, easy to build and debug
2. Client-Server → the API is the contract between them
3. Layered Architecture → UI, Application, Domain, Infrastructure
4. Vertical Slice → all code for one feature lives together
5. CRUD Architecture → the base of most business systems
6. Request-Response → simple HTTP calls, easy to trace
👉 𝗠𝗶𝗱𝗱𝗹𝗲 𝗗𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿
Add patterns that connect parts of a system and keep it running.
1. Modular Monolith → clear module boundaries, one deployable
2. API Gateway → one entry point for routing, auth, rate limits
3. Event-Driven Architecture → services talk through async events
4. Publish/Subscribe → one event, many consumers
5. Point-to-Point Queues → one message, one consumer, reliable delivery
6. Outbox Pattern → save data and event in one transaction
7. CQRS → separate read and write models when the load differs
8. Read Replicas → scale reads and improve availability
9. Circuit Breaker → stop calling a service that keeps failing
10. Retry with Backoff → recover from short network failures
11. Cache-Aside → read from cache, fall back to the database
12. Idempotency → the same request twice gives one result
👉 𝗦𝗲𝗻𝗶𝗼𝗿 𝗗𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿
Here patterns turn into trade-offs and consequences.
1. Strangler Fig → replace a legacy system piece by piece
2. Saga → distributed transactions with compensation steps
3. Event Sourcing → store every change as an event
4. Anti-Corruption Layer → keep external models out of your domain
5. Backend for Frontend → one API shaped for each client
6. Sidecar → logging, security and networking outside your code
7. Service Discovery → services find each other at scale
8. Sharding → split data to scale writes
9. Replication vs Sharding → consistency vs availability, latency vs correctness
10. When NOT to use a pattern → microservices too early, CQRS without a need
11. Evolution paths → Monolith → Modular Monolith → Microservices
Architects also know which ones to skip.
This loop took 2.4 seconds. A change to the lookup cut it to 4.7 milliseconds.
The benchmark checks customer IDs on 200,000 orders against 50,000 blocked customer IDs. Both use Guid keys. With a List, each missed lookup scans all 50,000 entries. Put that inside a loop and the work adds up fast.
Build a HashSet once, then use it for each check. That took 4.7 ms in this run, including the time to build the set. The result stayed the same.
This was a Release run on .NET 11 preview. Your time will vary. A set also uses extra space, so I wouldn't swap every small list for one.
In a review, I look for a search inside a loop. Then I check how much work it does as both inputs grow.
Try the same idea in Contains Duplicate on Katabench. Its large test has 400,000 numbers and a 500 ms limit. Start with the free tour:
https://t.co/hMGIrYcd2W
You change a value in the appsettings file, save it, and your API keeps returning the old value.
There is no error and you did not restart the app, so it looks like the file was ignored. What decides this is the options interface you injected.
All three of them give you the same options class, and the only difference is when they read the value.
I tested this on .NET 10 by changing Temperature from 22 to 35 while a request was still running.
IOptions is a singleton that builds the value the first time you ask for it and then caches it. It kept returning 22 until I restarted the app.
IOptionsSnapshot is scoped, so every request gets its own copy. The request that was already running kept 22, and the next request got 35.
IOptionsMonitor returned 35 in the middle of that same request, because its CurrentValue property always reads the latest value.
The mistake I would watch for is injecting IOptionsSnapshot into a singleton service. In Development the app refuses to start. In Production it starts fine, and that singleton keeps its first value until the next restart.
So I use IOptions by default, IOptionsSnapshot when each request needs the latest value from the file, and IOptionsMonitor in singletons and background services.
Follow me if you want more .NET concepts explained this way.
Support for agents.md in Visual Studio is coming soon. It works in our internal builds and will be in the next feature update to the public Insiders build.
I still see this mistake in most https://t.co/5lU2uiIwnK Core APIs.
The endpoint accepts a query parameter, runs an async DB call, returns the result. Looks fine. But there is no CancellationToken anywhere.
The user closes the tab. The mobile client times out. The load balancer drops the connection. The server does not care. It keeps running the query, holding the connection, allocating memory, racing toward a result nobody is waiting for.
https://t.co/5lU2uiIwnK Core gives you a token for free. Every endpoint can accept a CancellationToken parameter, and the framework wires in HttpContext.RequestAborted automatically. Pass it down to EF Core, HttpClient, file IO, channels, any async call. The moment the request is aborted, those operations stop. The DB query is cancelled mid-flight. The HTTP call is dropped. The connection goes back to the pool.
Two scenarios where this is the difference between healthy and on fire:
A burst of users hammering a slow search endpoint. Half rage-click and abandon. Without the token, the server runs every query to completion. With it, the abandoned ones drop in milliseconds and the pool stays open for the users who are still waiting.
A long-running export that fails halfway. The client retries with new parameters. Without the token, the old export keeps grinding for two more minutes while the new one queues behind it. With it, the connection abort frees the worker immediately.
The change is two parameters: one on the endpoint, one on the data access method. That is it.
The counter I hear: "what about background work that should not be cancelled?" Fair. Pass CancellationToken.None explicitly for those, and the intent is documented right in the signature.
Every async IO call in your codebase should accept and propagate a CancellationToken. The ones that do not are the ones that wake you up at 2am.
What's the oldest async method in your codebase that still doesn't take a token?
𝟭𝟳 .𝗡𝗘𝗧 𝗹𝗶𝗯𝗿𝗮𝗿𝗶𝗲𝘀 𝗲𝘃𝗲𝗿𝘆 𝗯𝗮𝗰𝗸𝗲𝗻𝗱 𝗱𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿 𝘀𝗵𝗼𝘂𝗹𝗱 𝗵𝗮𝘃𝗲 𝗶𝗻 𝘁𝗵𝗲𝗶𝗿 𝘁𝗼𝗼𝗹𝗯𝗼𝘅
You don't need to build everything from scratch. Here's what each one solves:
1. 𝗪𝗼𝗹𝘃𝗲𝗿𝗶𝗻𝗲 - modern mediator and message bus for CQRS, with a built-in outbox, retries, and scheduling baked in.
2. 𝗗𝗮𝗽𝗽𝗲𝗿 - lightweight micro ORM, my pick when a query has a lot of tables and messy joins.
3. 𝗦𝗲𝗿𝗶𝗹𝗼𝗴 - structured logging with support for 40+ sinks.
4. 𝗕𝗼𝗴𝘂𝘀 - generates realistic fake data for testing and development.
5. 𝗙𝗹𝘂𝗲𝗻𝘁 𝗩𝗮𝗹𝗶𝗱𝗮𝘁𝗶𝗼𝗻 - validates models in a clear, fluent syntax.
6. 𝗥𝗲𝗳𝗶𝘁 - cuts the boilerplate out of HTTP API calls, built on top of HttpClient.
7. 𝗛𝗲𝗮𝗹𝘁𝗵 𝗖𝗵𝗲𝗰𝗸𝘀 - a standardized way to monitor service status and plug into alerting.
8. 𝗛𝗮𝗻𝗴𝗳𝗶𝗿𝗲 / 𝗤𝘂𝗮𝗿𝘁𝘇 - reliable background job scheduling for anything beyond simple hosted services.
9. 𝗡𝗼𝗱𝗮 𝗧𝗶𝗺𝗲 - proper time zone and date/time handling, built by Jon Skeet.
10. 𝗔𝘂𝘁𝗼𝗳𝗮𝗰 - a DI container built for advanced scenarios.
11. 𝗠𝗶𝗻𝗶𝗣𝗿𝗼𝗳𝗶𝗹𝗲𝗿 - quick, easy speed profiling for your app.
12. 𝗙𝗮𝘀𝘁𝗘𝗻𝗱𝗽𝗼𝗶𝗻𝘁𝘀 - REPR pattern library for building Web APIs, a structured alternative to controllers and Minimal APIs.
13. 𝗡𝗦𝘂𝗯𝘀𝘁𝗶𝘁𝘂𝘁𝗲 - a mocking framework that's simple to set up; my switch after I dropped Moq over their data collection practices.
14. 𝗦𝘆𝘀𝘁𝗲𝗺.𝗧𝗲𝘅𝘁.𝗝𝘀𝗼𝗻 - mature JSON serialization, my default over Newtonsoft for better performance.
15. 𝗕𝗲𝗻𝗰𝗵𝗺𝗮𝗿𝗸𝗗𝗼𝘁𝗡𝗲𝘁 - accurate speed measurement for your code.
16. 𝗦𝗰𝗮𝗹𝗮𝗿 - interactive API docs, now the default replacement for Swagger UI in .NET 9 and later.
17. 𝗦𝗶𝗴𝗻𝗮𝗹𝗥 - simplifies real-time features like chat, built on WebSockets under the hood.
Which one do you reach for the most?
📌 If you found it helpful, then you should join my weekly .NET newsletter with 10k+ engineers. Subscribe here → https://t.co/wzKsfBgAOw
Repost ♻️ would be appreciated
#dotnet
#csharp
#dotnetcore
#softwareengineering
#backenddevelopment
New GitHub Copilot pricing is here. And it requires new usage behaviour.
Left (light):
- Ask mode with Auto model (10% discount)
- 0.8 AI credits
Right (dark):
- Agent mode with Sonnet 4.6
- 4.3 AI credits
Same prompt and same useful answer. 81% cheaper.
Stop building your own auth system.
It’s 2026, and Keycloak is still one of the best ways to handle identity in .NET apps.
I just dropped a full guide on integrating Keycloak 26 with .NET 10 using Docker and OAuth 2.0.
Full setup here: https://t.co/gfaPkSxTGy
Two things you need to know about the EF Core bulk update APIs:
- They execute immediately on the database
- They aren't part of the native unit of work
- They don't affect the change tracker
This seriously affects your design, so be mindful of how these APIs work.
AI rant..🧵
Each Friday I set aside time to learn, use our products in development, tinker. My fridays are now consumed with understanding AI for productivity and accelerated development. Beware this is an AI rant. 1/15
Stop wasting the first 3 days of every project setting up boilerplate.
I built a free, production-ready Clean Architecture template to handle the plumbing for you.
It's already used by 40,000+ developers.
Here is what's inside the latest version:
- 𝗨𝗽𝗱𝗮𝘁𝗲𝗱 𝘁𝗼 .𝗡𝗘𝗧 𝟭𝟬
- 𝗡𝗲𝘄 .𝘀𝗹𝗻𝘅 𝗦𝗼𝗹𝘂𝘁𝗶𝗼𝗻 𝗙𝗼𝗿𝗺𝗮𝘁
- CQRS (No MediatR dependency)
- Structured Logging & Validation
- JWT Authentication & RBAC
- Docker Compose support
It saves you hours of setup time.
Download it for free here: https://t.co/RB9Rj29qV6
💡 Why the shift to .slnx? The new Solution format in .NET is a game-changer. It replaces the old bloated syntax with a clean XML syntax. It makes merge conflicts in your solution file a thing of the past.
They asked me this question, and I didn’t know the answer.
What's the difference between a Mutex and a Semaphore?
Mutexes and Semaphores are synchronization mechanisms used in concurrent programming.
They coordinate access to shared resources and protect them from simultaneous access.
Mutex
A mutex, short for mutual exclusion, is like a lock that ensures only one thread can access a resource at any given time.
Imagine it as a key to a single-person restroom. Only one person can use it at a time, and it stays locked until the person is done. Mutexes are binary—either locked or unlocked.
Semaphore
A semaphore is like a parking lot with multiple spots. It uses a counter to track available resources, allowing multiple threads to access them concurrently.
The counter starts at the number of available resources and goes down each time a thread takes a spot. When a thread leaves, the counter goes up.
Depending on the count, semaphores can allow multiple threads in.
Who owns What?
Mutexes maintain ownership, acquire, and release by the same thread or process.
In contrast, semaphores have no inherent concept of ownership. Any thread or process can increment or decrement the semaphore count.
When to use each?
• Mutex: When you need to ensure only one thread can access a resource at a time.
• Semaphore: When you need to allow a limited number of threads to access a resource concurrently.
Quick Analogies
• Mutex: A single key to a restroom. One person at a time.
• Semaphore: A parking lot with limited spaces. Multiple cars can park, but only up to the limit.
I hope this helps in your next interview.
Stay curious!
Something developers should be doing is always honing their skills. One way to do this is to traverse forum post like Stackoverflow. Find something unknown and experiment. In the following code I setup code to work with simple json that for some readers is new while others old hat but the point is to learn something new.
As done in the gist, experiment in a new class rather than say write code in main method of a console project and even better, write the code in a class project. Once the code is understood, document the code at method levels and create a readme file with details as time goes on without documentation a developer may forget details of code experimentation.
https://t.co/SrLtcQPm3q
Most C# coding standards recommend using camelCase for local variables and _camelCase for private or internal fields. Unfortunately, out of the box Visual Studio just uses camelCase for these fields.
https://t.co/dXB9GZed9Z
#VisualStudio#CleanCode
Your data has a temperature, and you are wasting money if you don't know it.
Hot, Warm, and Cold data.
Storing data is not just about saving it and forgetting about it. You need to understand how often you will access the data and how long you should keep it.
You can group data into three categories based on how often it's accessed:
Hot data
• What It Is: Data that you need often and fast.
• Where It's Stored: On fast storage like SSDs or even in memory.
• Examples: Things like product recommendations or cached search results.
• Cost: Storing hot data is expensive, but accessing it is cheap because it's always ready to go.
Warm Data
• What It Is: Data you access occasionally, like once a month.
• Where It's Stored: On slower but still accessible storage, e.g., Amazon S3 Infrequently Accessed Tier, Google Nearline.
• Examples: Older logs or data that are not as frequently needed. This could be data that you use for reporting or analytics.
• Cost: It is cheaper to store than hot data, but accessing it costs a bit more.
Cold Data
• What It Is: Data are rarely accessed and primarily kept for long-term storage.
• Where It's Stored: On the cheapest storage options, like HDDs or cloud archive services.
• Examples: Old backups or records that you keep for compliance reasons.
• Cost: It is very cheap to store but can be slow and expensive to access.
Retention is a different animal, explains "how long you should keep data" and is based on 4 pillars:
Value
Is this data critical for you, or can it be recreated if needed? You should keep Important data for longer.
Time
For data you store in fast-access places like memory, set a time limit (TTL) for how long it stays there before moving it to cheaper storage.
Compliance
Some laws require you to keep data for a certain amount of time or delete it after a specific period. Make sure your data storage practices follow these rules.
Cost
Storing data costs money. To save on storage costs, you can automate deleting or archiving data when it's no longer needed.
Don't just store data—manage it. Save this for your next Storage Decision.
Quick C# Tip 💡
This is the way how to enumerate C# enum:
In C# 12 with .NET 8, you can enumerate an enum using the 𝗘𝗻𝘂𝗺.𝗚𝗲𝘁𝗩𝗮𝗹𝘂𝗲𝘀 method.
This method returns an array of the values in the enum, which you can then iterate over.
Enum.GetValues(typeof(Colors)) gets an array of all the values in the Colors enum.
This ensures that the color variable is of the Colors type during enumeration.
Did you use it already?
__
Transform your API development process with Postman Flows! Experience a new way to visually create, debug, and automate complex API workflows with ease. Dive into the future of API management and enhance your productivity https://t.co/eqQDSsM5Gl.
#dotnet