𝗛𝗼𝘄 𝗥𝗮���𝗯𝗶𝘁𝗠𝗤 𝗺𝗲𝘀𝘀𝗮𝗴𝗶𝗻𝗴 𝘄𝗼𝗿𝗸𝘀 📨
RabbitMQ is one of the most popular message brokers in modern distributed systems. It's also widely used in cloud environments and on-premise.
But how does messaging work with RabbitMQ?
The simplest scenario is a publish-subscribe with one queue. The producer publishes messages to the queue, and a consumer subscribes to the queue and handles incoming messages.
What happens if we introduce a second consumer to the same queue? In that case, we have a competing consumer scenario. When one consumer handles a message from the queue, another consumer can't process it. This means that consumers compete with each other who will process the message.
What if you need each consumer to handle the message?
RabbitMQ has a concept of exchanges. You can think of exchanges as routers that distribute messages between queues based on the exchange type. The most common exchange type is a fanout exchange, which routes messages to all connected queues.
Now, back to our original question – handling the same message with all consumers. We need to create a queue for each consumer. Then, we can introduce a fanout exchange and bind it to the respective queues. Lastly, we need to update the producer to publish messages to the exchange (instead of the queue).
Have you used RabbitMQ in some of your projects?
𝗦𝗰𝗮𝗹𝗶𝗻𝗴 𝗪𝗲𝗯 𝗮𝗽𝗽𝘀 𝘁𝗼 𝟭,𝟬𝟬𝟬,𝟬𝟬𝟬 𝘂𝘀𝗲𝗿𝘀
I worked on a large system that had more than a million users. This is how we scaled the system to handle that amount of traffic.
The application started as a humble monolith: one application server and one database server. This worked well for a few years, but as the number of users grew, the system became slower. Something needed to be done.
The next evolution was horizontally scaling the Web API to handle more requests. The database instance was scaled vertically (scale up). However, we soon started running into problems with the database.
We already used caching to some extent, but this was simple in-memory caching on the application servers. So, we decided to introduce distributed caching with Redis. After introducing Redis, the load on the database was drastically reduced as most requests could be served from the cache. An added benefit was improved performance and responsiveness.
I want you to take away one thing from this: solve the problem you have right now. We're prone to overengineering systems before they reach any significant scale.
Also, why would you want to scale an unprofitable application? Developers rarely think about financial stuff. Don't forget that your application is probably there to run a business. And a business is crappy if it's not profitable.
What was the largest application you worked on?
Is it time to build your own agent harness?
#dotNETRocks and Emmz Rendle discuss her work on Daemonic AI, the upcoming rug pull in AI software dev tools, and choosing what agents and configurations to use for each of the agent roles you want. Listen in: https://t.co/BOH4PYWVKY
No - you aren't doing "integration" testing with an in-memory database.
At best it's a glorified unit test...
I've seen many examples using the EF Core in-memory provider.
This isn't an integration test because there's no real database.
Worse, this will fail to catch any LINQ or SQL bugs.
Here's a better approach:
- Use a real database or Docker container
- Connect to this database from your tests
- Write proper integration tests that have value
If you want to use Docker, I recommend exploring Testcontainers.
It lets you define throwaway containers in your tests.
What tools or methods do you use for integration testing?
Your C# lock works perfectly.
Until you run two instances of your app.
This is an easy problem to miss.
On one server, you can stop two tasks from changing the same data at the same time.
But once your app runs across many instances, each one has its own memory.
They cannot see each other's locks.
Now two workers may:
→ Run the same scheduled task
→ Refresh the same cache entry
→ Process the same shared resource
→ Generate the same report
→ Update data at the same time
That can lead to duplicate work, extra load, or broken data.
This is where distributed locking helps.
It gives several app instances one shared rule:
Only one of you can do this work right now.
You do not need it everywhere.
But for jobs that must run once, or shared work that must not overlap, it can prevent some very painful bugs.
If you already use PostgreSQL, advisory locks are a simple place to start.
And when you need a cleaner option across Postgres, Redis, or SQL Server, a distributed locking library can handle more of the hard parts.
Your app may look fine on one server.
The real test starts when you add the second one.
Here’s how to coordinate that work safely in .NET: https://t.co/ELbD0ZvL0C
𝗦𝘁𝗼𝗽 𝘂𝘀𝗶𝗻𝗴 𝗗𝗮𝘁𝗲𝗧𝗶𝗺𝗲.𝗡𝗼𝘄 𝗶𝗻 𝘆𝗼𝘂𝗿 𝗰𝗼𝗱𝗲.
Here is why 👇
Almost every .NET project I review has the same hidden bug.
DateTime[.]Now is scattered everywhere: services, validators, business rules, even domain entities.
It looks innocent. But it quietly breaks your tests and your code's reliability.
📌 The real problem with DateTime[.]Now:
→ You can't test time-dependent logic
→ You can't simulate "tomorrow" or "1 year ago"
→ Your tests become flaky and timezone-dependent
→ Your business rules silently depend on the server clock
→ Switching environments breaks behavior in subtle ways
Want to test what happens when a subscription expires?
Or when a free trial ends?
Or when a discount window closes at midnight?
You can't! Unless you control time in your tests.
✅ The fix is simple: inject time as a dependency.
You have two clean options in modern .NET:
1. Custom IDateTimeProvider interface (works in any .NET version)
2. Built-in TimeProvider (available since .NET 8)
I prefer TimeProvider for new projects.
It's part of the framework, ships with FakeTimeProvider for testing, and supports timers and time zones out of the box.
Register it once in DI:
𝚋𝚞𝚒𝚕𝚍𝚎𝚛.𝚂𝚎𝚛𝚟𝚒𝚌𝚎𝚜.𝙰𝚍𝚍𝚂𝚒𝚗𝚐𝚕𝚎𝚝𝚘𝚗(𝚃𝚒𝚖𝚎𝙿𝚛𝚘𝚟𝚒𝚍𝚎𝚛.𝚂𝚢𝚜𝚝����𝚖);
Then inject it like any other service and call GetUtcNow() instead of DateTime[.]UtcNow.
This one change makes your code testable, predictable, and ready for production.
Where do you still use DateTime[.]Now in your code? Leave a comment down below 👇
——
♻️ Repost to help others write testable, time-aware code
➕ Follow me ( @AntonMartyniuk ) to improve your .NET and Architecture Skills
Architecture diagrams don’t enforce architecture.
Tests do.
Every project starts clean:
- Layer boundaries are agreed
- Dependency rules are clear
- Naming conventions make sense
- The folder structure looks intentional
Then six months pass.
A domain service ends up in Infrastructure.
A handler gets named `ProcessPaymentService`.
A class that should be `internal` becomes `public`.
A NuGet dependency leaks into the wrong layer.
Nobody meant to break the architecture.
But nobody caught it either.
That’s why I like architecture tests.
They turn your architectural rules into automated tests that run in CI.
If someone violates a rule, the build fails.
The 5 tests I add to .NET projects are:
1. Layer dependency tests
2. Naming convention tests
3. Colocation tests
4. Visibility tests
5. Dependency guard tests
They run fast.
They don’t need infrastructure.
And they document the architecture in a way the build can actually enforce.
Start with layer dependency tests.
They take a few minutes to add and catch the most damaging violations.
Then add the rest as your codebase grows.
I wrote a full breakdown with ArchUnitNET, xUnit, and reflection examples here: https://t.co/Ch3SNRUe7a
Building Production-Ready Software in 2026
Should take days instead of months
Most developers spend weeks on architecture decisions and months writing boilerplate code.
I use this proven 10-step workflow that takes projects from idea to deployment in days.
𝗣𝗵𝗮𝘀𝗲 𝟭: 𝗥𝗲𝗾𝘂𝗶𝗿𝗲𝗺𝗲𝗻𝘁𝘀 & 𝗣𝗹𝗮𝗻𝗻𝗶𝗻𝗴
• 𝗦𝘁𝗲𝗽 𝟭: Define Business Requirements
- Upload your BRD to Claude Opus 4.7 and use the Plan Mode. Clarify user roles, core features, workflows, business rules, and edge cases until all ambiguity is removed.
Free guide: https://t.co/0RxR5YDLXq
• 𝗦𝘁𝗲𝗽 𝟮: Define Non-Functional Requirements
- State your constraints: availability, performance, scalability, cost, security.
𝗣𝗵𝗮𝘀𝗲 𝟮: 𝗔𝗿𝗰𝗵𝗶𝘁𝗲𝗰𝘁𝘂𝗿𝗲 & 𝗦𝗽𝗲𝗰𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻
• 𝗦𝘁𝗲𝗽 𝟯: Design the Architecture
- Ask Claude Opus 4.7 to act as an Architect Consultant with "Extended Thinking" mode. Define architecture style, module boundaries, patterns, API contracts and database schema.
• 𝗦𝘁𝗲𝗽 𝟰: Generate the Backend Specification
- Ask Claude Opus 4.7 to create a detailed MD file for backend implementation.
You need CLAUDE[.]MD, free guide: https://t.co/mhqFgHxgEz
𝗣𝗵𝗮𝘀𝗲 𝟯: 𝗕𝗮𝗰𝗸𝗲𝗻𝗱 𝗜𝗺𝗽𝗹𝗲𝗺𝗲𝗻𝘁𝗮𝘁𝗶𝗼𝗻
• 𝗦𝘁𝗲𝗽 𝟱: Code the Backend
- Feed the MD spec to Claude Opus 4.7 with this prompt: https://t.co/a44Jg3RXNU
• 𝗦𝘁𝗲𝗽 𝟲: Review and Refine
- Ask Claude Opus 4.7 to review code quality, detect performance risks and verify security gaps. Get the prompt I use in production: https://t.co/bsfQCzy7s0
𝗣𝗵𝗮𝘀𝗲 𝟰: 𝗙𝗿𝗼𝗻𝘁𝗲𝗻𝗱 𝗜𝗺𝗽𝗹𝗲𝗺𝗲𝗻𝘁𝗮𝘁𝗶𝗼𝗻
• 𝗦𝘁𝗲𝗽 𝟳: Generate the Frontend Specification
- Ask Claude Opus 4.7 to create MD file for frontend. Use this prompt: https://t.co/3QGvuJoDrB
• 𝗦𝘁𝗲𝗽 𝟴: Code the Frontend
- Use similar prompt: "You are a Principal Developer.... Use [tech stack]. Implement a professional frontend based strictly on the MD specification file."
𝗣𝗵𝗮𝘀𝗲 𝟱: 𝗗𝗲𝗽𝗹𝗼𝘆𝗺𝗲𝗻𝘁
• 𝗦𝘁𝗲𝗽 𝟵:
- Ask Claude Opus 4.7 to write CI/CD scripts.
𝗦𝘁𝗲𝗽 𝟭𝟬: Human review, test, deploy.
Before using AI for creating production-ready apps, read this:
https://t.co/8ba53yVjg8
What AI models do you use to create production-ready apps? Leave a comment 👇
——
♻️ Repost to help others build software faster
➕ Follow me ( @AntonMartyniuk ) to improve your .NET and Architecture Skills
Do you want to improve your knowledge of software development?
Learn design patterns from these lessons I created over the past few years. 🚀
26 𝐏𝐚𝐭𝐭𝐞𝐫𝐧𝐬:
• Factory Method: https://t.co/jpTx3NZo6t
• Abstract Factory: https://t.co/RdnCbGgsUN
• Facade: https://t.co/k797kCSQnh
• Chain of Responsibility: https://t.co/rj4bttRxba
• Adapter: https://t.co/9iSc5VWFPW
• CQRS: https://t.co/fcrLik5A59
• Bridge: https://t.co/qVSzkNf7nV
• Command: https://t.co/T5LCum4ves
• Observer: https://t.co/z3PvbTX404
• Decorator: https://t.co/UfKXOUJ8Ma
• Singleton (multithreading): https://t.co/hIwIOXpfD2
• Options (IOptions): https://t.co/sPelJzpL5I
• Builder: https://t.co/V9Oyz9rmkf
• State: https://t.co/SAQcYna3xJ
• Memento: https://t.co/dBuFSWhBYc
• Strategy: https://t.co/OrcWb5RedJ
• Template Method: https://t.co/fvQyKMNfu4
• Composite: https://t.co/ThVl03kKV8
• Visitor: https://t.co/lShGtOv8sR
• Proxy: https://t.co/Aqe6EIxQMH
• Prototype: https://t.co/99gUO4aihd
• REPR: https://t.co/Bcv0fUBPMb
• Service Collection Extension: https://t.co/1EtKECNj0B
• Saga Orchestration: https://t.co/3u9I7oeuqp
• Outbox: https://t.co/C5hv1pssu3
• Circuit Breaker (resilient APIs): https://t.co/nKSi3UZRIn
You can also check my 2 ebooks on Design Patterns:
https://t.co/5QQCOJTRxu
https://t.co/MP1XK414jF (Here's a 20% discount code: DEEP20 )
__
♻️ Repost to help others learn more.
📂 Save this post for later - you'll thank yourself when refactoring at 2 AM.
➕ Follow me to learn .NET and Architecture.
Slow API requests don’t just annoy users. They quietly cap how much traffic your API can handle.
Return 202 Accepted, store the work as a job, process it with workers, and use a queue when you need scale.
Full breakdown here: https://t.co/PQ6QYja9ut
Not every AI feature needs a dedicated vector database.
If your data already lives in PostgreSQL, adding Pinecone, Qdrant, or Weaviate might be one moving part too many.
For many use cases, `pgvector` is enough.
It gives PostgreSQL native vector storage and similarity search.
That means you can keep your embeddings next to your relational data and still use the things PostgreSQL is already great at:
- joins
- filters
- pagination
- transactions
- indexes
The basic flow is simple:
1. Generate an embedding for your content
2. Store it in a `vector` column
3. Generate an embedding for the search query
4. Order results by cosine distance with `<=>`
5. Return the closest matches
Now your users can search by meaning, not just exact keywords.
A query like “how to secure an API” can return articles about authentication, JWT validation, and authorization, even if those exact words don’t appear.
In this article, I show how to build simple vector search in .NET using PostgreSQL, pgvector, Aspire, Ollama, MEAI, and Dapper.
Read the full article here: https://t.co/XiTjXOz2C4
🔍 Exploring Enterprise AI done right?
✅ #FoundryIQ episodes are live
See how Foundry IQ enables AI agents with secure, permission aware access to enterprise knowledge across Azure, SharePoint, OneLake & more.
👉 https://t.co/p8Np5mxJ4D
#IQSeries
Ethiopia helped SA freedom struggle more than any other country. So did the rest of Africa. I was directly involved in this. SA owes us respect not savagery. SA has a problem with itself not with other Africans and has become a fragile country on the brinks. Needs help agai
I built a free Clean Architecture template.
And now I've made it even better by adding Aspire.
More than 40,000+ developers have already downloaded it.
Here's what's inside:
- Simple domain model
- Domain Events pattern
- CQRS + clean use cases
- Validation and logging
- Authentication with JWT
- Boilerplate for RBAC Authz
- Minimal APIs, health checks
- Run locally with Aspire in seconds
I also made sure not to use any commercial libraries.
Get the template here: https://t.co/z109b3rqAE