---
tags: sidechains, benchmarks
---
# Profile Deku with `landmarks`, `wrk`, and traffic control `tc`
## Landmarks profiling
Note that:
> This tool is intended to be used as a way to find where the time is spent in your programs (and not benchmark independent pieces of code like Core_bench) while providing results that only correspond to the instrumented portion of your OCaml code (contrary to tools that directly work with the binary executable like `gprof` or `perf`).
### Example
Dune setting
```
(executable
(name bench_load_tests)
(public_name bench-load-tests)
(modules bench_load_tests)
(preprocess
(pps landmarks-ppx --auto))
(libraries load_test_helpers landmarks))
```
You can either use the `landmarks-ppx` as an example below, or add the
`landmarks` and `landmarks-ppx --auto` in `dune` only as example above to get the profile for the code.
```
[@@@landmark "auto"]
let[@landmark] init_params n =
List.init n (fun i ->
let i = i |> Float.of_int in
(2. ** i, 2. ** (Float.of_int n -. i)))
let () =
let[@landmark] main () = ignore (init_params 13) in
main ()
```
Build:
```
dune build
OCAML_LANDMARKS=on _build/default/tests/e2e/bench_load_tests.exe
```
Output:
```
OCAML_LANDMARKS=on _build/default/tests/e2e/bench_load_tests.exe
Call graph '_build/default/tests/e2e/bench_load_tests.exe':
-----------------------------------------------------------
[ 29.74K cycles in 1 calls ] - 70.21% : load(bench_load_tests)
[ 28.95K cycles in 1 calls ] | - 97.34% : Bench_load_tests.main
[ 28.07K cycles in 1 calls ] | | - 96.95% : Bench_load_tests.init_params
Note: Nodes accounting for less than 1.00% of their parent have been ignored.
Aggregated table:
----------------
Name; Filename; Calls; Time
ROOT; src/landmark.ml; 0; 42.36K
load(bench_load_tests); tests/e2e/bench_load_tests.ml:11; 1; 29.74K
Bench_load_tests.main; tests/e2e/bench_load_tests.ml:19; 1; 28.95K
Bench_load_tests.init_params; tests/e2e/bench_load_tests.ml:13; 1; 28.07K
```
Example on Git: [bench_landmarks](https://github.com/marigold-dev/deku/tree/d4hines/copy-noop-benchmarking/tests/e2e/bench_landmarks)
## Wrk
Wrk is a modern HTTP benchmarking tool written in C language which can be used to test the performance of an API.
### Example with deku-node
- Start a deku-node running on terminal 1
```
docker compose up -d
./sandbox.sh setup
./sandbox.sh start
```
- Using `wrk`
Start a second terminal and run a benchmark for `http://localhost:4441` for 1 minute `d60s`, using 8 threads `-t8`, keeping 40 http connection opens `-c40`, and a constant throughput of 30K requests per second `-R 30K` (total, across all connections combined), print latency statistics percentile info `-L` and measure latency of whole batches of pipeline ops `-B` (as opposed to each op)
```
sudo wrk -t8 -c40 -d60s -R 30K -L -B http://localhost:4441
```
The `wrk` report provides the Latency and Request/Sec statistics and along with the latency distribution by percentile.
Output:
```
sudo wrk -t8 -c40 -d60s -R 30K -L -B http://localhost:4441
Running 1m test @ http://localhost:4441
8 threads and 40 connections
Thread calibration: mean lat.: 63.123ms, rate sampling interval: 295ms
Thread calibration: mean lat.: 62.393ms, rate sampling interval: 294ms
Thread calibration: mean lat.: 63.582ms, rate sampling interval: 305ms
Thread calibration: mean lat.: 63.134ms, rate sampling interval: 297ms
Thread calibration: mean lat.: 64.164ms, rate sampling interval: 312ms
Thread calibration: mean lat.: 63.582ms, rate sampling interval: 294ms
Thread calibration: mean lat.: 63.233ms, rate sampling interval: 302ms
Thread calibration: mean lat.: 63.665ms, rate sampling interval: 299ms
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.14s 3.19s 10.69s 80.51%
Req/Sec 2.96k 621.97 4.77k 70.45%
Latency Distribution (HdrHistogram - Recorded Latency)
50.000% 1.86s
75.000% 5.07s
90.000% 8.60s
99.000% 10.40s
99.900% 10.63s
99.990% 10.67s
99.999% 10.70s
100.000% 10.70s
```
Save this part output into a `text.hrgm` and import it via https://hdrhistogram.github.io/HdrHistogram/plotFiles.html
```
Detailed Percentile spectrum:
Value Percentile TotalCount 1/(1-Percentile)
0.037 0.000000 1 1.00
94.975 0.100000 118110 1.11
191.615 0.200000 236053 1.25
372.223 0.300000 354058 1.43
1113.087 0.400000 472100 1.67
1862.655 0.500000 590161 2.00
2785.279 0.550000 649145 2.22
3354.623 0.600000 708107 2.50
3737.599 0.650000 767106 2.86
4435.967 0.700000 826204 3.33
5066.751 0.750000 885160 4.00
5427.199 0.775000 914788 4.44
6242.303 0.800000 944163 5.00
6762.495 0.825000 973724 5.71
7569.407 0.850000 1003125 6.67
8056.831 0.875000 1032690 8.00
8384.511 0.887500 1047427 8.89
8601.599 0.900000 1062451 10.00
8880.127 0.912500 1077241 11.43
9117.695 0.925000 1091780 13.33
9371.647 0.937500 1106404 16.00
9486.335 0.943750 1114108 17.78
9568.255 0.950000 1121200 20.00
9691.135 0.956250 1128976 22.86
9773.055 0.962500 1135895 26.67
9846.783 0.968750 1143438 32.00
9895.935 0.971875 1147321 35.56
9986.047 0.975000 1150711 40.00
10092.543 0.978125 1154576 45.71
10166.271 0.981250 1158024 53.33
10256.383 0.984375 1162031 64.00
10280.959 0.985938 1163602 71.11
10330.111 0.987500 1165473 80.00
10387.455 0.989062 1167598 91.43
10420.223 0.990625 1169282 106.67
10461.183 0.992188 1171299 128.00
10477.567 0.992969 1172144 142.22
10493.951 0.993750 1173064 160.00
10510.335 0.994531 1174015 182.86
10526.719 0.995313 1175026 213.33
10543.103 0.996094 1175793 256.00
10551.295 0.996484 1176076 284.44
10567.679 0.996875 1176495 320.00
10584.063 0.997266 1176958 365.71
10600.447 0.997656 1177604 426.67
10608.639 0.998047 1178023 512.00
10616.831 0.998242 1178488 568.89
10616.831 0.998437 1178488 640.00
10625.023 0.998633 1178914 731.43
10625.023 0.998828 1178914 853.33
10633.215 0.999023 1179259 1024.00
10633.215 0.999121 1179259 1137.78
10633.215 0.999219 1179259 1280.00
10641.407 0.999316 1179547 1462.86
10641.407 0.999414 1179547 1706.67
10649.599 0.999512 1179792 2048.00
10649.599 0.999561 1179792 2275.56
10649.599 0.999609 1179792 2560.00
10649.599 0.999658 1179792 2925.71
10657.791 0.999707 1179923 3413.33
10657.791 0.999756 1179923 4096.00
10657.791 0.999780 1179923 4551.11
10657.791 0.999805 1179923 5120.00
10665.983 0.999829 1180011 5851.43
10665.983 0.999854 1180011 6826.67
10665.983 0.999878 1180011 8192.00
10674.175 0.999890 1180067 9102.22
10674.175 0.999902 1180067 10240.00
10674.175 0.999915 1180067 11702.86
10674.175 0.999927 1180067 13653.33
10682.367 0.999939 1180105 16384.00
10682.367 0.999945 1180105 18204.44
10682.367 0.999951 1180105 20480.00
10682.367 0.999957 1180105 23405.71
10682.367 0.999963 1180105 27306.67
10690.559 0.999969 1180124 32768.00
10690.559 0.999973 1180124 36408.89
10690.559 0.999976 1180124 40960.00
10690.559 0.999979 1180124 46811.43
10690.559 0.999982 1180124 54613.33
10698.751 0.999985 1180145 65536.00
10698.751 1.000000 1180145 inf
#[Mean = 3139.480, StdDeviation = 3186.799]
#[Max = 10690.560, Total count = 1180145]
#[Buckets = 27, SubBuckets = 2048]
----------------------------------------------------------
1480586 requests in 1.00m, 63.54MB read
Non-2xx or 3xx responses: 1480586
Requests/sec: 24676.25
Transfer/sec: 1.06MB
```

## Traffic control `tc`
Traffic control (tc) is a very useful Linux utility that gives you the ability to configure the kernel packet scheduler.
```
# search for the dev
/sbin/ifconfig
# show process
lsof -i
# or
lsof -iCall graph './_build/default/etc/f.exe'
```
Traffic control
```
# delay docker0 to 97ms
sudo tc qdisc add dev docker0 root netem delay 97ms
# verify the change
tc -s qdisc | grep netem
qdisc netem 8002: dev docker0 root refcnt 2 limit 1000 delay 97ms
# latency and packet loss 20%
sudo tc qdisc change dev docker0 root netem delay 97ms loss 20%
# remove delay and lost
sudo tc qdisc change dev docker0 root netem delay 0ms loss 0%
```
## References
- landmarks: https://github.com/LexiFi/landmarks-starter
- wrk/wrk2: https://nitikagarw.medium.com/getting-started-with-wrk-and-wrk2-benchmarking-6e3cdc76555f
- traffic control `tc`: https://netbeez.net/blog/how-to-use-the-linux-traffic-control/