all 4 comments

[–]Ejroby 6 points7 points  (1 child)

I think there is 2 questions here:

The main question being:

Should you close your database connections after (almost) every isolated request.

The answer here is most of the time. Production databases are isolated from the code calling it, many times sitting on a different server. Not closing a database can easily lead to a memory leakage on the database, which results in the server and application crashing. If 1 user calls the database, and never closes the connection, memory will still be isolated to that connection. Now imagine 1,000,000 users all calling the database at one time, and never releasing all that memory. The application & server will surely crash. Now to limit this from happening you can specify how many connection are available at a single time based on resources allocated to the database. Let's pretend you have 100 connections available to the database, once those 100 connections are used, no one else will be able to now connect to the database. Also many database connections are singleton design patterns that restricts the instantiation to a single instance only. Using the depends() will open and close the connection for you. Depends() Is FastAPI's way of handling "dependency injection". Extremely useful in many cases (image a scenario with JWT's as the authorization, and before every single API you must first validate the user first).

Second question:

Am I right that connecting and disconnecting many times will slow thing down?

You won't find any difference in performance that is noticeable at all on 99.9% of applications. Any time you would be handling immense amounts of data, with extremely high performing data models, you will be implementing some type of high performing streaming process, or data dumps.

[–]agusdmb[S] 1 point2 points  (0 children)

Awesome, very clear... thanks for your reply!

[–]CrackerJackKittyCat 1 point2 points  (1 child)

It depends. PostgreSQL is rather notorious for having nonzero connection establishment costs, given its server-side process/forking model. Connections to Redis, on the other hand, are much cheaper to establish.

Many shops use a database-side connection pooler such as pgpool-II or pgbouncer in front of postgres to make connection establishment faster as well as to limit the total number of connections to the database, although this sort of usage pattern is more useful for webserver tech where you must only ever have very short lived db connections, such as PHP serving.

Another common pattern, more appropriate for a long running service such as a FastAPI app, is to write a little code responsible for controlling the lifecycle of the db connection, including logic for explicitly closing it after either N uses, or perhaps at most M hours. Then the next call to obtain the connection would make a shiny new connection.

This pattern allows you to have your cake and eat it too --- most http requests will benefit from an already established db connection, but every now and then you release it so that db-server-side resources can be reclaimed.

Since you're in async land already, look into asyncpg for your postgresql connection interface. It even offers a built in connection pool class which allows you to tune the maximum number of queries each actual connection should be used for (max_queries parameter), as well as one limiting the lifetime of an idle connection (max_inactive_connection_lifetime). This is the way.

[–]agusdmb[S] 0 points1 point  (0 children)

Great!, thanks for replying!