Performance is Redis most advertized selling point. As an in-memory database it provides low-latency solutions for backend typical needs: caching, queuing, rate limiting etc.
The Redis server however is only one side of the equation, clients on the other end must be capable of using the server efficiently for the performance of the system as a whole to be great.
In this article we profiled the performance of some of the most popular clients by simulating the scenario where Redis is mostly used: internet facing servers (usually HTTP) that serve connections concurrently while receiving server pushes e.g. pubsub events. The benchmark consists of
-
starting multiple sessions that issue commands in a loop.
-
subscribing to a channel to receive pubsub events.
The following clients have been considered
| Client | UIA | Stars | Contributors | Age | Lnaguage |
|---|---|---|---|---|---|
| boost-redis | 64 | 270 | 14 | 6 | C++ |
| go-redis | 1090 | 21800 | 400 | 13 | Go |
| rueidis | 174 | 2900 | 132 | 5 | Go |
| redis-rs | 495 | 4100 | 261 | 12 | Rust |
| redis++ | 327 | 1900 | 44 | 8 | C++ |
| fred-rs* | 94 | 505 | 1 | 4 | Rust |
Where the abbreviation UIA used above refers to the unique number of github issue authors (Unique Issue Authors)
- The
fred-rsbenchmark was aborted due to apparent bug or misuse of the library, which is being clarified in this issue.
The parameters used in the simulation result in the following number of requests, responses and pushes
| Type | Counter | Bytes (Mb) |
|---|---|---|
| Requests | 60M | 1130 |
| Responses | 60M | 390 |
| Pushes | 10M | 430 |
| Client | Time (s/s) |
|---|---|
| boost-redis-asio-co | 2.2 |
| boost-redis-asio-cb | 1.3 |
| boost-redis-corosio | 1 |
| redis-rs | 4.7 |
| rueidis | - |
| go-redis | 27.6 |
The table above provide the times normalized to the fastest client which was boost-redis running on corosio. The value has been computed by multiplying the wall time with the percentage of CPU usage by the client.
| Client | user(%) | sys(%) |
|---|---|---|
| boost-redis-asio-co | 65.0 | 3.3 |
| boost-redis-asio-cb | 46.2 | 2.8 |
| boost-redis-corosio | 32.5 | 6.2 |
| redis-rs | 98.2 | 1.6 |
| rueidis | - | - |
| go-redis | 174.0 | 105.1 |
| Client | threads | fd-nr |
|---|---|---|
| boost-redis-asio-co | 2 | 7 |
| boost-redis-asio-cb | 2 | 7 |
| boost-redis-corosio | 3 | 7 |
| redis-rs | 1 | 10 |
| rueidis | - | - |
| go-redis | 24 | 1006 |
| Client | context switches/s |
|---|---|
| boost-redis-asio-co | 2733.56 |
| boost-redis-asio-cb | 2861.21 |
| boost-redis-corosio | 3325.44 |
| redis-rs | 25.85 |
| rueidis | |
| go-redis | 3113.71 |
| Client | cache-misses | branch-misses |
|---|---|---|
| boost-redis-asio-co | 16,808,299 | 84,612,336 |
| boost-redis-asio-cb | 6,979,958 | 56,653,319 |
| boost-redis-corosio | 19,369,915 | 75,381,092 |
| redis-rs | 736,951 | 302,865,130 |
| rueidis | - | - |
| go-redis | 1,216,462,587 | 1,666,424,709 |
Time needed to build different configuration using only one process e.g. make -j1.
| Client | Time(s) |
|---|---|
| boost-redis-asio-co | 3.60 |
| boost-redis-asio-cb | 8.62 |
| boost-redis-corosio | 1.68 |
| redis-rs | 3.10 |
| fred-rs | 12.80 |
| go-redis | 0.28 |
| rueidis | 0.28 |
| Client | Time(s) |
|---|---|
| boost-redis-lib-asio | 21.7 |
| boost-redis-lib-corosio | 5.3 |
| redis-rs | 9.6 |
| fred-rs | 18.7 |
| go-redis | - |
| rueidis | - |
NOTE: I haven't found a way to build only the client excluding the app in go.
| Client | Time(s) |
|---|---|
| boost-redis-asio-co | 35.5 |
| boost-redis-asio-cb | 40.5 |
| boost-redis-corosio | 33.6 |
| redis-rs | 42.6 |
| fred-rs | 63.7 |
| go-redis | 9.0 |
| rueidis | 9.5 |