Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Driver Performance #1185

Open
Sydney-o9 opened this issue Mar 2, 2024 · 5 comments
Open

Driver Performance #1185

Sydney-o9 opened this issue Mar 2, 2024 · 5 comments
Labels

Comments

@Sydney-o9
Copy link

We are Neo4j cloud users and are measuring performance using Sentry.

Our backend application simply leverages the neo4j-javascript-driver to make calls to our Neo4j cloud db.

It takes almost 750ms for the driver to initialise and fulfil the request

Neo4j

I'm looking for ways to improve this, ideally would like to know how long it takes for:

  • the driver to be initialised
  • the request to Neo4j to fulfil
  • the parsing to be complete

Overall, I found the driver to be slow, but I have no proof, I want to measure this.

Can you give us ways to assess the performance of the driver in our application?

@Sydney-o9 Sydney-o9 added the bug label Mar 2, 2024
@Sydney-o9
Copy link
Author

Hi Team, if you could please give some indication here - that'd be appreciated

@bigmontz
Copy link
Contributor

bigmontz commented Mar 5, 2024

Hi @Sydney-o9,

the internal timings in the driver are not exposed, but you can troubleshooting by check:

import neo4j from 'neo4j-driver'

const mydbname = "the database name, usually 'neo4j'"
const driver = neo4j.driver(...)

// Check the timing for this request
// This one should just bootstrap the driver and do a handshake with the database
await driver.getServerInfo({ database: mydbname }) 


// Measure the time for running the query
const { records, summary } = await driver.executeQuery(query, params, { database: mydbname })

You an also check in the summary, the time the database get to consume the result (https://neo4j.com/docs/api/javascript-driver/current/class/lib6/result-summary.js~ResultSummary.html#instance-member-resultConsumedAfter), this can be useful for checking if the issue are in the query.

@bigmontz
Copy link
Contributor

bigmontz commented Mar 5, 2024

Could you inform also the NodeJS version, Driver version, Database version and some snippet to see what you're doing?

@Overdrivr
Copy link

Overdrivr commented Apr 5, 2024

Hello,
We're facing similar performance issues :

  • Our database is hosted on neo4j aura, in Francfort (we're in France) version 4.4 (we're facing the problem on 2 different DBs, staging and production, production db is 4x larger than staging)
  • We're using the latest version of neo4j-javascript-driver
  • node 18.10

All timings are captured around this snipped of code

export class Neo4jHelper {
  private driver: Driver

  constructor() {
      this.driver = neo4j.driver(
        neo4jAccount?.uri,
        neo4j.auth.basic(neo4jAccount?.user, neo4jAccount?.password),
        { disableLosslessIntegers: true },
      )
  }

  public async read(query: string, config?: TransactionConfig) {
    const session = this.driver.session()
    try {
      return await session.executeRead(tx => tx.run(query, config))
    } finally {
      await session.close()
    }
  }
}

A few examples that caught our attention, they are reproducible and don't appear to be some random variation. Almost all of our call exhibit the same patterns.

Example 1

The call to read took 700ms, to return the label of a single node.
Consuming the records themselves takes 0 time units (0 ms).

image image

Example 2

A slightly more complex query, that took approximately 2.4s to read() and returns about 2k records (with 10 fields each)

image

The query itself took 260 ms for records to be consumed, which leaves an overhead of 2.2s in the driver itself.

image

Questions

  • Is there something obviously wrong about our code above ? I haven't added the tracing code, but it just wraps the call to read, nothing else (and I've tried with an without instrumentation, top level timings are similar)
  • I initially suspected transport latency between our DB and my server, but the numbers are so large especially the second one, that it feels way off. Am I correct, or does this look like transport latency ?

@bigmontz
Copy link
Contributor

bigmontz commented Apr 8, 2024

The time measures reported in the resultConsumedAfter and resultAvailableAfter are calculated without taking in consideration any networking.

The driver itself take some work to bootstrap, so if you are creating a driver for each request, you will might have issues. Setting the database name in the session creation is highly recommend in the environments with high latency, since when the database name is not set, the driver will take an extra round trip to resolve the database name. In Aura, the database name is neo4j. So, you might create the session like:

const session = this.driver.session({ database: 'neo4j' })

The first request might get a bit more time because the driver will fetch the cluster formation before trigger the first query, but the next requests should be faster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants