Now that AntTP v0.11.3 lets us disable caching again, we can see how the underlying performance is progressing. I did 3 runs and all were over 900 iterations (950, 930, 970), which is impressive and the best yet!
I was hoping it would hit the 1000 iteration test limit for the first time, but I couldn’t quite squeeze it over the line! 
This is the same (‘small’) test set as I’ve ran a bunch of times. As you can see, average response time is under 800ms and throughput is around 5.5 MB/s. Nice!
To re-iterate, this is with both in-memory and on-disk cache set to 0, to exercise the client/network the hardest.
$ cat ~/dev/anttp/test/performance/src/localhost-autonomi-http.js; k6 run -u 10 -i 1000 ~/dev/anttp/test/performance/src/localhost-autonomi-http.js
import http from 'k6/http';
export default function () {
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_QdxdljdwBwR2QbAVr8scuw.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_dH5Ce6neTHIfEkAbmsr1BQ.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_pt48p45dQmR5PBW8np1l8Q.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_sWZ4OWGeQjWs6urcPwR6Yw.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_ZT6qplX5Yt8PMCUqxq1lFQ.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_SxkGLnSNsMtu0SDrsWW8Wg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_bogEVpJvgx_gMHQoHMoSLg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_LFEyRQMHmxRnZtJwMozW5w.jpeg', { timeout: '600s' });
}
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/
execution: local
script: /home/paul/dev/anttp/test/performance/src/localhost-autonomi-http.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1000 iterations shared among 10 VUs (maxDuration: 10m0s, gracefulStop: 30s)
data_received..................: 3.4 GB 5.6 MB/s
data_sent......................: 1.4 MB 2.2 kB/s
dropped_iterations.............: 30 0.049745/s
http_req_blocked...............: avg=8.93µs min=1.57µs med=5.63µs max=3.24ms p(90)=12.53µs p(95)=16.74µs
http_req_connecting............: avg=265ns min=0s med=0s max=305.42µs p(90)=0s p(95)=0s
http_req_duration..............: avg=776.99ms min=300.18ms med=700.76ms max=3.42s p(90)=1.27s p(95)=1.63s
{ expected_response:true }...: avg=776.99ms min=300.18ms med=700.76ms max=3.42s p(90)=1.27s p(95)=1.63s
http_req_failed................: 0.00% 0 out of 7760
http_req_receiving.............: avg=515.09ms min=232.61ms med=483.52ms max=2.5s p(90)=805.75ms p(95)=929.16ms
http_req_sending...............: avg=40.78µs min=5.67µs med=16.45µs max=8.79ms p(90)=41.91µs p(95)=63.38µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=261.86ms min=209.67µs med=170.98ms max=1.5s p(90)=736.64ms p(95)=875.53ms
http_reqs......................: 7760 12.867245/s
iteration_duration.............: avg=6.21s min=4.91s med=6.18s max=8.94s p(90)=6.98s p(95)=7.14s
iterations.....................: 970 1.608406/s
vus............................: 10 min=10 max=10
vus_max........................: 10 min=10 max=10
running (10m03.1s), 00/10 VUs, 970 complete and 0 interrupted iterations
default ✗ [===================================>--] 10 VUs 10m03.1s/10m0s 0970/1000 shared iters
How does it compare to a fully cached (in-memory and on-disk) setup? Well, that is around 140 MB/s with an average latency of about 30ms. Clearly, caching helps a lot! 
$ cat ~/dev/anttp/test/performance/src/localhost-autonomi-http.js; k6 run -u 10 -i 1000 ~/dev/anttp/test/performance/src/localhost-autonomi-http.js
import http from 'k6/http';
export default function () {
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_QdxdljdwBwR2QbAVr8scuw.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_dH5Ce6neTHIfEkAbmsr1BQ.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_pt48p45dQmR5PBW8np1l8Q.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_sWZ4OWGeQjWs6urcPwR6Yw.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_ZT6qplX5Yt8PMCUqxq1lFQ.png', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_SxkGLnSNsMtu0SDrsWW8Wg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_bogEVpJvgx_gMHQoHMoSLg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/cec7a9eb2c644b9a5de58bbcdf2e893db9f0b2acd7fc563fc849e19d1f6bd872/1_LFEyRQMHmxRnZtJwMozW5w.jpeg', { timeout: '600s' });
}
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/
execution: local
script: /home/paul/dev/anttp/test/performance/src/localhost-autonomi-http.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1000 iterations shared among 10 VUs (maxDuration: 10m0s, gracefulStop: 30s)
data_received..................: 3.5 GB 139 MB/s
data_sent......................: 1.4 MB 56 kB/s
http_req_blocked...............: avg=5.93µs min=1.64µs med=4.38µs max=565.1µs p(90)=8.3µs p(95)=10.15µs
http_req_connecting............: avg=312ns min=0s med=0s max=302.64µs p(90)=0s p(95)=0s
http_req_duration..............: avg=31.2ms min=1.56ms med=40.67ms max=89.88ms p(90)=55.54ms p(95)=58.43ms
{ expected_response:true }...: avg=31.2ms min=1.56ms med=40.67ms max=89.88ms p(90)=55.54ms p(95)=58.43ms
http_req_failed................: 0.00% 0 out of 8000
http_req_receiving.............: avg=30.55ms min=1.3ms med=40.21ms max=83.58ms p(90)=54.91ms p(95)=57.62ms
http_req_sending...............: avg=16.82µs min=5.15µs med=13.44µs max=1.42ms p(90)=25.33µs p(95)=32.4µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=632.39µs min=199.29µs med=453.68µs max=17.59ms p(90)=961.62µs p(95)=1.36ms
http_reqs......................: 8000 317.904805/s
iteration_duration.............: avg=250.57ms min=112.93ms med=246.35ms max=390.94ms p(90)=315.87ms p(95)=328.68ms
iterations.....................: 1000 39.738101/s
vus............................: 8 min=8 max=10
vus_max........................: 10 min=10 max=10
running (00m25.2s), 00/10 VUs, 1000 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 00m25.2s/10m0s 1000/1000 shared iters
How about tarchives? They are a good bit slower slower and heavily CPU dependent. This is due to the cache only storing chunks in (self) encrypted form, then decrypting them on request. This makes the system secure, but it does mean that combining files in one chunk, means that a bigger chunk needs to be decrypted to read the smaller files within it.
Is the trade off worth it? Absolutely, from my experience. It puts a bit more load on the AntTP host and the latencies increase a bit, but compared to downloading lots of small chunks, the overall performance improvement is substantial (around 3x from a browser).
Without caching, I expected the difference to be minor or potentially worse. However, downloading the same chunk over and over again, seems to result in the network optimising the throughput. Therefore, there are still performance gains, even though each file request must pull the entire tarchive down. Surprising, but interesting!
In summary, about 11 MB/s and under 400ms latency - twice as good as the small files without caching:
$ cat ~/dev/anttp/test/performance/src/localhost-tarchive-autonomi-http.js; k6 run -u 10 -i 1000 ~/dev/anttp/test/performance/src/localhost-tarchive-autonomi-http.js
import http from 'k6/http';
export default function () {
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_QdxdljdwBwR2QbAVr8scuw.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_dH5Ce6neTHIfEkAbmsr1BQ.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_pt48p45dQmR5PBW8np1l8Q.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_sWZ4OWGeQjWs6urcPwR6Yw.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_ZT6qplX5Yt8PMCUqxq1lFQ.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_SxkGLnSNsMtu0SDrsWW8Wg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_bogEVpJvgx_gMHQoHMoSLg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_LFEyRQMHmxRnZtJwMozW5w.jpeg', { timeout: '600s' });
}
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/
execution: local
script: /home/paul/dev/anttp/test/performance/src/localhost-tarchive-autonomi-http.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1000 iterations shared among 10 VUs (maxDuration: 10m0s, gracefulStop: 30s)
data_received..................: 3.5 GB 11 MB/s
data_sent......................: 1.4 MB 4.5 kB/s
http_req_blocked...............: avg=8.01µs min=1.39µs med=5.42µs max=3.37ms p(90)=11.84µs p(95)=15.44µs
http_req_connecting............: avg=398ns min=0s med=0s max=555.01µs p(90)=0s p(95)=0s
http_req_duration..............: avg=385.19ms min=71.56ms med=250.75ms max=9.51s p(90)=729.83ms p(95)=927.34ms
{ expected_response:true }...: avg=385.19ms min=71.56ms med=250.75ms max=9.51s p(90)=729.83ms p(95)=927.34ms
http_req_failed................: 0.00% 0 out of 8000
http_req_receiving.............: avg=342.52ms min=70.63ms med=149.59ms max=9.51s p(90)=721.4ms p(95)=916.84ms
http_req_sending...............: avg=29.57µs min=4.85µs med=17.3µs max=6.06ms p(90)=39.11µs p(95)=51.01µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=42.63ms min=264.11µs med=5.44ms max=2.72s p(90)=126.33ms p(95)=190.01ms
http_reqs......................: 8000 25.949717/s
iteration_duration.............: avg=3.08s min=1.9s med=2.62s max=12.26s p(90)=3.97s p(95)=4.98s
iterations.....................: 1000 3.243715/s
vus............................: 10 min=10 max=10
vus_max........................: 10 min=10 max=10
running (05m08.3s), 00/10 VUs, 1000 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 05m08.3s/10m0s 1000/1000 shared iters
With in-memory/on-disk caching enabled, the full benefits can be observed, with the chunk being downloaded once, then referenced over and over again:
This results in about 30 MB/s and 160ms latency, when in-memory/on-disk caching is enabled. My CPU is also maxed out for this test (only):
$ cat ~/dev/anttp/test/performance/src/localhost-tarchive-autonomi-http.js; k6 run -u 10 -i 1000 ~/dev/anttp/test/performance/src/localhost-tarchive-autonomi-http.js
import http from 'k6/http';
export default function () {
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_QdxdljdwBwR2QbAVr8scuw.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_dH5Ce6neTHIfEkAbmsr1BQ.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_pt48p45dQmR5PBW8np1l8Q.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_sWZ4OWGeQjWs6urcPwR6Yw.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_ZT6qplX5Yt8PMCUqxq1lFQ.png', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_SxkGLnSNsMtu0SDrsWW8Wg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_bogEVpJvgx_gMHQoHMoSLg.jpeg', { timeout: '600s' });
http.get('http://localhost:18888/16969e9dbe3861f48890c42931fbfa1e3b66e0cc21071ea788df8ad527b91522/1_LFEyRQMHmxRnZtJwMozW5w.jpeg', { timeout: '600s' });
}
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/
execution: local
script: /home/paul/dev/anttp/test/performance/src/localhost-tarchive-autonomi-http.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1000 iterations shared among 10 VUs (maxDuration: 10m0s, gracefulStop: 30s)
data_received..................: 3.5 GB 27 MB/s
data_sent......................: 1.4 MB 11 kB/s
http_req_blocked...............: avg=9.48µs min=1.87µs med=6.36µs max=3.7ms p(90)=12.5µs p(95)=15.77µs
http_req_connecting............: avg=276ns min=0s med=0s max=295.48µs p(90)=0s p(95)=0s
http_req_duration..............: avg=162.69ms min=59.77ms med=138.93ms max=555.82ms p(90)=248.3ms p(95)=275.52ms
{ expected_response:true }...: avg=162.69ms min=59.77ms med=138.93ms max=555.82ms p(90)=248.3ms p(95)=275.52ms
http_req_failed................: 0.00% 0 out of 8000
http_req_receiving.............: avg=160.45ms min=59.2ms med=136.13ms max=554.69ms p(90)=246.45ms p(95)=273.27ms
http_req_sending...............: avg=38.49µs min=6.4µs med=21.05µs max=8.77ms p(90)=42.77µs p(95)=52.4µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=2.2ms min=336.27µs med=1.32ms max=31.84ms p(90)=4.86ms p(95)=6.56ms
http_reqs......................: 8000 61.219419/s
iteration_duration.............: avg=1.3s min=836.71ms med=1.29s max=1.82s p(90)=1.46s p(95)=1.5s
iterations.....................: 1000 7.652427/s
vus............................: 8 min=8 max=10
vus_max........................: 10 min=10 max=10
running (02m10.7s), 00/10 VUs, 1000 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 02m10.7s/10m0s 1000/1000 shared iters
As above, the throughput is lower than individual files (instead of a tarchive), but from a browser/client perspective, the savings from downloading fewer uncached chunks provides network efficiency gains (i.e. the 3x mentioned above). I suspect the uncached test network efficiencies above also plays into this.