Neo4j Aura has a hard-coded 60-minute timeout for idle connections.
In addition, we have a keep-alive mechanism in place, which means any in-use connection will get a NO-OP message (probe) sent back from the server.
This is an attempt to stop network entities (NLB, some routers) from timing out in-use connections that appear idle otherwise.
Note: The keep-alive mechanism only works in official drivers of versions 4.3 and higher.
This would allow for connections to be kept alive even indefinitely.
However, the infrastructure of some of the cloud providers terminates connections older than 60 minutes or those that see no traffic for varying interval of time.
To accommodate this 60-minute limit, the connection lifetime should be set to something lesser than 60 minutes.
We recommend setting it to 50 minutes.
The exact driver configuration parameter varies between languages:
- Python: max-connection-lifetime
- Javascript: maxConnectionLifetime
- Java: withMaxConnectionLifetime
- Spring Boot:
spring.neo4j.pool.max-connection-lifetime
org.neo4j.driver.pool.max-connection-lifetime if you are using the Java Driver Spring Boot Starter - .NET : MaxConnectionLifetime
- Go : MaxConnectionLifetime
Connection Liveness Check Timeout :
Please be aware that connections between your client and our server may be terminated by other network components for various reasons, with the most common one being TTL.
If you face frequent SessionExpiredExceptions even after following the above recommendation, please check your application's infrastructure for low TTL values.
You could also make use of the ConnectionLivenessCheckTimeout driver configuration.
When the driver acquires a connection from its connection pool to execute a query or perform other operations, it needs to ensure that the connection is still alive and capable of handling the request.
The liveness check is performed by sending a lightweight request to the server and waiting for a response within a certain timeframe.
Pooled connections that have been idle in the pool for longer than this timeout will be tested before they are used again to ensure they are still alive.
- If this option is set too low, an additional network call will be incurred when acquiring a connection, which causes a performance hit.
- If this is set high, you may receive sessions that are backed by no longer live connections, which will lead to exceptions in your application.
- Value 0 means connections will always be tested for validity, and negative values mean connections will never be tested.
There are two options to handle session expiration on top of this:
On query failure caused by session expiry, you can:
- Either re-instantiate the driver object
- Or add a try-catch block.
Note: It is crucial to use idempotent Cypher statements if you are using retries.
Spring Data Neo4j has to be approached differently due to the way it handles transactions internally:
Using Resilience4j for retries in Spring Data Neo4j
Examples of the drive re-initiation and try-catch options:
- This is an example of re-instantiating the driver in Python:
# 1st time error does not occur
with driver.session() as session:
result = session.run("MATCH (a:Person) RETURN a.name AS name")
time.sleep(60 * 60)
# 2nd try, error will occur
with driver.session() as session:
result = session.run("MATCH (a:Person) RETURN a.name AS name")
# error should no longer occur
driver = GraphDatabase.driver(uri, auth=(user, password))
with driver.session() as session:
result = session.run("MATCH (a:Person) RETURN a.name AS name")
driver.close()
- An example of using a try-except block in Python:
driver = GraphDatabase.driver(uri, auth=(user, password))
sleep(60*60)
for i in range(2):
try:
with driver.session() as session:
result = session.run("RETURN 1")
except SessionExpired:
driver = GraphDatabase.driver(uri, auth=(user, password))
continue
Comments
0 comments
Article is closed for comments.