1. Baselinetoday's load, p95, CPU per request
→
2. Forecastgrowth, seasonality, campaigns
→
3. Add headroomrun at 60–70%, N+1 for failures
→
4. Load testprove the per-instance limit
→
5. Set autoscale limitsmin, max, quotas, DB limits
→
6. Reviewmonthly, after big events
L = λ × W
L = average number of requests in the system (in flight)
λ (lambda) = arrival rate (requests per second)
W = average time each request spends in the system
Works for any stable system: APIs, queues, call centres, bank branches.
🧮 Example
Peak = 400 requests/s, average response = 0.25 s.
L = 400 × 0.25 = 100 requests in flight.
Load test shows one instance handles 25 concurrent requests at 65% CPU → 100 ÷ 25 = 4 instances, + 1 for a failure (N+1) = 5.
If a slow dependency doubles W to 0.5 s, L doubles to 200. Latency eats capacity.
Informwho spends what: tags, showback, unit cost
→
Optimiseright-size, commit, use spot, delete waste
→
Operatebudgets, alerts, policies, reviews
↻
📏 Unit economics
Track cost per transaction, per customer or per payment, not just the total bill. A rising bill with a falling unit cost is healthy growth.
📉 Right-sizing
Most VMs and DBs are over-provisioned. Use utilisation data (Azure Advisor, AWS Compute Optimizer) to step down a size. Turn off non-prod at night.
🤝 Commitments
Reservations and savings plans (1 or 3 years) cut the price of steady, always-on load. Commit to the baseline only, not the peak.
⚡ Spot / preemptible
Big discounts on spare capacity, but the cloud can take it back at short notice. Only for interruptible work: batch, CI, stateless workers.
🏷 Tagging
Tag every resource (app, env, owner, cost-centre) and enforce it with policy. No tags = no showback.
🔔 Budgets & alerts
Budgets per subscription or team, alerts at 50/80/100% and on anomalies. A forgotten GPU or log ingestion spike shows up in days, not at month end.
.NET 10 How to implement it
| Library / API | Package | Use it for |
| Concurrency and throughput metrics | built-in System.Diagnostics.Metrics; ASP.NET Core http.server.active_requests | Measure L and λ for Little's Law per instance. Watch live with dotnet-counters monitor |
| Load testing in C# | NBomber commercial licence | Find the per-instance limit. Free for personal use only; organisations need a paid licence. Free alternatives: k6, JMeter, Azure Load Testing |
| Micro-benchmarks | BenchmarkDotNet | Cost per call of hot code paths (see 3.8) |
| Event-driven autoscale | Platform config: KEDA scalers in Azure Container Apps / AKS (Service Bus, Kafka, HTTP, cron) | Scale workers on queue length; scheduled scaling with the cron scaler |
| Cost queries | Azure.ResourceManager.CostManagement | Query cost by tag or resource group and build cost-per-transaction reports |
| Usage metrics | Azure.Monitor.Query.Metrics, Azure.Monitor.Query.Logs | Pull utilisation and request counts for capacity reviews. These replace the older Azure.Monitor.Query package, now deprecated |
// Track in-flight work (L) and completed work (λ) for a queue worker
public sealed class WorkerMetrics
{
private readonly UpDownCounter<long> _inFlight; // L
private readonly Counter<long> _done; // its rate = λ
public WorkerMetrics(IMeterFactory meterFactory)
{
var meter = meterFactory.Create("Bank.Payments.Worker");
_inFlight = meter.CreateUpDownCounter<long>("payments.in_flight");
_done = meter.CreateCounter<long>("payments.processed");
}
public async Task TrackAsync(Func<Task> work)
{
_inFlight.Add(1);
try { await work(); _done.Add(1); }
finally { _inFlight.Add(-1); }
}
}
// dotnet-counters monitor -n PaymentsWorker --counters Bank.Payments.Worker
One formula every architect should know: L = λ × W 🧮
📥 λ = how many requests arrive per second
⏱ W = how long each one takes
🔄 L = how many are in flight at once, which is the capacity you must provide
400 req/s × 0.25 s = 100 in flight. If a slow dependency doubles latency, you need double the capacity. Latency is a cost.
💸 Then FinOps: reserve the baseline, autoscale the peak, use spot for batch, and track cost per transaction, not just the bill.
#CapacityPlanning #FinOps #Cloud #SystemDesign