PV - botleneck

Few days ago I had the need to debug the output of a stream, the problem was that the output is bandwidth is not always constant and that seamed to affect the input application didn’t behave the same with different workloads.

A colleague told me to check pv. As I have never used it before I checked the man page first and it seamed promising. Bellow there are some details about it.

pv can be used to:

progress show progress bar
timer show elapsed time
eta show estimated time of arrival (completion)
rate show data transfer rate counter
average-rate show data transfer average rate counter
bytes show number of bytes transferred
format FORMAT set output format to FORMAT
numeric output percentages, not visual information

you can also change the standard behaviour of a pipe (and probably this is the most interesting part), you’ll be able to:

rate-limit RATE limit transfer to RATE bytes per second
buffer-size BYTES use a buffer size of BYTES
skip-errors skip read errors in input
stop-at-size stop after –size bytes have been transferred

Here are 3 pv usage examples:

Limit bw available within a pipe:

In this case I’ll limit the write of a file to 1024MB/s, while writing a 10MB file (please note that the limits on both dd and pv are in bytes)

dd count=10 bs=1048576 if=/dev/zero | pv -L 1048576 | dd of=to_delete.file
10+0 records in [1021kiB/s] [ <=> ]
10+0 records out
10485760 bytes (10 MB) copied, 9.84052 s, 1.1 MB/s
10MiB 0:00:09 [1.01MiB/s] [ <=> ]
20400+100 records in
20480+0 records out
10485760 bytes (10 MB) copied, 9.93452 s, 1.1 MB/s

Write only a 5 MB file from the pipe:

dd count=10 bs=1048576 if=/dev/zero | pv -S -s 5242880 | dd of=to_delete.file
5MiB 0:00:00 [92.4MiB/s] [===========================================>] 100%
10240+0 records in
10240+0 records out
5242880 bytes (5.2 MB) copied, 0.073623 s, 71.2 MB/s

Increase the buffer size for faster transfers

With default buffers (512KB):

dd count=500 bs=1048576  if=/dev/zero | pv | dd of=/dev/null
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.684948 s, 765 MB/s
500MiB 0:00:00 [ 731MiB/s] [ <=>                                                                       ]
1024000+0 records in
1024000+0 records out
524288000 bytes (524 MB) copied, 0.683847 s, 767 MB/s

With a bigger buffer (5MB):

dd count=500 bs=1048576  if=/dev/zero | pv -B 5242880 | dd of=/dev/null
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.667252 s, 786 MB/s
500MiB 0:00:00 [ 750MiB/s] [ <=>                                                                       ]
1024000+0 records in
1024000+0 records out
524288000 bytes (524 MB) copied, 0.667482 s, 785 MB/s

If you want to have more information or check some other use cases you may check this post on cyberciti.

See you next time,

Pedro Oliveira