Cold starts are one of the most discussed and least understood performance topics in serverless .NET. Many of the usual tips either address something you cannot control or were true years ago and no longer are. This guide separates the levers that move the number from the ones that mostly add complexity. What a cold start actually contains When Lambda has no warm execution environment available, it creates one. That includes downloading your code, starting the runtime, and running your initialization code. On .NET, the part you can influence most is the runtime start and your own startup logic: loading assemblies, JIT-compiling code, building the dependency injection container and creating SDK clients. The easiest way to see it is the REPORT line Lambda writes to CloudWatch Logs for each invocation. Cold invocations include an Init Duration field. Query that field in CloudWatch Logs Insights to get p50, p95 and p99 for your own function before changing anything. The levers, fro...
Dependency injection (DI) is usually sold as a way to make unit tests easier. In a legacy .NET modernization that is the smallest part of its value. The larger value is that DI forces a team to name the contracts between components that were tangled together for years, and once those contracts exist you can replace what sits behind them one piece at a time. This article is organized as the questions that come up when you start, in the order they usually appear. What problem does DI actually surface? Older .NET code often mixes construction, configuration and execution in one method. A routine that sends an email might create an SMTP client, read a connection string from a config file, build the message, log the attempt, retry on failure and update a database row, all inline. You cannot test it without live dependencies, and you cannot change any one of those concerns without touching the others. DI does not fix that code by itself. What it does is ask an uncomfortable question: wh...