diff --git a/docs/dimensioning/esp32_c3/base.png b/docs/dimensioning/esp32_c3/base.png new file mode 100644 index 0000000..c46e00f Binary files /dev/null and b/docs/dimensioning/esp32_c3/base.png differ diff --git a/docs/dimensioning/esp32_c3/files_api_001.png b/docs/dimensioning/esp32_c3/files_api_001.png new file mode 100644 index 0000000..bc67914 Binary files /dev/null and b/docs/dimensioning/esp32_c3/files_api_001.png differ diff --git a/docs/dimensioning/esp32_c3/files_api_002.png b/docs/dimensioning/esp32_c3/files_api_002.png new file mode 100644 index 0000000..3671dd1 Binary files /dev/null and b/docs/dimensioning/esp32_c3/files_api_002.png differ diff --git a/docs/dimensioning/esp32_c3/files_api_003.png b/docs/dimensioning/esp32_c3/files_api_003.png new file mode 100644 index 0000000..34ee0cd Binary files /dev/null and b/docs/dimensioning/esp32_c3/files_api_003.png differ diff --git a/docs/dimensioning/esp32_c3/high_mem_cap_001.png b/docs/dimensioning/esp32_c3/high_mem_cap_001.png new file mode 100644 index 0000000..972ded2 Binary files /dev/null and b/docs/dimensioning/esp32_c3/high_mem_cap_001.png differ diff --git a/docs/dimensioning/esp32_c3/high_mem_cap_002.png b/docs/dimensioning/esp32_c3/high_mem_cap_002.png new file mode 100644 index 0000000..584e400 Binary files /dev/null and b/docs/dimensioning/esp32_c3/high_mem_cap_002.png differ diff --git a/docs/dimensioning/esp32_c3/high_mem_cap_003.png b/docs/dimensioning/esp32_c3/high_mem_cap_003.png new file mode 100644 index 0000000..44b391e Binary files /dev/null and b/docs/dimensioning/esp32_c3/high_mem_cap_003.png differ diff --git a/docs/dimensioning/esp32_c3/low_mem_cap_001.png b/docs/dimensioning/esp32_c3/low_mem_cap_001.png new file mode 100644 index 0000000..0e8571f Binary files /dev/null and b/docs/dimensioning/esp32_c3/low_mem_cap_001.png differ diff --git a/docs/dimensioning/esp32_c3/low_mem_cap_002.png b/docs/dimensioning/esp32_c3/low_mem_cap_002.png new file mode 100644 index 0000000..39c261d Binary files /dev/null and b/docs/dimensioning/esp32_c3/low_mem_cap_002.png differ diff --git a/docs/dimensioning/esp32_c3/low_mem_cap_003.png b/docs/dimensioning/esp32_c3/low_mem_cap_003.png new file mode 100644 index 0000000..16a0313 Binary files /dev/null and b/docs/dimensioning/esp32_c3/low_mem_cap_003.png differ diff --git a/docs/dimensioning/esp32_c3/measurements.json b/docs/dimensioning/esp32_c3/measurements.json new file mode 100644 index 0000000..fc49611 --- /dev/null +++ b/docs/dimensioning/esp32_c3/measurements.json @@ -0,0 +1,1907 @@ +[ + { + "id": "base", + "idle": 40320, + "usage": [ + 0, + 38592, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38944, + 40448, + 40352, + 40448, + 40352, + 40352, + 40176, + 39792, + 40736, + 40128, + 40352, + 40192, + 40176, + 40352, + 39888, + 40736, + 40448, + 40736, + 40176, + 40448, + 40352, + 40448, + 40176, + 40736, + 40448, + 40352, + 40352, + 40176, + 40736, + 40128, + 40448, + 40736, + 40448, + 40352, + 40736, + 40480, + 40720, + 40352, + 40224, + 40352, + 40128, + 40736, + 40752, + 40352, + 40736, + 40224, + 40224, + 40352, + 40128, + 40736, + 40736, + 40192, + 40352, + 40624, + 40176, + 40736, + 40736, + 40448, + 40224, + 40448, + 39184, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 195, + "errors": 0, + "avg_ms": 306.9329908153845, + "min_ms": 120.35957199987024, + "max_ms": 720.1993210001092, + "rps": 3.2, + "p95_ms": 660.0, + "p99_ms": 690.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.05, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "low_mem_cap_001", + "idle": 40320, + "usage": [ + 0, + 38592, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38400, + 38768, + 40432, + 40736, + 40736, + 40736, + 40192, + 40448, + 40352, + 40176, + 40192, + 40736, + 40128, + 40736, + 40448, + 40352, + 40352, + 40224, + 40352, + 40736, + 39792, + 40736, + 40352, + 40736, + 40352, + 40448, + 40352, + 40352, + 40176, + 40736, + 40736, + 40192, + 40352, + 40448, + 39792, + 40448, + 40736, + 40448, + 40736, + 40352, + 40448, + 40176, + 40176, + 40352, + 40736, + 40224, + 40448, + 40736, + 40448, + 40224, + 41136, + 40736, + 40224, + 40448, + 40176, + 40352, + 40352, + 40352, + 40352, + 40448, + 40448, + 40592, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 206, + "errors": 0, + "avg_ms": 289.7499063301043, + "min_ms": 111.7459689999123, + "max_ms": 688.2222139997793, + "rps": 3.5, + "p95_ms": 670.0, + "p99_ms": 680.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.0127, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "low_mem_cap_002", + "idle": 41536, + "usage": [ + 0, + 39808, + 39616, + 39616, + 39616, + 39616, + 39616, + 39616, + 39616, + 39616, + 39616, + 41376, + 43328, + 42720, + 43104, + 43712, + 43184, + 42400, + 44064, + 43392, + 44272, + 43184, + 43056, + 43280, + 43568, + 43152, + 43184, + 43664, + 43680, + 42832, + 42800, + 43120, + 43104, + 43056, + 43104, + 43008, + 43344, + 43648, + 43280, + 42720, + 43408, + 43456, + 43120, + 43120, + 42960, + 43664, + 43568, + 43568, + 43104, + 42960, + 43216, + 44032, + 43456, + 43952, + 43104, + 43440, + 43008, + 43008, + 43664, + 42960, + 43952, + 43344, + 43568, + 43392, + 43312, + 43392, + 43056, + 42720, + 43968, + 43184, + 43120, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 369, + "errors": 0, + "avg_ms": 324.6449824579858, + "min_ms": 107.9484759998195, + "max_ms": 753.1731879998915, + "rps": 6.6, + "p95_ms": 680.0, + "p99_ms": 720.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.0253, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "low_mem_cap_003", + "idle": 43968, + "usage": [ + 0, + 42240, + 42048, + 42048, + 42048, + 42048, + 42048, + 42048, + 42048, + 42048, + 42048, + 42048, + 42048, + 42752, + 49776, + 49072, + 48784, + 50288, + 49984, + 48896, + 49840, + 49760, + 49136, + 48512, + 49424, + 49168, + 48880, + 49504, + 47456, + 50032, + 49152, + 48784, + 49664, + 50240, + 49232, + 49360, + 50880, + 49600, + 50000, + 50288, + 49792, + 48784, + 49360, + 48800, + 50272, + 49056, + 49664, + 48016, + 49504, + 49232, + 49696, + 49184, + 50016, + 49792, + 49584, + 48768, + 49136, + 49184, + 49664, + 48448, + 48768, + 49152, + 49136, + 49136, + 50080, + 48544, + 49888, + 49328, + 49104, + 48880, + 49840, + 48688, + 49776, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 413, + "errors": 0, + "avg_ms": 579.1376370338962, + "min_ms": 174.81975099963165, + "max_ms": 1508.0461420002393, + "rps": 6.7, + "p95_ms": 1400.0, + "p99_ms": 1400.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.0505, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "high_mem_cap_001", + "idle": 47488, + "usage": [ + 0, + 45760, + 45568, + 45568, + 45568, + 45568, + 45568, + 45568, + 45568, + 45568, + 45568, + 45568, + 45568, + 47616, + 47392, + 47904, + 47904, + 47392, + 47360, + 47792, + 47344, + 47344, + 47520, + 46960, + 47520, + 47344, + 47904, + 47392, + 47056, + 47392, + 47360, + 47520, + 47520, + 47344, + 47392, + 47520, + 47344, + 47792, + 47616, + 47616, + 47520, + 47520, + 46960, + 47344, + 47520, + 48528, + 47056, + 47520, + 47344, + 47520, + 47792, + 46960, + 47520, + 46960, + 47520, + 47344, + 47904, + 47616, + 47392, + 47392, + 47520, + 47392, + 47520, + 47056, + 47392, + 47344, + 47520, + 47616, + 47056, + 47600, + 47520, + 47616, + 47520, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 283, + "errors": 0, + "avg_ms": 210.6301068762976, + "min_ms": 119.44056999982422, + "max_ms": 755.250647000139, + "rps": 4.2, + "p95_ms": 480.0, + "p99_ms": 510.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.0568, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "high_mem_cap_002", + "idle": 55872, + "usage": [ + 0, + 54144, + 53952, + 53952, + 53952, + 53952, + 53952, + 53952, + 53952, + 53952, + 53952, + 53952, + 53952, + 63104, + 57568, + 57616, + 57472, + 57712, + 57520, + 57616, + 57616, + 57136, + 57200, + 57136, + 57488, + 57360, + 56960, + 57344, + 57616, + 56832, + 57232, + 58000, + 57616, + 57232, + 57712, + 57488, + 56960, + 60336, + 57168, + 57056, + 57056, + 57616, + 57456, + 57360, + 57392, + 57440, + 57616, + 57520, + 57776, + 57616, + 56800, + 57488, + 57648, + 57520, + 57344, + 57728, + 57712, + 57488, + 58160, + 57600, + 57232, + 57904, + 57616, + 57440, + 57392, + 57728, + 57440, + 57184, + 57632, + 57088, + 57216, + 57984, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 560, + "errors": 0, + "avg_ms": 213.61373795537185, + "min_ms": 104.09169400008977, + "max_ms": 579.7837550007898, + "rps": 9.7, + "p95_ms": 420.0, + "p99_ms": 460.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.114, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "high_mem_cap_003", + "idle": 72640, + "usage": [ + 0, + 70912, + 70720, + 70720, + 70720, + 70720, + 70720, + 70720, + 70720, + 70720, + 70720, + 70720, + 70720, + 76928, + 77888, + 77504, + 77344, + 78384, + 77088, + 76816, + 77184, + 76896, + 77184, + 77216, + 77104, + 77184, + 78032, + 77984, + 77552, + 76064, + 76864, + 77392, + 77856, + 76672, + 77520, + 77296, + 80528, + 77920, + 77712, + 76528, + 77440, + 76096, + 77008, + 77696, + 77424, + 77216, + 77152, + 77792, + 76464, + 77408, + 78144, + 77072, + 76816, + 77456, + 76448, + 77232, + 77568, + 77424, + 77680, + 77792, + 77776, + 77296, + 77584, + 78064, + 77696, + 77344, + 80592, + 77440, + 76448, + 79504, + 77616, + 77968, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 616, + "errors": 0, + "avg_ms": 387.3104625941404, + "min_ms": 147.39018499949452, + "max_ms": 971.8016779997924, + "rps": 10.4, + "p95_ms": 820.0, + "p99_ms": 880.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.228, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "multipart_001", + "idle": 45040, + "usage": [ + 0, + 43088, + 42896, + 42896, + 42896, + 42896, + 42896, + 42896, + 42896, + 42896, + 42896, + 42896, + 42896, + 44912, + 44608, + 46400, + 46400, + 46192, + 46144, + 46144, + 46160, + 46112, + 46192, + 45104, + 46256, + 44896, + 45504, + 46192, + 45936, + 46368, + 45120, + 46192, + 45520, + 46160, + 46368, + 46400, + 46112, + 44976, + 46192, + 46512, + 45120, + 45120, + 45200, + 45120, + 45936, + 46400, + 46304, + 45104, + 46144, + 45504, + 46160, + 46368, + 45888, + 46192, + 46400, + 44896, + 45104, + 46256, + 46112, + 45520, + 46400, + 45104, + 46304, + 46400, + 46400, + 46144, + 44896, + 46400, + 46192, + 46400, + 46144, + 46112, + 46368, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 71, + "errors": 0, + "avg_ms": 838.0303002816904, + "min_ms": 770.5004279996501, + "max_ms": 1054.9864020003952, + "rps": 1.2, + "p95_ms": 890.0, + "p99_ms": 1100.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.0127, + "http_multipart": true, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "multipart_002", + "idle": 46256, + "usage": [ + 0, + 44304, + 44112, + 44112, + 44112, + 44112, + 44112, + 44112, + 44112, + 44112, + 44112, + 44112, + 44112, + 44480, + 50336, + 50176, + 48304, + 50080, + 48000, + 50416, + 47616, + 50208, + 50032, + 50064, + 50048, + 49488, + 47232, + 48000, + 50048, + 47776, + 50256, + 49232, + 49888, + 48000, + 49840, + 47840, + 47888, + 49664, + 48048, + 49680, + 49680, + 50416, + 48896, + 50256, + 50480, + 50512, + 48496, + 49232, + 50112, + 48496, + 50224, + 49232, + 50368, + 50272, + 50304, + 50320, + 50064, + 50144, + 50096, + 49200, + 50096, + 50256, + 48048, + 50112, + 48752, + 50160, + 49104, + 48960, + 50256, + 48912, + 48752, + 49328, + 47664, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 90, + "errors": 0, + "avg_ms": 1318.015343555544, + "min_ms": 968.9139729998715, + "max_ms": 1833.6361209999268, + "rps": 1.6, + "p95_ms": 1600.0, + "p99_ms": 1800.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.0253, + "http_multipart": true, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "multipart_003", + "idle": 48688, + "usage": [ + 0, + 46736, + 46544, + 46544, + 46544, + 46544, + 46544, + 46544, + 46544, + 46544, + 46544, + 46544, + 46544, + 48816, + 58304, + 57616, + 57360, + 57008, + 58000, + 57632, + 57888, + 56640, + 57600, + 57184, + 56976, + 56592, + 57712, + 55904, + 55312, + 56080, + 54640, + 55712, + 55856, + 55872, + 57312, + 56288, + 54992, + 55424, + 58096, + 55600, + 55392, + 56928, + 57120, + 58416, + 57792, + 58096, + 57504, + 57792, + 58512, + 57712, + 55808, + 57360, + 56032, + 56544, + 57776, + 58160, + 56192, + 58288, + 57536, + 56400, + 56944, + 58144, + 58576, + 57344, + 56448, + 55808, + 56672, + 57712, + 57296, + 57584, + 55984, + 56336, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 99, + "errors": 0, + "avg_ms": 2380.730864676755, + "min_ms": 1605.0147549999565, + "max_ms": 3318.4125239999958, + "rps": 1.8, + "p95_ms": 3100.0, + "p99_ms": 3300.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.0505, + "http_multipart": true, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "files_api_001", + "idle": 47872, + "usage": [ + 0, + 46144, + 45952, + 45952, + 45952, + 45952, + 45952, + 45952, + 45952, + 45952, + 45952, + 45952, + 45952, + 48016, + 48880, + 47728, + 48336, + 48832, + 47344, + 47936, + 48016, + 48304, + 47344, + 48016, + 47728, + 47440, + 47728, + 47760, + 48304, + 47728, + 48832, + 48880, + 48880, + 47440, + 47744, + 47792, + 47776, + 47744, + 48016, + 48832, + 47344, + 47344, + 48880, + 48016, + 48880, + 48672, + 48016, + 48880, + 48880, + 48336, + 48016, + 48032, + 48832, + 47728, + 47936, + 47760, + 47344, + 47760, + 47744, + 47728, + 47344, + 47344, + 48016, + 48848, + 48832, + 48304, + 48832, + 47344, + 47936, + 47936, + 48016, + 48336, + 48192, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 332, + "errors": 0, + "avg_ms": 180.42329718975924, + "min_ms": 122.59894900034851, + "max_ms": 819.9667389999377, + "rps": 5.7, + "p95_ms": 230.0, + "p99_ms": 300.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.0127, + "http_multipart": false, + "http_files_api": true, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "files_api_002", + "idle": 49088, + "usage": [ + 0, + 47360, + 47168, + 47168, + 47168, + 47168, + 47168, + 47168, + 47168, + 47168, + 47168, + 47168, + 47168, + 48320, + 50352, + 50752, + 51152, + 51536, + 51776, + 51568, + 50688, + 51792, + 50592, + 50720, + 51312, + 51280, + 50608, + 51568, + 50400, + 50976, + 51664, + 51328, + 52800, + 50960, + 51408, + 52800, + 51600, + 51840, + 50608, + 51488, + 52112, + 50416, + 51360, + 52656, + 51792, + 51248, + 50608, + 52112, + 51248, + 50688, + 50576, + 51840, + 51504, + 51792, + 50384, + 52064, + 52752, + 51776, + 51136, + 50992, + 50432, + 51408, + 50960, + 52256, + 50880, + 52768, + 50096, + 51200, + 52096, + 51776, + 50464, + 50128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 434, + "errors": 0, + "avg_ms": 275.56767837097334, + "min_ms": 157.43496300001425, + "max_ms": 414.42680999989534, + "rps": 7.1, + "p95_ms": 370.0, + "p99_ms": 390.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.0253, + "http_multipart": false, + "http_files_api": true, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "files_api_003", + "idle": 51520, + "usage": [ + 0, + 49792, + 49600, + 49600, + 49600, + 49600, + 49600, + 49600, + 49600, + 49600, + 49600, + 49600, + 49600, + 54016, + 58224, + 56704, + 55184, + 57376, + 57984, + 58656, + 59168, + 57344, + 57632, + 57056, + 57712, + 56784, + 56176, + 56832, + 58400, + 56000, + 56528, + 57632, + 57792, + 57728, + 55968, + 56752, + 58480, + 56736, + 57152, + 56800, + 56784, + 57248, + 57248, + 56640, + 56704, + 56544, + 56912, + 57760, + 58304, + 57536, + 57824, + 55824, + 58800, + 57328, + 56592, + 57904, + 56896, + 55952, + 57968, + 56192, + 57760, + 57376, + 56992, + 57840, + 57024, + 58864, + 57360, + 58176, + 56528, + 56912, + 56192, + 51840, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 463, + "errors": 0, + "avg_ms": 515.3311474989238, + "min_ms": 296.7984459996842, + "max_ms": 760.5838969998331, + "rps": 7.7, + "p95_ms": 680.0, + "p99_ms": 700.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.0505, + "http_multipart": false, + "http_files_api": true, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "tls_001", + "idle": 43040, + "usage": [ + 0, + 40672, + 40480, + 40480, + 40480, + 40480, + 40480, + 40480, + 40480, + 40480, + 40480, + 40480, + 40480, + 42912, + 42944, + 43168, + 42896, + 42912, + 43168, + 43456, + 43456, + 42944, + 43456, + 43456, + 43072, + 43072, + 42896, + 43344, + 43344, + 42608, + 43344, + 43456, + 42896, + 43456, + 43168, + 43168, + 43440, + 43456, + 43456, + 43168, + 42896, + 42848, + 42896, + 43072, + 43456, + 42944, + 42848, + 42912, + 43168, + 43072, + 43344, + 42608, + 43456, + 43456, + 43456, + 42944, + 43072, + 43344, + 42608, + 42912, + 43072, + 43168, + 43072, + 43200, + 43328, + 42944, + 43456, + 42896, + 43168, + 43168, + 43072, + 43344, + 42848, + 42944, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 187, + "errors": 0, + "avg_ms": 319.9572561818331, + "min_ms": 127.92590099979861, + "max_ms": 933.7864350000018, + "rps": 3.3, + "p95_ms": 680.0, + "p99_ms": 820.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.0127, + "http_multipart": false, + "http_files_api": false, + "tls": true, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "tls_002", + "idle": 44256, + "usage": [ + 0, + 41888, + 41696, + 41696, + 41696, + 41696, + 41696, + 41696, + 41696, + 41696, + 41696, + 41696, + 41696, + 44160, + 46208, + 46976, + 47264, + 46368, + 46752, + 46976, + 46688, + 46208, + 46880, + 47264, + 47264, + 46976, + 46416, + 47184, + 46976, + 47264, + 46976, + 46592, + 46368, + 46240, + 46592, + 46720, + 46368, + 46032, + 47280, + 46704, + 46336, + 46976, + 46096, + 46704, + 46976, + 46896, + 46592, + 46368, + 46976, + 46592, + 46880, + 47280, + 46144, + 46496, + 46720, + 46592, + 46496, + 47264, + 46880, + 46880, + 46496, + 46896, + 47664, + 46032, + 46192, + 46464, + 46688, + 46976, + 46496, + 46528, + 46416, + 46496, + 45664, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 347, + "errors": 0, + "avg_ms": 343.80903827378205, + "min_ms": 119.16914399989764, + "max_ms": 1698.6069100003078, + "rps": 6.1, + "p95_ms": 740.0, + "p99_ms": 800.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.0253, + "http_multipart": false, + "http_files_api": false, + "tls": true, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + } +] \ No newline at end of file diff --git a/docs/dimensioning/esp32_c3/multipart_001.png b/docs/dimensioning/esp32_c3/multipart_001.png new file mode 100644 index 0000000..b1425a7 Binary files /dev/null and b/docs/dimensioning/esp32_c3/multipart_001.png differ diff --git a/docs/dimensioning/esp32_c3/multipart_002.png b/docs/dimensioning/esp32_c3/multipart_002.png new file mode 100644 index 0000000..ce4608c Binary files /dev/null and b/docs/dimensioning/esp32_c3/multipart_002.png differ diff --git a/docs/dimensioning/esp32_c3/multipart_003.png b/docs/dimensioning/esp32_c3/multipart_003.png new file mode 100644 index 0000000..3ca2d32 Binary files /dev/null and b/docs/dimensioning/esp32_c3/multipart_003.png differ diff --git a/docs/dimensioning/esp32_c3/tls_001.png b/docs/dimensioning/esp32_c3/tls_001.png new file mode 100644 index 0000000..cb599b9 Binary files /dev/null and b/docs/dimensioning/esp32_c3/tls_001.png differ diff --git a/docs/dimensioning/esp32_c3/tls_002.png b/docs/dimensioning/esp32_c3/tls_002.png new file mode 100644 index 0000000..aa309b1 Binary files /dev/null and b/docs/dimensioning/esp32_c3/tls_002.png differ diff --git a/docs/dimensioning/esp32_s3/base.png b/docs/dimensioning/esp32_s3/base.png new file mode 100644 index 0000000..d8263c7 Binary files /dev/null and b/docs/dimensioning/esp32_s3/base.png differ diff --git a/docs/dimensioning/esp32_s3/files_api_001.png b/docs/dimensioning/esp32_s3/files_api_001.png new file mode 100644 index 0000000..4baab92 Binary files /dev/null and b/docs/dimensioning/esp32_s3/files_api_001.png differ diff --git a/docs/dimensioning/esp32_s3/files_api_002.png b/docs/dimensioning/esp32_s3/files_api_002.png new file mode 100644 index 0000000..6d648a6 Binary files /dev/null and b/docs/dimensioning/esp32_s3/files_api_002.png differ diff --git a/docs/dimensioning/esp32_s3/files_api_003.png b/docs/dimensioning/esp32_s3/files_api_003.png new file mode 100644 index 0000000..c0ef387 Binary files /dev/null and b/docs/dimensioning/esp32_s3/files_api_003.png differ diff --git a/docs/dimensioning/esp32_s3/high_mem_cap_001.png b/docs/dimensioning/esp32_s3/high_mem_cap_001.png new file mode 100644 index 0000000..998cadc Binary files /dev/null and b/docs/dimensioning/esp32_s3/high_mem_cap_001.png differ diff --git a/docs/dimensioning/esp32_s3/high_mem_cap_002.png b/docs/dimensioning/esp32_s3/high_mem_cap_002.png new file mode 100644 index 0000000..91d0e33 Binary files /dev/null and b/docs/dimensioning/esp32_s3/high_mem_cap_002.png differ diff --git a/docs/dimensioning/esp32_s3/high_mem_cap_003.png b/docs/dimensioning/esp32_s3/high_mem_cap_003.png new file mode 100644 index 0000000..5c39e65 Binary files /dev/null and b/docs/dimensioning/esp32_s3/high_mem_cap_003.png differ diff --git a/docs/dimensioning/esp32_s3/low_mem_cap_001.png b/docs/dimensioning/esp32_s3/low_mem_cap_001.png new file mode 100644 index 0000000..95351f5 Binary files /dev/null and b/docs/dimensioning/esp32_s3/low_mem_cap_001.png differ diff --git a/docs/dimensioning/esp32_s3/low_mem_cap_002.png b/docs/dimensioning/esp32_s3/low_mem_cap_002.png new file mode 100644 index 0000000..9d7a780 Binary files /dev/null and b/docs/dimensioning/esp32_s3/low_mem_cap_002.png differ diff --git a/docs/dimensioning/esp32_s3/low_mem_cap_003.png b/docs/dimensioning/esp32_s3/low_mem_cap_003.png new file mode 100644 index 0000000..1d6f8eb Binary files /dev/null and b/docs/dimensioning/esp32_s3/low_mem_cap_003.png differ diff --git a/docs/dimensioning/esp32_s3/measurements.json b/docs/dimensioning/esp32_s3/measurements.json new file mode 100644 index 0000000..ea2508e --- /dev/null +++ b/docs/dimensioning/esp32_s3/measurements.json @@ -0,0 +1,2034 @@ +[ + { + "id": "base", + "idle": 47456, + "usage": [ + 0, + 45728, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 45904, + 47584, + 47760, + 47312, + 47568, + 47312, + 47328, + 47488, + 47328, + 47584, + 47584, + 47360, + 47488, + 47616, + 47584, + 47312, + 47888, + 47488, + 47312, + 47328, + 47488, + 47760, + 47584, + 46928, + 47488, + 47312, + 47488, + 47584, + 47024, + 47392, + 47584, + 47584, + 47360, + 47584, + 47024, + 47488, + 47488, + 47312, + 47584, + 46928, + 47488, + 47488, + 47488, + 47328, + 47584, + 47360, + 47584, + 47488, + 47312, + 47888, + 47584, + 47488, + 46928, + 47488, + 47488, + 47584, + 47312, + 47776, + 47584, + 47488, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 217, + "errors": 0, + "avg_ms": 275.09792664042106, + "min_ms": 177.9682890010008, + "max_ms": 726.1661369993817, + "rps": 3.8, + "p95_ms": 480.0, + "p99_ms": 500.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.05, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "low_mem_cap_001", + "idle": 40288, + "usage": [ + 0, + 38560, + 38368, + 38368, + 38368, + 38368, + 38368, + 38368, + 38368, + 38368, + 38368, + 40144, + 40608, + 40720, + 40720, + 40144, + 39856, + 40320, + 40608, + 40320, + 40144, + 40144, + 40416, + 40704, + 40096, + 40416, + 40192, + 40416, + 40400, + 40192, + 40416, + 40704, + 40416, + 39856, + 40320, + 40192, + 40416, + 40704, + 40720, + 40320, + 39760, + 40720, + 40608, + 40704, + 40144, + 39760, + 40192, + 40416, + 40144, + 40608, + 40720, + 40720, + 40704, + 40320, + 40416, + 40144, + 40416, + 40416, + 40320, + 39760, + 40320, + 40704, + 40096, + 40144, + 40416, + 40704, + 40192, + 40608, + 40400, + 40400, + 40416, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 153, + "errors": 0, + "avg_ms": 391.5697839805159, + "min_ms": 184.72109199865372, + "max_ms": 728.2016149983974, + "rps": 2.7, + "p95_ms": 660.0, + "p99_ms": 690.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.000247, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "low_mem_cap_002", + "idle": 41504, + "usage": [ + 0, + 39776, + 39584, + 39584, + 39584, + 39584, + 39584, + 39584, + 39584, + 39584, + 39584, + 39952, + 43984, + 43600, + 43248, + 43648, + 43376, + 43248, + 43584, + 43648, + 43248, + 43552, + 42976, + 43344, + 42912, + 43552, + 43408, + 43536, + 43248, + 42464, + 43376, + 42992, + 44432, + 43648, + 43840, + 43648, + 44000, + 43664, + 43152, + 43552, + 43088, + 43024, + 43936, + 43264, + 43632, + 44096, + 43584, + 43632, + 42800, + 42896, + 42976, + 43648, + 43072, + 43248, + 43088, + 43648, + 43824, + 43648, + 43664, + 43936, + 43936, + 43248, + 43024, + 42864, + 43648, + 43088, + 43376, + 43392, + 43328, + 44032, + 42000, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 299, + "errors": 0, + "avg_ms": 399.2018889665781, + "min_ms": 157.27941099976306, + "max_ms": 973.5448530009307, + "rps": 5.1, + "p95_ms": 820.0, + "p99_ms": 900.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.000493, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "low_mem_cap_003", + "idle": 43936, + "usage": [ + 0, + 42208, + 42016, + 42016, + 42016, + 42016, + 42016, + 42016, + 42016, + 42016, + 42016, + 42528, + 49120, + 49360, + 50080, + 48768, + 48656, + 48288, + 49200, + 49968, + 49072, + 49840, + 49968, + 49792, + 49856, + 48352, + 48544, + 48928, + 49568, + 48576, + 50080, + 49680, + 50352, + 49840, + 48672, + 49184, + 49504, + 49568, + 48448, + 49344, + 49760, + 49776, + 49920, + 49792, + 49392, + 48480, + 49536, + 48896, + 48832, + 49216, + 48880, + 49760, + 49840, + 50336, + 50080, + 48752, + 49424, + 49792, + 50048, + 48944, + 49872, + 48944, + 49120, + 48880, + 50480, + 49664, + 50656, + 49680, + 49664, + 49536, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 382, + "errors": 0, + "avg_ms": 624.3807886517751, + "min_ms": 191.1531309997372, + "max_ms": 1713.8781639987428, + "rps": 6.4, + "p95_ms": 1400.0, + "p99_ms": 1500.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.000985, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "high_mem_cap_001", + "idle": 47456, + "usage": [ + 0, + 45728, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 45536, + 47024, + 47584, + 47488, + 47584, + 47312, + 47488, + 47024, + 47584, + 46928, + 47584, + 47584, + 47312, + 47584, + 47584, + 47360, + 47584, + 47584, + 47312, + 47312, + 47584, + 47328, + 47488, + 47600, + 47024, + 47488, + 47312, + 47584, + 47328, + 47776, + 47584, + 47024, + 47488, + 47360, + 47024, + 47776, + 47488, + 47360, + 46928, + 47488, + 47488, + 47776, + 47360, + 47488, + 47488, + 47024, + 47488, + 46928, + 47584, + 47328, + 47584, + 47312, + 47488, + 47488, + 47568, + 47024, + 47792, + 47328, + 47776, + 47312, + 46320, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 221, + "errors": 0, + "avg_ms": 269.7235890633377, + "min_ms": 189.81274199904874, + "max_ms": 798.6247689987067, + "rps": 3.7, + "p95_ms": 470.0, + "p99_ms": 490.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.00111, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "high_mem_cap_002", + "idle": 55840, + "usage": [ + 0, + 54112, + 53920, + 53920, + 53920, + 53920, + 53920, + 53920, + 53920, + 53920, + 53920, + 55408, + 56880, + 56976, + 57920, + 57584, + 57712, + 57984, + 56928, + 57424, + 57168, + 57488, + 57424, + 58272, + 57360, + 57232, + 57712, + 57984, + 57200, + 57680, + 57680, + 57344, + 57984, + 57584, + 57584, + 57424, + 57360, + 57360, + 57584, + 57456, + 57680, + 58000, + 57424, + 56928, + 57408, + 57584, + 59232, + 58464, + 57136, + 57328, + 57488, + 60336, + 57904, + 57312, + 57424, + 57584, + 57328, + 57328, + 57024, + 57232, + 57024, + 57408, + 57584, + 57424, + 57872, + 56768, + 57424, + 57360, + 57312, + 57984, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 405, + "errors": 0, + "avg_ms": 294.6867814246942, + "min_ms": 153.9950160004082, + "max_ms": 661.1706010007765, + "rps": 6.9, + "p95_ms": 560.0, + "p99_ms": 610.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.00222, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "high_mem_cap_003", + "idle": 72608, + "usage": [ + 0, + 70880, + 70688, + 70688, + 70688, + 70688, + 70688, + 70688, + 70688, + 70688, + 70688, + 72528, + 76432, + 77120, + 77296, + 77472, + 78240, + 79936, + 77504, + 77056, + 77440, + 77744, + 76960, + 77360, + 80368, + 76208, + 77488, + 77712, + 76928, + 78016, + 76672, + 77840, + 77312, + 77264, + 78288, + 76752, + 77152, + 77312, + 77984, + 78336, + 77392, + 77872, + 76992, + 77888, + 76896, + 77648, + 78096, + 77248, + 77424, + 77232, + 78048, + 77056, + 77584, + 76976, + 77184, + 77584, + 77328, + 77328, + 78096, + 77296, + 77424, + 76848, + 77840, + 77584, + 77408, + 77232, + 77184, + 77888, + 77696, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 497, + "errors": 0, + "avg_ms": 480.02186370017284, + "min_ms": 180.53324699940276, + "max_ms": 1276.8714900012128, + "rps": 8.5, + "p95_ms": 1000.0, + "p99_ms": 1200.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.00443, + "http_multipart": false, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "multipart_001", + "idle": 44960, + "usage": [ + 0, + 43056, + 42864, + 42864, + 42864, + 42864, + 42864, + 42864, + 42864, + 42864, + 42864, + 45808, + 45040, + 46112, + 44880, + 46240, + 46320, + 45312, + 46320, + 45904, + 45024, + 46448, + 45856, + 46448, + 45040, + 46112, + 46064, + 46112, + 44496, + 46320, + 45040, + 45040, + 46032, + 46112, + 46320, + 46112, + 45968, + 45024, + 46240, + 45424, + 45024, + 46192, + 45888, + 46144, + 45424, + 45040, + 45040, + 45088, + 46112, + 46288, + 44880, + 46320, + 46112, + 44816, + 44880, + 45040, + 46080, + 45440, + 44816, + 44816, + 45040, + 46448, + 45424, + 44592, + 44816, + 45424, + 46112, + 46112, + 46288, + 46032, + 46064, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 77, + "errors": 0, + "avg_ms": 774.4412679612061, + "min_ms": 702.702506998321, + "max_ms": 930.4371309990529, + "rps": 1.2, + "p95_ms": 880.0, + "p99_ms": 930.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.000247, + "http_multipart": true, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "multipart_002", + "idle": 46176, + "usage": [ + 0, + 44272, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 47488, + 48080, + 49312, + 48880, + 49920, + 48256, + 50448, + 50080, + 50144, + 49216, + 50080, + 49328, + 50240, + 48912, + 49040, + 49824, + 49520, + 47792, + 48992, + 47856, + 49264, + 50208, + 48880, + 49008, + 48912, + 49808, + 50272, + 49008, + 49056, + 50416, + 50400, + 50320, + 50080, + 49936, + 49808, + 50192, + 48368, + 50320, + 48352, + 47520, + 50416, + 50192, + 49824, + 49168, + 49408, + 50192, + 49760, + 50080, + 49008, + 49280, + 49104, + 49008, + 50288, + 49376, + 49184, + 49248, + 49792, + 50656, + 48736, + 47344, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 122, + "errors": 0, + "avg_ms": 975.6486063114771, + "min_ms": 700.6420840007195, + "max_ms": 1376.7830739998317, + "rps": 2.1, + "p95_ms": 1200.0, + "p99_ms": 1300.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.000493, + "http_multipart": true, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "multipart_003", + "idle": 48608, + "usage": [ + 0, + 46704, + 46512, + 46512, + 46512, + 46512, + 46512, + 46512, + 46512, + 46512, + 46512, + 57760, + 57328, + 57344, + 54720, + 55680, + 55552, + 56016, + 57552, + 56912, + 56608, + 55648, + 55504, + 55776, + 57376, + 57984, + 55600, + 55648, + 56656, + 56576, + 57312, + 54656, + 54128, + 57584, + 58640, + 55856, + 57760, + 57168, + 57376, + 58048, + 57456, + 57968, + 55888, + 55792, + 54832, + 55552, + 57504, + 58032, + 56928, + 58192, + 56624, + 54848, + 56672, + 55184, + 55936, + 57040, + 57312, + 55712, + 58048, + 56048, + 56464, + 58512, + 58464, + 58416, + 56256, + 55840, + 56912, + 57248, + 58176, + 58096, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 137, + "errors": 0, + "avg_ms": 1725.360749226353, + "min_ms": 1196.5070849983022, + "max_ms": 2505.5717830000503, + "rps": 2.3, + "p95_ms": 2200.0, + "p99_ms": 2400.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.000985, + "http_multipart": true, + "http_files_api": false, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "files_api_001", + "idle": 47840, + "usage": [ + 0, + 46064, + 46080, + 46080, + 46080, + 46080, + 46080, + 46080, + 46080, + 46080, + 48736, + 48688, + 47984, + 48592, + 48240, + 47696, + 47696, + 47728, + 47984, + 48752, + 48752, + 48688, + 48736, + 48736, + 48704, + 48000, + 48624, + 48688, + 48704, + 48656, + 48688, + 48688, + 48688, + 48688, + 48688, + 48688, + 48688, + 48896, + 48688, + 48736, + 48736, + 47696, + 47984, + 48752, + 48752, + 48688, + 48704, + 48688, + 48688, + 48688, + 48688, + 48288, + 48688, + 48736, + 47712, + 48688, + 48656, + 48624, + 48624, + 48624, + 48688, + 48688, + 48688, + 48688, + 48688, + 48688, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 81, + "errors": 0, + "avg_ms": 728.8924180865712, + "min_ms": 254.9681460004649, + "max_ms": 1103.9164310022898, + "rps": 1.3, + "p95_ms": 1000.0, + "p99_ms": 1100.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.000247, + "http_multipart": false, + "http_files_api": true, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "files_api_002", + "idle": 49056, + "usage": [ + 0, + 47280, + 47296, + 47296, + 47296, + 47296, + 47296, + 47296, + 47296, + 47296, + 50624, + 51856, + 51808, + 51024, + 52336, + 52304, + 52336, + 51936, + 51312, + 52336, + 52336, + 51008, + 51056, + 51008, + 51632, + 52176, + 51792, + 51568, + 51824, + 51056, + 51008, + 50560, + 51552, + 51312, + 51904, + 50928, + 52336, + 51552, + 51632, + 50928, + 51872, + 51360, + 51360, + 51312, + 51184, + 51136, + 50992, + 51504, + 51904, + 50928, + 52560, + 52208, + 50992, + 52288, + 51360, + 51360, + 51568, + 52016, + 52208, + 51296, + 51408, + 51408, + 50640, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 103, + "errors": 0, + "avg_ms": 1151.4038323789684, + "min_ms": 257.31607399939094, + "max_ms": 1987.013787998876, + "rps": 1.7, + "p95_ms": 1900.0, + "p99_ms": 1900.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.000493, + "http_multipart": false, + "http_files_api": true, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "files_api_003", + "idle": 51488, + "usage": [ + 0, + 49712, + 49728, + 49728, + 49728, + 49728, + 49728, + 49728, + 49728, + 49728, + 56352, + 57728, + 56912, + 57904, + 56624, + 58016, + 57792, + 56736, + 58560, + 56560, + 59680, + 58688, + 56048, + 56400, + 56240, + 56464, + 55472, + 57936, + 57328, + 58000, + 56112, + 57104, + 56256, + 58912, + 57152, + 56704, + 56720, + 58176, + 58624, + 56864, + 56944, + 56224, + 58096, + 58064, + 56064, + 56848, + 58176, + 58608, + 56096, + 58704, + 56016, + 59040, + 58752, + 56048, + 56384, + 57568, + 57760, + 59152, + 58192, + 56448, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 109, + "errors": 0, + "avg_ms": 2149.179494807242, + "min_ms": 670.4549899986887, + "max_ms": 3807.874025998899, + "rps": 1.9, + "p95_ms": 3600.0, + "p99_ms": 3800.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.000985, + "http_multipart": false, + "http_files_api": true, + "tls": false, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "tls_001", + "idle": 42624, + "usage": [ + 0, + 40624, + 40432, + 40432, + 40432, + 40432, + 40432, + 40432, + 40432, + 40432, + 40432, + 42528, + 42432, + 42480, + 42096, + 42528, + 42528, + 43056, + 42192, + 42672, + 43040, + 42752, + 42752, + 42752, + 42528, + 43040, + 43040, + 42752, + 42528, + 42656, + 42496, + 42752, + 42752, + 42656, + 42752, + 42480, + 42192, + 42752, + 42496, + 42528, + 43056, + 42656, + 43056, + 43056, + 42752, + 42752, + 42656, + 42192, + 43056, + 43056, + 42480, + 42496, + 42432, + 42752, + 42752, + 43056, + 42480, + 42656, + 43056, + 42752, + 42656, + 42496, + 42928, + 42656, + 42752, + 42096, + 42656, + 42752, + 42528, + 43056, + 42656, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 144, + "errors": 0, + "avg_ms": 413.5269441458149, + "min_ms": 201.92779400167638, + "max_ms": 1264.3235409996123, + "rps": 2.5, + "p95_ms": 670.0, + "p99_ms": 840.0 + }, + "config": { + "socket_max_con": 1, + "http_mem_cap": 0.000247, + "http_multipart": false, + "http_files_api": false, + "tls": true, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "tls_002", + "idle": 43840, + "usage": [ + 0, + 41840, + 41648, + 41648, + 41648, + 41648, + 41648, + 41648, + 41648, + 41648, + 41648, + 43744, + 45472, + 45600, + 46544, + 46160, + 46640, + 45392, + 46560, + 46240, + 45280, + 45952, + 45856, + 45952, + 45856, + 46160, + 46032, + 46320, + 45360, + 45120, + 45456, + 45888, + 46544, + 46416, + 46144, + 45856, + 45360, + 45856, + 46256, + 46256, + 46144, + 46608, + 46256, + 46256, + 45984, + 45856, + 46560, + 46368, + 46544, + 45984, + 45888, + 46144, + 45728, + 46144, + 45856, + 45696, + 45952, + 45856, + 46192, + 45856, + 46256, + 45200, + 46256, + 45408, + 46544, + 46544, + 46256, + 45984, + 45856, + 46000, + 44288, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 269, + "errors": 0, + "avg_ms": 444.8922698736666, + "min_ms": 176.24865000107093, + "max_ms": 1274.587370997324, + "rps": 4.7, + "p95_ms": 890.0, + "p99_ms": 1100.0 + }, + "config": { + "socket_max_con": 2, + "http_mem_cap": 0.000493, + "http_multipart": false, + "http_files_api": false, + "tls": true, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + }, + { + "id": "tls_003", + "idle": 46272, + "usage": [ + 0, + 44272, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 44080, + 46176, + 51232, + 52400, + 53072, + 52848, + 52288, + 52192, + 52768, + 52752, + 51904, + 52384, + 53344, + 52336, + 52352, + 51824, + 52912, + 52528, + 52256, + 53216, + 52448, + 52384, + 52320, + 51680, + 52560, + 51680, + 53264, + 52912, + 52800, + 52720, + 52672, + 52208, + 52128, + 52608, + 52416, + 51232, + 53216, + 52912, + 51232, + 52608, + 51520, + 52304, + 52320, + 52672, + 52960, + 53520, + 51648, + 53632, + 53120, + 51440, + 52512, + 52272, + 51904, + 52432, + 52736, + 52384, + 52224, + 52304, + 52592, + 51024, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stats": { + "ok": 331, + "errors": 0, + "avg_ms": 719.9920886313579, + "min_ms": 219.18677799840225, + "max_ms": 2874.1862599999877, + "rps": 5.9, + "p95_ms": 1700.0, + "p99_ms": 2300.0 + }, + "config": { + "socket_max_con": 4, + "http_mem_cap": 0.000985, + "http_multipart": false, + "http_files_api": false, + "tls": true, + "http_port": 8080, + "https_port": 4443, + "log_level": "info", + "http_served_paths": "/lib/pyrobusta /www" + } + } +] \ No newline at end of file diff --git a/docs/dimensioning/esp32_s3/multipart_001.png b/docs/dimensioning/esp32_s3/multipart_001.png new file mode 100644 index 0000000..e3cf11c Binary files /dev/null and b/docs/dimensioning/esp32_s3/multipart_001.png differ diff --git a/docs/dimensioning/esp32_s3/multipart_002.png b/docs/dimensioning/esp32_s3/multipart_002.png new file mode 100644 index 0000000..2a9d575 Binary files /dev/null and b/docs/dimensioning/esp32_s3/multipart_002.png differ diff --git a/docs/dimensioning/esp32_s3/multipart_003.png b/docs/dimensioning/esp32_s3/multipart_003.png new file mode 100644 index 0000000..7f3ecd0 Binary files /dev/null and b/docs/dimensioning/esp32_s3/multipart_003.png differ diff --git a/docs/dimensioning/esp32_s3/tls_001.png b/docs/dimensioning/esp32_s3/tls_001.png new file mode 100644 index 0000000..ccc32cb Binary files /dev/null and b/docs/dimensioning/esp32_s3/tls_001.png differ diff --git a/docs/dimensioning/esp32_s3/tls_002.png b/docs/dimensioning/esp32_s3/tls_002.png new file mode 100644 index 0000000..befa6d0 Binary files /dev/null and b/docs/dimensioning/esp32_s3/tls_002.png differ diff --git a/docs/dimensioning/esp32_s3/tls_003.png b/docs/dimensioning/esp32_s3/tls_003.png new file mode 100644 index 0000000..35fb1f7 Binary files /dev/null and b/docs/dimensioning/esp32_s3/tls_003.png differ diff --git a/docs/dimensioning/http_dimensioning.md b/docs/dimensioning/http_dimensioning.md index fe28566..d086dbf 100644 --- a/docs/dimensioning/http_dimensioning.md +++ b/docs/dimensioning/http_dimensioning.md @@ -28,22 +28,24 @@ with no active network traffic. | id | http_mem_cap | http_multipart | socket_max_con | tls | footprint_bytes | | --- | --- | --- | --- | --- | --- | -| base | 0.05 | False | 1 | False | 39200 | -| low_mem_cap_001 | 0.0127 | False | 1 | False | 39200 | -| low_mem_cap_002 | 0.0253 | False | 2 | False | 40416 | -| low_mem_cap_003 | 0.0505 | False | 4 | False | 42848 | -| high_mem_cap_001 | 0.0568 | False | 1 | False | 46368 | -| high_mem_cap_002 | 0.114 | False | 2 | False | 54752 | -| high_mem_cap_003 | 0.228 | False | 4 | False | 71520 | -| multipart_001 | 0.0127 | True | 1 | False | 43616 | -| multipart_002 | 0.0253 | True | 2 | False | 44832 | -| multipart_003 | 0.0505 | True | 4 | False | 47264 | -| tls_001 | 0.0127 | False | 1 | True | 41872 | -| tls_002 | 0.0253 | False | 2 | True | 43088 | -| tls_003 | 0.0505 | False | 4 | True | 45520 | +| base | 0.05 | False | 1 | False | 40320 | +| low_mem_cap_001 | 0.0127 | False | 1 | False | 40320 | +| low_mem_cap_002 | 0.0253 | False | 2 | False | 41536 | +| low_mem_cap_003 | 0.0505 | False | 4 | False | 43968 | +| high_mem_cap_001 | 0.0568 | False | 1 | False | 47488 | +| high_mem_cap_002 | 0.114 | False | 2 | False | 55872 | +| high_mem_cap_003 | 0.228 | False | 4 | False | 72640 | +| multipart_001 | 0.0127 | True | 1 | False | 45040 | +| multipart_002 | 0.0253 | True | 2 | False | 46256 | +| multipart_003 | 0.0505 | True | 4 | False | 48688 | +| files_api_001 | 0.0127 | False | 1 | False | 47872 | +| files_api_002 | 0.0253 | False | 2 | False | 49088 | +| files_api_003 | 0.0505 | False | 4 | False | 51520 | +| tls_001 | 0.0127 | False | 1 | True | 43040 | +| tls_002 | 0.0253 | False | 2 | True | 44256 | ## Heap usage under network traffic -![image info](./img/esp32_c3/base.png) +![image info](./esp32_c3/base.png) # ESP32-S3 (8MB PSRAM) @@ -53,19 +55,22 @@ with no active network traffic. ## Idle heap usage | id | http_mem_cap | http_multipart | socket_max_con | tls | footprint_bytes | | --- | --- | --- | --- | --- | --- | -| base | 0.05 | False | 1 | False | 45856 | -| low_mem_cap_001 | 0.000247 | False | 1 | False | 38688 | -| low_mem_cap_002 | 0.000493 | False | 2 | False | 39904 | -| low_mem_cap_003 | 0.000985 | False | 4 | False | 42336 | -| high_mem_cap_001 | 0.00111 | False | 1 | False | 45856 | -| high_mem_cap_002 | 0.00222 | False | 2 | False | 54240 | -| high_mem_cap_003 | 0.00443 | False | 4 | False | 71008 | -| multipart_001 | 0.000247 | True | 1 | False | 40896 | -| multipart_002 | 0.000493 | True | 2 | False | 42112 | -| multipart_003 | 0.000985 | True | 4 | False | 44544 | -| tls_001 | 0.000247 | False | 1 | True | 41072 | -| tls_002 | 0.000493 | False | 2 | True | 42288 | -| tls_003 | 0.000985 | False | 4 | True | 44720 | +| base | 0.05 | False | 1 | False | 47456 | +| low_mem_cap_001 | 0.000247 | False | 1 | False | 40288 | +| low_mem_cap_002 | 0.000493 | False | 2 | False | 41504 | +| low_mem_cap_003 | 0.000985 | False | 4 | False | 43936 | +| high_mem_cap_001 | 0.00111 | False | 1 | False | 47456 | +| high_mem_cap_002 | 0.00222 | False | 2 | False | 55840 | +| high_mem_cap_003 | 0.00443 | False | 4 | False | 72608 | +| multipart_001 | 0.000247 | True | 1 | False | 44848 | +| multipart_002 | 0.000493 | True | 2 | False | 46064 | +| multipart_003 | 0.000985 | True | 4 | False | 48496 | +| files_api_001 | 0.000247 | False | 1 | False | 47840 | +| files_api_002 | 0.000493 | False | 2 | False | 49056 | +| files_api_003 | 0.000985 | False | 4 | False | 51488 | +| tls_001 | 0.000247 | False | 1 | True | 42624 | +| tls_002 | 0.000493 | False | 2 | True | 43840 | +| tls_003 | 0.000985 | False | 4 | True | 46272 | ## Heap usage under network traffic -![image info](./img/esp32_s3/base.png) \ No newline at end of file +![image info](./esp32_s3/base.png) \ No newline at end of file diff --git a/docs/dimensioning/img/esp32_c3/base.png b/docs/dimensioning/img/esp32_c3/base.png deleted file mode 100644 index f00159d..0000000 Binary files a/docs/dimensioning/img/esp32_c3/base.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/high_mem_cap_001.png b/docs/dimensioning/img/esp32_c3/high_mem_cap_001.png deleted file mode 100644 index 93d7c59..0000000 Binary files a/docs/dimensioning/img/esp32_c3/high_mem_cap_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/high_mem_cap_002.png b/docs/dimensioning/img/esp32_c3/high_mem_cap_002.png deleted file mode 100644 index b313f74..0000000 Binary files a/docs/dimensioning/img/esp32_c3/high_mem_cap_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/high_mem_cap_003.png b/docs/dimensioning/img/esp32_c3/high_mem_cap_003.png deleted file mode 100644 index a673534..0000000 Binary files a/docs/dimensioning/img/esp32_c3/high_mem_cap_003.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/low_mem_cap_001.png b/docs/dimensioning/img/esp32_c3/low_mem_cap_001.png deleted file mode 100644 index e400ed1..0000000 Binary files a/docs/dimensioning/img/esp32_c3/low_mem_cap_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/low_mem_cap_002.png b/docs/dimensioning/img/esp32_c3/low_mem_cap_002.png deleted file mode 100644 index 00757bc..0000000 Binary files a/docs/dimensioning/img/esp32_c3/low_mem_cap_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/low_mem_cap_003.png b/docs/dimensioning/img/esp32_c3/low_mem_cap_003.png deleted file mode 100644 index 3190cd9..0000000 Binary files a/docs/dimensioning/img/esp32_c3/low_mem_cap_003.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/multipart_001.png b/docs/dimensioning/img/esp32_c3/multipart_001.png deleted file mode 100644 index 8ec57c2..0000000 Binary files a/docs/dimensioning/img/esp32_c3/multipart_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/multipart_002.png b/docs/dimensioning/img/esp32_c3/multipart_002.png deleted file mode 100644 index d878756..0000000 Binary files a/docs/dimensioning/img/esp32_c3/multipart_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/multipart_003.png b/docs/dimensioning/img/esp32_c3/multipart_003.png deleted file mode 100644 index 511065e..0000000 Binary files a/docs/dimensioning/img/esp32_c3/multipart_003.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/tls_001.png b/docs/dimensioning/img/esp32_c3/tls_001.png deleted file mode 100644 index fdab204..0000000 Binary files a/docs/dimensioning/img/esp32_c3/tls_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_c3/tls_002.png b/docs/dimensioning/img/esp32_c3/tls_002.png deleted file mode 100644 index bbef1c0..0000000 Binary files a/docs/dimensioning/img/esp32_c3/tls_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/base.png b/docs/dimensioning/img/esp32_s3/base.png deleted file mode 100644 index b65470b..0000000 Binary files a/docs/dimensioning/img/esp32_s3/base.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/high_mem_cap_001.png b/docs/dimensioning/img/esp32_s3/high_mem_cap_001.png deleted file mode 100644 index a2affb9..0000000 Binary files a/docs/dimensioning/img/esp32_s3/high_mem_cap_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/high_mem_cap_002.png b/docs/dimensioning/img/esp32_s3/high_mem_cap_002.png deleted file mode 100644 index 648340c..0000000 Binary files a/docs/dimensioning/img/esp32_s3/high_mem_cap_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/high_mem_cap_003.png b/docs/dimensioning/img/esp32_s3/high_mem_cap_003.png deleted file mode 100644 index 1a8062d..0000000 Binary files a/docs/dimensioning/img/esp32_s3/high_mem_cap_003.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/low_mem_cap_001.png b/docs/dimensioning/img/esp32_s3/low_mem_cap_001.png deleted file mode 100644 index 78f731d..0000000 Binary files a/docs/dimensioning/img/esp32_s3/low_mem_cap_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/low_mem_cap_002.png b/docs/dimensioning/img/esp32_s3/low_mem_cap_002.png deleted file mode 100644 index dcdf0da..0000000 Binary files a/docs/dimensioning/img/esp32_s3/low_mem_cap_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/low_mem_cap_003.png b/docs/dimensioning/img/esp32_s3/low_mem_cap_003.png deleted file mode 100644 index 25c9993..0000000 Binary files a/docs/dimensioning/img/esp32_s3/low_mem_cap_003.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/multipart_001.png b/docs/dimensioning/img/esp32_s3/multipart_001.png deleted file mode 100644 index a4d1f16..0000000 Binary files a/docs/dimensioning/img/esp32_s3/multipart_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/multipart_002.png b/docs/dimensioning/img/esp32_s3/multipart_002.png deleted file mode 100644 index b628b9b..0000000 Binary files a/docs/dimensioning/img/esp32_s3/multipart_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/multipart_003.png b/docs/dimensioning/img/esp32_s3/multipart_003.png deleted file mode 100644 index 22665f7..0000000 Binary files a/docs/dimensioning/img/esp32_s3/multipart_003.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/tls_001.png b/docs/dimensioning/img/esp32_s3/tls_001.png deleted file mode 100644 index 55c8c6a..0000000 Binary files a/docs/dimensioning/img/esp32_s3/tls_001.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/tls_002.png b/docs/dimensioning/img/esp32_s3/tls_002.png deleted file mode 100644 index e05ead0..0000000 Binary files a/docs/dimensioning/img/esp32_s3/tls_002.png and /dev/null differ diff --git a/docs/dimensioning/img/esp32_s3/tls_003.png b/docs/dimensioning/img/esp32_s3/tls_003.png deleted file mode 100644 index 3e07f21..0000000 Binary files a/docs/dimensioning/img/esp32_s3/tls_003.png and /dev/null differ diff --git a/requirements.txt b/requirements.txt index 33b498a..361a557 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,9 @@ mpremote==1.27.0 +locust==2.27.0 +gevent==24.2.1 +greenlet==3.0.3 +requests==2.32.3 +urllib3==2.2.2 pylint black requests diff --git a/tests/system/http_dimensioning/boot.py b/tests/system/http_dimensioning/boot.py index 72dd783..a708124 100644 --- a/tests/system/http_dimensioning/boot.py +++ b/tests/system/http_dimensioning/boot.py @@ -7,6 +7,8 @@ from pyrobusta.protocol.http import HttpEngine from pyrobusta.connectivity import wifi +from pyrobusta.utils.config import get_config, CONF_HTTP_MULTIPART + TS_DURATION = 100 MEM_TIME_SERIES = [0] * TS_DURATION @@ -22,11 +24,24 @@ def time_series(*_): return "application/json", MEM_TIME_SERIES +@HttpEngine.route("/test/stream", "POST") +def chunked_callback(http_ctx, chunk_or_part): + if ( + http_ctx.headers.get("content-type", "").startswith("multipart/form-data") + and http_ctx.mp_is_last + ): + return "text/plain", "OK" + elif not chunk_or_part: # Received terminating chunk/part + return "text/plain", "OK" + pass # process chunk/part data as needed + + async def mem_usage(): i = 0 collect() while True: i = (i + 1) % TS_DURATION + collect() MEM_TIME_SERIES[i] = mem_alloc() await asyncio.sleep(1) @@ -35,6 +50,27 @@ async def main(): server = http_server.HttpServer() connected = wifi.initialize() if connected and not machine.reset_cause() == machine.SOFT_RESET: + if get_config(CONF_HTTP_MULTIPART): + + def multipart_response(num_responses, part_size): + i = 0 + + def response_generator(): + nonlocal i + i += 1 + if i > num_responses: + return None + return "text/plain", b"X" * part_size + + return response_generator + + def multipart_callback(http_ctx, _): + part_count = int(http_ctx.headers.get("x-part-count", 1)) + part_size = int(http_ctx.headers.get("x-part-size", 1024)) + return "multipart/form-data", multipart_response(part_count, part_size) + + HttpEngine.register("/test/multipart", multipart_callback, "GET") + asyncio.create_task(server.start_socket_server()) asyncio.create_task(mem_usage()) while True: diff --git a/tests/system/http_dimensioning/http_user.py b/tests/system/http_dimensioning/http_user.py new file mode 100644 index 0000000..e1548c4 --- /dev/null +++ b/tests/system/http_dimensioning/http_user.py @@ -0,0 +1,164 @@ +from locust import HttpUser, task, constant + +TLS_VERIFY = False + + +class DefaultUser(HttpUser): + """ + Use the /index.html and /examples.html + endpoints to test static file serving. + """ + + wait_time = constant(0) + + def on_start(self): + self.client.verify = TLS_VERIFY + + @task(2) + def get_index(self): + response = self.client.get( + "/index.html", + name="/index.html", + ) + print( + self.client.base_url + "/index.html", + response.status_code, + response.elapsed.total_seconds(), + ) + + @task(2) + def get_docs(self): + response = self.client.get( + "/examples.html", + name="/examples.html", + ) + print( + self.client.base_url + "/examples.html", + response.status_code, + response.elapsed.total_seconds(), + ) + + @task(1) + def post_chunked(self): + """ + Use the /test/stream endpoint to test chunked request handling, + sending a chunked request with multiple chunks of specified size. + """ + part_count = 10 + part_size = 256 + chunked_data = b"" + for i in range(part_count): + chunked_data += b"%X\r\n" % part_size + chunked_data += b"X" * part_size + b"\r\n" + chunked_data += b"0\r\n\r\n" + + response = self.client.post( + "/test/stream", + data=chunked_data, + headers={ + "Content-Type": "application/octet-stream", + "Transfer-Encoding": "chunked", + }, + name="/test/stream", + ) + print( + self.client.base_url + + "/test/stream (chunked; parts=%d, size=%d)" % (part_count, part_size), + response.status_code, + response.elapsed.total_seconds(), + ) + + +class MultipartUser(HttpUser): + wait_time = constant(0) + + def on_start(self): + self.client.verify = TLS_VERIFY + + @task(2) + def get_multipart(self): + """ + Use the /test/multipart endpoint with the x-part-count and x-part-size + headers to test multipart response handling. + """ + part_count = 10 + part_size = 256 + response = self.client.get( + "/test/multipart", + headers={"x-part-count": str(part_count), "x-part-size": str(part_size)}, + name="/test/multipart", + ) + print( + self.client.base_url + + "/test/multipart (parts=%d, size=%d)" % (part_count, part_size), + response.status_code, + response.elapsed.total_seconds(), + ) + + @task(1) + def post_multipart(self): + """ + Use the /test/stream endpoint to test multipart request handling, + sending multipart requests with multiple parts of specified size. + """ + part_count = 10 + part_size = 256 + multipart_data = b"" + for i in range(part_count): + multipart_data += b"--boundary\r\n" + multipart_data += ( + b'Content-Disposition: form-data; name="part"; filename="part%d.txt"\r\n' + % i + ) + multipart_data += b"Content-Type: text/plain\r\n\r\n" + multipart_data += b"X" * part_size + b"\r\n" + multipart_data += b"--boundary--\r\n" + + response = self.client.post( + "/test/stream", + data=multipart_data, + headers={"Content-Type": "multipart/form-data; boundary=boundary"}, + name="/test/stream", + ) + print( + self.client.base_url + + "/test/stream (multipart; parts=%d, size=%d)" % (part_count, part_size), + response.status_code, + response.elapsed.total_seconds(), + ) + + +class FilesApiUser(HttpUser): + """ + Use the /files endpoint to test static + file serving with directory listing. + """ + + wait_time = constant(0) + + def on_start(self): + self.client.verify = TLS_VERIFY + + @task(2) + def get_index(self): + response = self.client.get( + "/files/www/index.html", + name="/files/www/index.html", + ) + print( + self.client.base_url + "/files/www/index.html", + response.status_code, + response.elapsed.total_seconds(), + ) + + @task(2) + def get_dir(self): + response = self.client.get( + "/files/www/", + name="/files/www/", + ) + print( + self.client.base_url + "/files/www/", + response.status_code, + response.elapsed.total_seconds(), + ) diff --git a/tests/system/http_dimensioning/test.py b/tests/system/http_dimensioning/test.py index 562440c..ae2acb0 100644 --- a/tests/system/http_dimensioning/test.py +++ b/tests/system/http_dimensioning/test.py @@ -1,18 +1,53 @@ """ -Measure memory usage of HTTP server. +This test performs load tests while dimensioning the HTTP server +with different configurations, measuring the resulting heap usage +and performance. The test is designed to run against a device +running the boot.py + +Tests are performed with the Locust load testing framework, simulating +multiple concurrent users accessing the device's HTTP server with +different request patterns. + +The test workflow includes: +1. Applying a configuration to the device using mpremote. + +2. Performing a load test with Locust, simulating concurrent + users making requests to the device. + +3. Measuring the heap usage of the device before and after + the load test using a dedicated endpoint. + +4. Collecting performance metrics such as response times and + request rates from Locust. + +5. Visualizing the results with time series plots of heap usage and a + summary table of performance metrics for each configuration. """ +from flask import json +from gevent import os +import gevent.monkey + +gevent.monkey.patch_all() + +import urllib3 + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +import gevent import requests import sys import socket import subprocess import tempfile -import threading import math -from time import sleep +from time import sleep, monotonic +from locust.env import Environment +from locust.stats import stats_printer from utils import generate_measurement_table, generate_plot +from http_user import DefaultUser, FilesApiUser, MultipartUser # --------------------------- # Test configuration settings @@ -121,6 +156,14 @@ def round_up_sig(x, sig=3): } for max_con in socket_counts ], + "files_api": [ + { + "http_mem_cap": round_up_sig((buffer_small / sram_bytes) * max_con, 3), + "http_files_api": True, + "socket_max_con": max_con, + } + for max_con in socket_counts + ], "tls": [ { "http_mem_cap": round_up_sig((buffer_small / sram_bytes) * max_con, 3), @@ -207,54 +250,54 @@ def measure_footprint(config, device_ip): def load_test(config, device_ip): proto = "https" if config["tls"] else "http" port = 4443 if config["tls"] else 8080 + host = f"{proto}://{device_ip}:{port}" max_con = config.get("socket_max_con", 1) - base_url = f"{proto}://{device_ip}:{port}" + user_classes = [DefaultUser] + if config.get("http_multipart", False): + user_classes = [MultipartUser] + if config.get("http_files_api", False): + user_classes = [FilesApiUser] - stop_flag = False - results = { - "ok": 0, - "errors": 0, - } + env = Environment( + user_classes=user_classes, + host=host, + ) + + runner = env.create_local_runner() + runner.start( + user_count=max_con, + spawn_rate=max_con, + ) + + start_time = monotonic() + while monotonic() - start_time < LOAD_TEST_DURATION: + gevent.sleep(5) + + print( + f"users={runner.user_count} " + f"state={runner.state} " + f"requests={env.stats.total.num_requests} " + f"failures={env.stats.total.num_failures}" + ) - lock = threading.Lock() - - def worker(): - nonlocal stop_flag - while not stop_flag: - try: - resp = requests.get( - f"{base_url}/index.html", - verify=False, - timeout=5, - headers={"Connection": "close"}, - ) - resp.raise_for_status() - - with lock: - results["ok"] += 1 - - except Exception: - with lock: - results["errors"] += 1 - - threads = [] - for _ in range(max_con): - t = threading.Thread(target=worker, daemon=True) - t.start() - threads.append(t) - - # Run load phase - sleep(LOAD_TEST_DURATION) - - # Stop workers - stop_flag = True - for t in threads: - t.join(timeout=2) + runner.quit() + + total = env.stats.total + stats = { + "ok": total.num_requests, + "errors": total.num_failures, + "avg_ms": total.avg_response_time, + "min_ms": total.min_response_time, + "max_ms": total.max_response_time, + "rps": total.current_rps, + "p95_ms": total.get_response_time_percentile(0.95), + "p99_ms": total.get_response_time_percentile(0.99), + } try: usage = requests.get( - f"{base_url}/mem/time-series", + f"{host}/mem/time-series", verify=False, timeout=5, headers={"Connection": "close"}, @@ -263,17 +306,9 @@ def worker(): print(f"Measured: {usage}") except Exception as e: print(f"WARNING - exception: {e}") - return { - "load": [], - "load_stats": results, - "concurrency": max_con, - } - - return { - "load": usage, - "load_stats": results, - "concurrency": max_con, - } + return [], stats + + return usage, stats def test_config_delta(device_name, device_ip, base_config, config_delta={}): @@ -293,8 +328,8 @@ def test_config_delta(device_name, device_ip, base_config, config_delta={}): apply_mpremote_config(target_config, device_name) idle = measure_footprint(target_config, device_ip) - load = load_test(target_config, device_ip) - return idle, load + usage, stats = load_test(target_config, device_ip) + return idle, usage, stats if __name__ == "__main__": @@ -305,38 +340,46 @@ def test_config_delta(device_name, device_ip, base_config, config_delta={}): validate_device_ip(device_ip) apply_mpremote_config(base_config, device_id) - measured_idle, measured_load = test_config_delta(device_id, device_ip, base_config) - baseline = { + idle, usage, stats = test_config_delta(device_id, device_ip, base_config) + + base_measurement = { "id": "base", - "idle": measured_idle, + "idle": idle, + "usage": usage, + "stats": stats, "config": base_config, } - baseline.update(measured_load) + generate_plot(base_measurement, device_name) - measurements = [] + measurements = [base_measurement] sram_bytes, buffer_small, buffer_large = get_mem_params(device_id) test_config = get_test_config(sram_bytes, buffer_small, buffer_large) for case in test_config: delta_cnt = 0 for i, delta in enumerate(test_config[case]): - measured_idle, measured_load = test_config_delta( + load_idle, load_usage, load_stats = test_config_delta( device_id, device_ip, base_config, delta ) - if measured_idle and measured_load: + if load_idle and load_usage and load_stats: delta_cnt += 1 m = { "id": f"{case}_{delta_cnt:03d}", - "idle": measured_idle, - "delta": delta, + "idle": load_idle, + "usage": load_usage, + "stats": load_stats, + "config": base_config | delta, } - m.update(measured_load) measurements.append(m) + generate_plot(m, device_name) + + target_dir = device_name.replace("-", "_").lower() + if target_dir not in os.listdir("./docs/dimensioning/"): + os.mkdir(f"./docs/dimensioning/{target_dir}") - print(baseline) - print(measurements) + with open(f"docs/dimensioning/{target_dir}/measurements.json", "w") as f: + json.dump(measurements, f, indent=4) table = generate_measurement_table( - baseline, measurements, excluded_keys={ "http_port", @@ -347,8 +390,4 @@ def test_config_delta(device_name, device_ip, base_config, config_delta={}): }, ) - generate_plot(baseline, device_name) - for m in measurements: - generate_plot(m, device_name) - print(table) diff --git a/tests/system/http_dimensioning/utils.py b/tests/system/http_dimensioning/utils.py index b976d84..1747e19 100644 --- a/tests/system/http_dimensioning/utils.py +++ b/tests/system/http_dimensioning/utils.py @@ -6,14 +6,15 @@ # ----------------------------------- -def generate_measurement_table(base, measurements, excluded_keys={}): +def generate_measurement_table(measurements, excluded_keys={}): """ Generate a table in markdown format for measurement data. """ + base = measurements[0] config_keys = set(base.get("config", {}).keys()) - for m in measurements: - config_keys.update(m.get("delta", {}).keys()) + for m in measurements[1:]: + config_keys.update(m.get("config", {}).keys()) config_keys = sorted(k for k in config_keys if k not in excluded_keys) headers = ["id"] + config_keys + ["footprint_bytes"] @@ -29,13 +30,10 @@ def generate_measurement_table(base, measurements, excluded_keys={}): rows.append(base_row) # Measurements - for m in measurements: - effective_cfg = dict(base_cfg) - effective_cfg.update(m.get("delta", {})) - + for m in measurements[1:]: row = [m["id"]] for key in config_keys: - row.append(effective_cfg.get(key, "")) + row.append(m["config"].get(key, "")) row.append(m["idle"]) rows.append(row) @@ -53,14 +51,14 @@ def generate_plot(measurement, device_name): id = measurement["id"] try: - last_idx = measurement["load"].index(0, 1) + last_idx = measurement["usage"].index(0, 1) except ValueError: - last_idx = len(measurement["load"]) + last_idx = len(measurement["usage"]) xticks = list(range(last_idx)) fig, ax = plt.subplots() - p = ax.plot(xticks, measurement["load"][0:last_idx]) + p = ax.plot(xticks, measurement["usage"][0:last_idx]) plt.title(f"Heap usage over time - {device_name}\n{id}") plt.grid(True) plt.xlabel("Time [s]") @@ -73,27 +71,29 @@ def generate_plot(measurement, device_name): label.set_visible(False) # Additional annotation - load_stats = measurement.get("load_stats", {}) - concurrency = measurement.get("concurrency", "n/a") - - ok = load_stats.get("ok", 0) - errors = load_stats.get("errors", 0) + load_stats = measurement.get("stats", {}) + concurrency = measurement["config"].get("socket_max_con", "n/a") - annotation_text = f"concurrency: {concurrency}\n" f"ok: {ok}\n" f"errors: {errors}" + annotation_text = "\n".join( + f"{key}: {value if not isinstance(value, float) else (f'{value:.0f}' if key.endswith('_ms') else f'{value:.2f}')}" + for key, value in load_stats.items() + ) + annotation_text += f"\nconcurrency: {concurrency}" plt.gca().text( - 0.02, - 0.98, + 0.95, + 0.05, annotation_text, transform=plt.gca().transAxes, fontsize=9, - verticalalignment="top", + verticalalignment="bottom", + horizontalalignment="right", bbox=dict(boxstyle="round", alpha=0.3), ) target_dir = device_name.replace("-", "_").lower() - if target_dir not in os.listdir("./docs/dimensioning/img/"): - os.mkdir(f"./docs/dimensioning/img/{target_dir}") + if target_dir not in os.listdir("./docs/dimensioning/"): + os.mkdir(f"./docs/dimensioning/{target_dir}") - plt.savefig(f"./docs/dimensioning/img/{target_dir}/{id}.png") + plt.savefig(f"./docs/dimensioning/{target_dir}/{id}.png") plt.clf()