The Same App, Built Twice
DevMentors shipped Trill as nine microservice repos, then rebuilt the identical product as a modular monolith three months later - giving us a controlled experiment in architecture that almost never exists in public.
In reading order.
DevMentors shipped Trill as nine microservice repos, then rebuilt the identical product as a modular monolith three months later - giving us a controlled experiment in architecture that almost never exists in public.
Trill's monolith makes every module type internal and gives each one an explicit friend list, so a cross-module reach is not a code-review conversation - it is a build error.
Four physical Mongo databases collapse into one when Trill is rebuilt as a monolith - and the only thing keeping the modules apart afterwards is a private const string copied into eleven files.
Trill's saga microservice references twenty-four third-party packages; the same saga as a module references one - because the monolith deleted Convey and rewrote 4,600 lines of it by hand.
Trill's hand-rolled framework follows the ASP.NET Core registration convention with unusual discipline, then breaks it twice on purpose - and the exceptions turn out to be more instructive than the rule.
Trill's monolith puts the envelope fields on the message itself, then uses one sentinel value to mean this-is-a-synchronous-call in three unrelated subsystems that never mention each other.
The Trill monolith ships a startup-time validator that compares independently declared copies of the same message and crashes the app on a mismatch - the most original idea in either build, adopted by four declarations out of twenty-two.
Two lines in Trill's module client serialise and immediately deserialise every cross-module message, buying a future network hop at the cost of a round trip that never leaves the heap - and there is a benchmark project defending the choice.
Trill's monolith implements typed Get, Post, Put and Delete extensions over IEndpointRouteBuilder on .NET 5 - the framework .NET shipped eighteen months later, complete with query binding by string replacement.
Running Trill as microservices takes eighteen containers and twenty-two published ports; running the same product as a monolith takes mongo, redis and dotnet run - and only the monolith still starts from a clean clone.
Trill's monolith routes every cross-module event through an unbounded channel drained by one background service - so its flagship end-to-end test has to sleep for two seconds to observe the architecture working.
Four non-trivial defects appear at near-identical line numbers in both builds of the same product - a ground-up rewrite by the same authors relocated them rather than finding any.
The rewrite multiplied the JWT lifetime by ten and deleted the only way to revoke a token early - one change in a JSON file, the other an absent folder, and neither visible in any diff of the domain.
Pick the one closest to the role. Each is two pages and carries the same facts.
Applied AI
Agentic AI & Cloud Engineer · multi-agent systems, RAG and MCP on AWS
Cloud & .NET
C#, .NET 10 and ASP.NET Core microservices on AWS and Azure · Terraform & AWS CDK
Data Engineering
AWS lakehouse · Kinesis, Glue (PySpark), Apache Iceberg, Lake Formation
Everything
All three domains, with the standout project from each