Configuring Connection Pooling with Spring R2DBC
Tags: java, spring, database, r2dbc
Published: 2022-01-04 15:04:07

This article is the second part of my first article related to Spring Boot R2DBC. If you haven't checked it out, please check out:  [Reactive Spring Boot Application with R2DBC and PostgreSQL](https://kamalhm.dev/reactive-spring-boot-application-with-r2dbc-and-postgresql)

## Connection Pooling


After successfully configuring your Spring Boot with Spring Data R2DBC, you probably want to launch it to production without any performance hiccup. Unfortunately, it's not as straightforward as you would like. You will need to use connection pooling.

Connection pooling is a way to store and reuse a connection to be reused again later, avoiding the expensive cost of creating a connection for each use.

Before we implement connection pooling, let's try to do some basic benchmarks to see whether or not it improves our application performance.

## Playing Around with R2DBC Pooling Performance


There are multiple ways to load test our application, you can even use Apache Benchmark directly from your terminal with the `ab` command. But this time, I'd like to explore a tool called [K6](https://k6.10).

### Load Testing with K6


We're testing an API that will insert a hundred record into our database. This is going to be a write-heavy operation to stress the database.

### Without Connection Pooling


![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1633857332864/fSp5qR4EU.png)

Without connection pooling, we only get 140 requests completed, with the 95th percentile of 2.33s.

I also noticed that the docker instance responsible for running the database CPU usage spiked dramatically.

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1633857567481/7-W1vcZMIu.png)

## Implementing Connection Pooling in Spring Boot R2DBC


In Spring Boot application that use blocking connection to DB such as JDBC connection pooling is usually handled by a popular library called [HikariCP](https://github.com/brettwooldridge/HikariCP). Luckily, Spring Data R2DBC already includes connection pooling option that we can use just by enabling it from our `properties`.

To enable it, you can add below properties to your `application.properties` file and R2DBC will be able to pool the connections to our database! Easy right?

```other
spring.r2dbc.pool.enabled=true
spring.r2dbc.pool.initial-size=50
spring.r2dbc.pool.max-size=100
```


As you can probably guess, these properties will initiate the pool with 50 connections ready to use, and when needed it can scale up to maximum of 100 connections. Now then, let's try our benchmark again.

### With Connection Pooling


![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1636298632321/0mgyNDQeh-.png)

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1636298645768/nRAh5aGCD.png)

The result is striking. With connection pooling, we completed 480 iterations of the requests, increasing throughput by almost 3.5x and reducing our 95th percentile latency to 668ms, that's an almost 4x latency improvement! When we take a look at the docker instance, the CPU usage also stays comfy at around 76% usage. Enabling connection pooling improves the performance by almost 4x and reduced our database load significantly.

## Connection Pool Sizing


After seeing an awesome performance improvement above, you might be tempted to try and increase the connection pool even further. After all, if we can get 4x improvement with 100 connection pool, then we should get even better performance with 200 connection pool, right?

Sorry to burst the bubble but the short answer is no. If you'd like to learn further about connection pool sizing, please refer to this awesome article on pool sizing by the author of HikariCP himself: [https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing)

## Conclusion


We have learned how easy it is to enable connection pooling on an R2DBC project and its impact on your application performance. So don't forget to set it up whenever you're configuring your application!

As usual, you can see the source code for the project at: [https://github.com/kamalhm/spring-boot-r2dbc](https://github.com/kamalhm/spring-boot-r2dbc)

This article is the second part of my first article related to Spring Boot R2DBC. If you haven't checked it out, please check out:  [Reactive Spring Boot Application with R2DBC and PostgreSQL](https://kamalhm.dev/reactive-spring-boot-application-with-r2dbc-and-postgresql)

## Connection Pooling


After successfully configuring your Spring Boot with Spring Data R2DBC, you probably want to launch it to production without any performance hiccup. Unfortunately, it's not as straightforward as you would like. You will need to use connection pooling.

Connection pooling is a way to store and reuse a connection to be reused again later, avoiding the expensive cost of creating a connection for each use.

Before we implement connection pooling, let's try to do some basic benchmarks to see whether or not it improves our application performance.

### Playing Around with R2DBC Pooling Performance


There are multiple ways to load test our application, you can even use Apache Benchmark directly from your terminal with the `ab` command. But this time, I'd like to explore a tool called [K6](https://k6.10).

### Load Testing with K6


We're testing an API that will insert a hundred record into our database. This is going to be a write-heavy operation to stress the database.

### Without Connection Pooling


![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1633857332864/fSp5qR4EU.png)

Without connection pooling, we only get 140 requests completed, with the 95th percentile of 2.33s.

I also noticed that the docker instance responsible for running the database CPU usage spiked dramatically.

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1633857567481/7-W1vcZMIu.png)

## Implementing Connection Pooling in Spring Boot R2DBC


In Spring Boot application that use blocking connection to DB such as JDBC connection pooling is usually handled by a popular library called [HikariCP](https://github.com/brettwooldridge/HikariCP). Luckily, Spring Data R2DBC already includes connection pooling option that we can use just by enabling it from our `properties`.

To enable it, you can add below properties to your `application.properties` file and R2DBC will be able to pool the connections to our database! Easy right?

```other
spring.r2dbc.pool.enabled=true
spring.r2dbc.pool.initial-size=50
spring.r2dbc.pool.max-size=100
```


As you can probably guess, these properties will initiate the pool with 50 connections ready to use, and when needed it can scale up to maximum of 100 connections. Now then, let's try our benchmark again.

### With Connection Pooling


![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1636298632321/0mgyNDQeh-.png)

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1636298645768/nRAh5aGCD.png)

The result is striking. With connection pooling, we completed 480 iterations of the requests, increasing throughput by almost 3.5x and reducing our 95th percentile latency to 668ms, that's an almost 4x latency improvement! When we take a look at the docker instance, the CPU usage also stays comfy at around 76% usage. Enabling connection pooling improves the performance by almost 4x and reduced our database load significantly.

## Connection Pool Sizing


After seeing an awesome performance improvement above, you might be tempted to try and increase the connection pool even further. After all, if we can get 4x improvement with 100 connection pool, then we should get even better performance with 200 connection pool, right?

Sorry to burst the bubble but the short answer is no. If you'd like to learn further about connection pool sizing, please refer to this awesome article on pool sizing by the author of HikariCP himself: [https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing)

## Conclusion


We have learned how easy it is to enable connection pooling on an R2DBC project and its impact on your application performance. So don't forget to set it up whenever you're configuring your application!

As usual, you can see the source code for the project at: [https://github.com/kamalhm/spring-boot-r2dbc](https://github.com/kamalhm/spring-boot-r2dbc)