Skip to main content

14 posts tagged with ".NET"

Runtime behaviour, GC and configuration details of .NET that only surface under real production load.

View All Tags

Building a Multi-Tenant CRM Platform from Nothing: 20 Months on the Job

· 31 min read
Nguyễn Huỳnh Minh Tiến
Middle Fullstack Developer @ Utop.vn
Summary

In January 2025 I was handed a product to initialise — the first time in my career — a multi-tenant CRM platform whose repository was completely empty when I took it on. For nearly its first year it lived in demo mode, shown to customers across many different industries, until late 2025 when a healthcare client signed and it moved into real delivery. Twenty months later it is 18 microservices on ABP Framework / .NET 9 and 13 Angular libraries, built by a team that grew to 25 people. This is not a technical article but a career story told chronologically, and it includes the export screen that forgot its permission checks, the two weeks of Angular work I had to revert, the three months mid-year when I was moved to a different loyalty project and committed nothing, and a migration so boring that nobody noticed it had happened. It also covers the EAV architecture that lets customers configure their own data fields from the portal, along with the months I spent wrestling with its performance and that of the dynamic filter sitting on top of it, the stretch where I mentored four interns for the first time, and how the way I write code shifted from typing everything by hand to ChatGPT, then Cursor, then Claude.

On 14 January 2025 I opened a completely empty repository with nothing in my head but a handful of very ordinary questions: what to name the solution, which folder goes where, how to split the database tables.

Until then I had always inherited codebases that were already running, where the work was reading, fixing and adding screens. This felt entirely different: there was nothing to copy, and whatever I typed would become the thing everyone else followed. It sounds impressive in the telling, but sitting in front of that empty repo I was genuinely a bit overwhelmed.

My commit that day was a single line, Init - Databases, projects, and there was nothing ceremonial about it.

Twenty months later that repo holds 18 microservices with 29,607 commits from 25 people. I am still there, and every so often I still open git log --reverse to look at those first few lines.

git log --reverse --format="%h %ad %an %s" --date=short | head -5

I am writing this to read again in a few years. The product belongs to the company, so I have anonymised all the proper nouns — the product name, the repo name, the client, the internal libraries — while leaving the tech stack intact, since that is the part I can tell.

Why Does .NET Eat 96% of Container RAM While Idle? Server GC and How to Cut Memory by 65%

· 12 min read
Nguyễn Huỳnh Minh Tiến
Middle Fullstack Developer @ Utop.vn
Summary

An ASP.NET Core 9 container sat at 987 MiB against a 1 GiB ceiling (96%) after two hours without receiving a single request. This was not a memory leak: the number was absolutely flat across repeated measurements, which is the signature of retained heap rather than a leak. The cause was Server GC — the ASP.NET Core default, which creates one heap per CPU core and releases very little memory back to the operating system. Setting DOTNET_gcServer=0 and DOTNET_GCConserveMemory=5 brought anonymous memory down from 822 MB to 280 MB (−65%), measured as stable after 30 minutes. The trade-off: Workstation GC gives lower throughput under heavy load on many-core machines.

This post records a real diagnostic session on a 4-core / 8 GB VPS running nine WordPress sites alongside a .NET API. Every number below is measured, not illustrative.

What Is Scalar? Why Use Scalar Instead of Swagger UI in ASP.NET Core 10

· 9 min read
Nguyễn Huỳnh Minh Tiến
Middle Fullstack Developer @ Utop.vn
Summary

Scalar is an open-source API Reference UI that replaces Swagger UI, and it is what Microsoft recommends for ASP.NET Core from .NET 9 onward. Starting with .NET 9, Microsoft removed Swashbuckle (Swagger UI) from the default Web API template and replaced it with Microsoft.AspNetCore.OpenApi combined with Scalar. This post explains the reasoning behind that change, compares Scalar against Swagger UI feature by feature, and walks through setting Scalar up in ASP.NET Core 10 — both for a brand new project and as a migration from an existing one.

If you created a new ASP.NET Core Web API project on .NET 9 or .NET 10 and were surprised to find Swagger UI missing, you are not alone. Microsoft deliberately replaced Swashbuckle with a native OpenAPI pipeline, and Scalar is the UI recommended alongside it.

The Scalar API Reference interface on scalar.com

Giới thiệu RabbitMQ - Message Broker mạnh mẽ

· 10 min read
Nguyễn Huỳnh Minh Tiến
Middle Fullstack Developer @ Utop.vn
Summary

RabbitMQ là một open-source message broker phổ biến trong kiến trúc microservices, hỗ trợ nhiều messaging protocols như AMQP, MQTT, STOMP. Bài viết giới thiệu khái niệm cơ bản (Producer, Consumer, Queue, Exchange), cách cài đặt RabbitMQ, và ví dụ thực tế với .NET 8 để gửi/nhận messages. RabbitMQ giúp giải quyết các vấn đề về decoupling, scalability và reliability trong distributed systems.

RabbitMQ là một trong những message broker phổ biến nhất trong thế giới phát triển phần mềm hiện đại. Trong bài viết này, chúng ta sẽ tìm hiểu về RabbitMQ và cách sử dụng nó trong ứng dụng .NET 8.