Skip to content

Run the workload

We are finally ready to run our workload! In this section, we inspect a little bit more the output we saw in the previous section, explaining how to interpret it.

Do a test run

We now run a workload for 2 minutes (-d 120) and 4 connections (-c 4). We also want read operations to make 70% of the overall traffic.

# targeting PostgreSQL Server
$ dbworkload run -w bank.py \
  --uri 'postgres://fabio:postgres@localhost:5432/bank?sslmode=disable' \
  --args '{"read_pct": 70}' -d 120 -c 4
2024-10-21 09:49:12,276 [INFO] (MainProcess MainThread) run:269: Starting workload Bank.20241021_134912
My thread ID is 0. The total count of threads is 4
My thread ID is 3. The total count of threads is 4
My thread ID is 1. The total count of threads is 4
My thread ID is 2. The total count of threads is 4
PostgreSQL 16.2 (Postgres.app) on aarch64-apple-darwin21.6.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.102), 64-bit
PostgreSQL 16.2 (Postgres.app) on aarch64-apple-darwin21.6.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.102), 64-bit
PostgreSQL 16.2 (Postgres.app) on aarch64-apple-darwin21.6.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.102), 64-bit
PostgreSQL 16.2 (Postgres.app) on aarch64-apple-darwin21.6.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.102), 64-bit
  elapsed  id                threads    tot_ops    tot_ops/s    period_ops    period_ops/s    mean(ms)    p50(ms)    p90(ms)    p95(ms)    p99(ms)    max(ms)
---------  --------------  ---------  ---------  -----------  ------------  --------------  ----------  ---------  ---------  ---------  ---------  ---------
       10  __cycle__               4      4,792          479         4,792               0        7.22       0.27      24.55      25.46      26.57      72.60
       10  txn_new_order           4      1,417          141         1,417               0        0.50       0.38       0.56       0.64       1.03      32.68
       10  txn_order_exec          4      1,417          141         1,417               0       23.25      23.12      25.36      25.78      26.75      66.76
       10  txn_read                4      3,375          337         3,375               0        0.27       0.23       0.36       0.41       0.52      31.26 

  elapsed  id                threads    tot_ops    tot_ops/s    period_ops    period_ops/s    mean(ms)    p50(ms)    p90(ms)    p95(ms)    p99(ms)    max(ms)
---------  --------------  ---------  ---------  -----------  ------------  --------------  ----------  ---------  ---------  ---------  ---------  ---------
       20  __cycle__               4     10,492          524         5,700               0        6.95       0.26      24.27      25.18      26.26      40.11
       20  txn_new_order           4      3,065          153         1,648               0        0.40       0.36       0.53       0.61       0.80       7.34
       20  txn_order_exec          4      3,065          153         1,648               0       23.01      22.91      25.21      25.62      26.27      39.71
       20  txn_read                4      7,427          371         4,052               0        0.24       0.22       0.35       0.40       0.51       5.02 

[...truncating...]

  elapsed  id                threads    tot_ops    tot_ops/s    period_ops    period_ops/s    mean(ms)    p50(ms)    p90(ms)    p95(ms)    p99(ms)    max(ms)
---------  --------------  ---------  ---------  -----------  ------------  --------------  ----------  ---------  ---------  ---------  ---------  ---------
      110  __cycle__               4     59,242          538         5,602               0        7.08       0.26      24.88      25.54      26.35      41.93
      110  txn_new_order           4     17,685          160         1,617               0        0.42       0.37       0.55       0.62       0.92       9.19
      110  txn_order_exec          4     17,685          160         1,617               0       23.48      23.70      25.45      25.75      26.43      41.59
      110  txn_read                4     41,557          377         3,985               0        0.25       0.22       0.35       0.40       0.51      15.43 

2024-10-21 09:51:12,330 [INFO] (MainProcess MainThread) run:369: Requested iteration/duration limit reached
2024-10-21 09:51:12,331 [INFO] (MainProcess MainThread) run:176: Printing final stats
  elapsed  id                threads    tot_ops    tot_ops/s    period_ops    period_ops/s    mean(ms)    p50(ms)    p90(ms)    p95(ms)    p99(ms)    max(ms)
