sfackler / rust-postgres

Native PostgreSQL driver for the Rust programming language
Apache License 2.0
3.42k stars 436 forks source link

What the most performant but still safe way to use tokio-postgres? #1091

Closed greg-nagy closed 7 months ago

greg-nagy commented 7 months ago

I am in the middle of running a small performance test on different technologies and stacks. https://github.com/greg-nagy/framework-test-at-home

I have looked at the the axum implementation in the tech empower test and also the axum example

I have created 3 implementations based on these:

The recommended way is to use tokio-postgres with a connection pool. On the other hand tech empower test implementation uses a single connection shared through an arc per thread Using bb8 for connection pooling reduces the throughput significantly. (2912 req/sec vs 8038 req/sec)

Is there any downside of using a shared tokio-postgres connection like that? This question can also be phrased as: What is the behavior of tokio-postgres if multiple queries are sent to the same connection? I would expect the lib to handle such situations, but haven't checked the code yet.

Is there an official recommendation on the usage of tokio-postgres?

sfackler commented 7 months ago

Some things to look out for when sharing a connection across tasks:

  1. Transactions will not behave properly. Do not use them.
  2. Queries are processed sequentially in order. If one task's query takes a while to process, it may cause other tasks to be slower than they would normally be as their requests queue up behind it.

If you are working on a real system that needs to work in the real world, you should absolutely use a connection pool. Tech Empower benchmarks are ~completely detached from the real world.

greg-nagy commented 7 months ago

Thanks for these thoughts!

I am suspicious that something is off with connection pooling. I would not expect it to cause a ~3x slowdown.

Do you have a recommendation for connection pooling that works well with tokio-postgres?

sfackler commented 7 months ago

There are some configuration options like https://docs.rs/bb8/latest/bb8/struct.Builder.html#method.test_on_check_out you could look at, but that is more of a question for the bb8 developers.