MAUI Capacity Planning
C# .NET MAUI Capacity Planning Performance Memory Management Load Testing Infrastructure Sizing API Backend Database Storage Auto-scaling Cross-Platform
| Platform | Avg Memory | Max Memory | Startup Time | APK/IPA Size |
|---|---|---|---|---|
| Android | 80 MB | 256 MB | 1.5s | 25 MB |
| iOS | 60 MB | 200 MB | 1.2s | 30 MB |
| Windows | 120 MB | 512 MB | 0.8s | 50 MB |
| macOS | 90 MB | 300 MB | 1.0s | 45 MB |
Performance Profiling
# === MAUI Performance Profiling ===
# Visual Studio Diagnostic Tools
# 1. Debug -> Performance Profiler
# 2. Select: CPU Usage, Memory Usage, .NET Async
# 3. Run and analyze
# Memory Profiling Code
# public class MemoryTracker
# {
# private readonly Timer _timer;
#
# public MemoryTracker()
# {
# _timer = new Timer(LogMemory, null, 0, 5000);
# }
#
# private void LogMemory(object state)
# {
# var totalMemory = GC.GetTotalMemory(false);
# var gen0 = GC.CollectionCount(0);
# var gen1 = GC.CollectionCount(1);
# var gen2 = GC.CollectionCount(2);
#
# Debug.WriteLine($"Memory: {totalMemory / 1024 / 1024}MB " +
# $"| GC: Gen0={gen0} Gen1={gen1} Gen2={gen2}");
# }
# }
# Image Optimization
# public static class ImageOptimizer
# {
# public static ImageSource LoadOptimized(string url, int maxWidth = 400)
# {
# return new UriImageSource
# {
# Uri = new Uri($"{url}?w={maxWidth}&q=80"),
# CachingEnabled = true,
# CacheValidity = TimeSpan.FromDays(7),
# };
# }
# }
from dataclasses import dataclass
@dataclass
class AppMetrics:
screen: str
memory_mb: float
cpu_pct: float
render_ms: float
api_calls: int
metrics = [
AppMetrics("Home", 45.2, 12.5, 16.0, 3),
AppMetrics("Product List", 85.6, 25.0, 22.0, 5),
AppMetrics("Product Detail", 62.3, 15.0, 18.0, 2),
AppMetrics("Cart", 38.5, 8.0, 14.0, 1),
AppMetrics("Checkout", 55.0, 20.0, 25.0, 4),
AppMetrics("Profile", 42.1, 10.0, 15.0, 2),
]
print("=== MAUI App Performance ===")
for m in metrics:
print(f" [{m.screen}]")
print(f" Memory: {m.memory_mb}MB | CPU: {m.cpu_pct}% | Render: {m.render_ms}ms | API: {m.api_calls}")
Load Testing Backend
# === k6 Load Test for Mobile API ===
# k6 Script
# import http from 'k6/http';
# import { check, sleep } from 'k6';
#
# export const options = {
# stages: [
# { duration: '2m', target: 100 }, // Ramp up
# { duration: '5m', target: 100 }, // Sustained
# { duration: '2m', target: 500 }, // Peak
# { duration: '5m', target: 500 }, // Sustained peak
# { duration: '2m', target: 0 }, // Ramp down
# ],
# thresholds: {
# http_req_duration: ['p(95)<500', 'p(99)<1000'],
# http_req_failed: ['rate<0.01'],
# },
# };
#
# export default function () {
# const token = 'Bearer xxx';
# const headers = { Authorization: token, 'Content-Type': 'application/json' };
#
# // API Endpoints
# let res = http.get('https://api.example.com/products', { headers });
# check(res, { 'products 200': (r) => r.status === 200 });
#
# res = http.get('https://api.example.com/products/1', { headers });
# check(res, { 'detail 200': (r) => r.status === 200 });
#
# res = http.post('https://api.example.com/cart', JSON.stringify({
# product_id: 1, quantity: 1
# }), { headers });
# check(res, { 'cart 201': (r) => r.status === 201 });
#
# sleep(1);
# }
# // Run: k6 run --out json=results.json load_test.js
@dataclass
class LoadTestResult:
scenario: str
vus: int
rps: float
p95_ms: float
p99_ms: float
error_rate: float
status: str
results = [
LoadTestResult("Baseline", 10, 150, 45, 80, 0.0, "PASS"),
LoadTestResult("Normal Load", 100, 1200, 120, 250, 0.1, "PASS"),
LoadTestResult("Peak Load", 500, 4500, 350, 680, 0.5, "PASS"),
LoadTestResult("Stress Test", 1000, 6200, 850, 1500, 2.5, "FAIL"),
LoadTestResult("Spike Test", 2000, 5800, 1200, 3000, 8.0, "FAIL"),
]
print("\n=== Load Test Results ===")
for r in results:
print(f" [{r.status}] {r.scenario} ({r.vus} VUs)")
print(f" RPS: {r.rps} | P95: {r.p95_ms}ms | P99: {r.p99_ms}ms | Errors: {r.error_rate}%")
Infrastructure Sizing
# === Infrastructure Capacity Planning ===
# Calculation
# DAU: 50,000 users
# Peak concurrent: 5,000 (10% of DAU)
# API calls per session: 20
# Session duration: 10 min
# Peak RPS: 5000 * 20 / 600 = ~167 RPS
# With 2x headroom: 334 RPS needed
# Per instance throughput: 100 RPS (from load test)
# Instances needed: ceil(334 / 100) = 4 instances
@dataclass
class CapacityPlan:
component: str
current: str
peak: str
recommended: str
cost_mo: str
plan = [
CapacityPlan("API Servers", "2x t3.medium", "4x t3.medium", "4x t3.medium + ASG", "$240"),
CapacityPlan("Database", "db.r6g.large", "db.r6g.xlarge", "db.r6g.large + Read Replica", "$350"),
CapacityPlan("Redis Cache", "cache.t3.medium", "cache.r6g.large", "cache.r6g.medium", "$120"),
CapacityPlan("CDN (Assets)", "100 GB/mo", "500 GB/mo", "CloudFront 500GB", "$50"),
CapacityPlan("Storage (S3)", "50 GB", "200 GB", "S3 Standard 200GB", "$5"),
CapacityPlan("Push Notifications", "50K/day", "200K/day", "FCM + APNs", "$0"),
]
print("Infrastructure Capacity Plan:")
for p in plan:
print(f" [{p.component}]")
print(f" Current: {p.current} | Peak: {p.peak}")
print(f" Recommended: {p.recommended} | Cost: {p.cost_mo}/mo")
# Growth Projection
growth = {
"Month 1": {"dau": 5000, "rps": 17, "instances": 1, "cost": "$150"},
"Month 3": {"dau": 15000, "rps": 50, "instances": 1, "cost": "$200"},
"Month 6": {"dau": 50000, "rps": 167, "instances": 2, "cost": "$400"},
"Month 12": {"dau": 150000, "rps": 500, "instances": 5, "cost": "$900"},
"Month 24": {"dau": 500000, "rps": 1667, "instances": 17, "cost": "$2,500"},
}
print(f"\n\nGrowth Projection:")
for period, data in growth.items():
print(f" [{period}] DAU: {data['dau']:,} | RPS: {data['rps']} | Instances: {data['instances']} | Cost: {data['cost']}")
เคล็ดลับ
- Profile: วัด Memory และ CPU จริงทุก Platform ก่อน Launch
- Load Test: ทดสอบ 2-3x Peak Load ที่คาดหวัง
- Headroom: เผื่อ Capacity 30-50% สำหรับ Spike
- Cache: ใช้ Cache ทั้งฝั่ง App และ Server ลด Load
- Auto-scale: ตั้ง Auto-scaling ไม่ต้อง Manual Scale
Capacity Planning สำหรับ MAUI App คืออะไร
วางแผนทรัพยากร Memory API Server Database Storage CDN Load Test Scale Growth ทดสอบก่อน Launch
MAUI App ใช้ Memory เท่าไหร่
Android 50-150MB iOS 40-120MB Windows 80-200MB ขึ้นอยู่กับหน้า รูปภาพ Cache Profiler วัดจริง Optimize Image Lazy Loading
Load Testing สำหรับ Mobile Backend ทำอย่างไร
k6 Locust Virtual Users Ramp up Response Time Throughput Error Rate Peak 2-3x Sustained Stress Spike Test
Infrastructure Sizing ทำอย่างไร
DAU MAU RPS Peak Concurrent Database Connections Storage Growth Load Test Throughput Instance Headroom 30-50% Auto-scaling
สรุป
C# .NET MAUI Capacity Planning Performance Profiling Memory Load Testing k6 Infrastructure Sizing API Backend Database Auto-scaling Growth Projection Cost Optimization