---------  --------------  ---------  ---------  -----------  ------------  --------------  ----------  ---------  ---------  ---------  ---------  ---------
      120  __cycle__               4     64,652          538         5,410               0        7.39       0.27      24.87      25.57      26.39      55.03
      120  txn_new_order           4     19,322          161         1,637               0        0.46       0.37       0.55       0.62       0.79      29.40
      120  txn_order_exec          4     19,322          161         1,637               0       23.39      23.53      25.49      25.77      26.27      44.41
      120  txn_read                4     45,330          377         3,773               0        0.25       0.23       0.35       0.40       0.49       5.49 

2024-10-21 09:51:12,332 [INFO] (MainProcess MainThread) run:181: Printing summary for the full test run

-------------  --------------------
run_name       Bank.20241021_134912
start_time     2024-10-21 13:49:12
end_time       2024-10-21 13:51:12
test_duration  120
-------------  --------------------

┌───────────┬────────────────┬───────────┬───────────┬─────────────┬────────────┬───────────┬───────────┬───────────┬───────────┬───────────┐
│   elapsed  id                threads    tot_ops    tot_ops/s    mean(ms)    p50(ms)    p90(ms)    p95(ms)    p99(ms)    max(ms) │
├───────────┼────────────────┼───────────┼───────────┼─────────────┼────────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│       120  __cycle__               4     64,652          538        7.29       0.30      24.72      25.51      26.42      98.36 │
│       120  txn_new_order           4     19,322          161        0.44       0.37       0.56       0.64       0.88      33.19 │
│       120  txn_order_exec          4     19,322          161       23.34      23.34      25.45      25.78      26.39      97.89 │
│       120  txn_read                4     45,330          377        0.26       0.23       0.36       0.41       0.52      31.26 │
└───────────┴────────────────┴───────────┴───────────┴─────────────┴────────────┴───────────┴───────────┴───────────┴───────────┴───────────┘

Parameter      Value
-------------  -----------------------------------------------------------------------------------------------------------------------
workload_path  /path/to/workloads/bank.py
conn_params    {'conninfo': 'postgres://fabio:postgres@localhost:5432/bank?sslmode=disable&application_name=Bank', 'autocommit': True}
conn_extras    {}
concurrency    4
duration       120
iterations
ramp           0
args           {'read_pct': 70}

As we have created 4 connections, each connection will execute the setup() function and print its thread ID and server version.

dbworkload will then print out, every 10 seconds, a table with count and latency statistics for the functions it invoked.

It is importand to understand that the statistics are on a function basis, not SQL transaction basis: as we saw while coding the bank.py workload class, certain functions do more than just executing a SQL statement. Function txn_order_exec, for example, executes 1 SELECT statements, then pauses for 20ms, and last it executes the UPDATE statement.

dbworkload thus shows you the latency to execute business functions rather than individual database statements/transactions.

Finally, you have noticed there is a __cycle__ entry in the table. This metric shows you the duration of the total execution of all functions returned in the loop(). This is helpful if the metric you use to benchmark your workload is neither at SQL transaction nor function level, but for the overall time taken to perform a series of functions.

For example, you can measure the performance based on total execution time of an Order Transaction, that is, the sum of executing the txn_new_order and txn_order_exec.

Save stats to CSV

dbworkload can save the statistics to a CSV file for later inspection.

There are 2 common uses of the CSV files:

  • as an input to plot charts.
  • if dbworkload is executed from multiple servers towards the same target, you can merge the CSV files to have a unified view of all the collected metrics.

For this second run, we add flags for saving to CSV (-s) and for omitting printing to stdout (-q).

$ dbworkload run -w bank.py \
  --uri 'postgres://fabio:postgres@localhost:5432/bank?sslmode=disable' \
  --args '{"read_pct": 70}' -d 120 -c 4 \
  -s -q

After 2 minutes, check your directory for 2 new files:

  • a .csv file
  • a .txt file
$ ls -lh1 Bank.*
Bank.20241021_145825.csv
Bank.20241021_145825.txt

The .txt file shows a summary of the test run, whose name you've noticed takes the form of the workload name, Bank, followed by the timestamp.

In the next session, we will use the .csv file to plot some charts.