Slow GraphQL querying with Realm (~27 sec response time for 15 results)

I’m developing a Vue.js web app and I’m noticing slow response times when accessing my Realm app’s GraphQL endpoint. For instance, querying a small collection named Accounts takes ~20-27 seconds to complete and returns ~15 documents with ~17 fields each using strings and ints for my field types: no document nesting. I am not using any relationships in this collection, either. I generated the schema from the existing documents that I’m using (all sample data).

Would anyone have any recommendations on how to improve query performance? Reducing the number of fields sent back only saved a couple of seconds (down to the lower-bound of ~20 seconds). I was expecting sub-second response time for a simple query on a very small collection, but perhaps I need to do something more.

Thanks!

EDIT: Here is my gql schema I’m using:

type Account {
  _id: ObjectId
  account_guid: String
  address_1: String
  address_2: String
  city: String
  company_name: String
  country: String
  created_at: String
  display_name: String
  id: Int
  modified_by: String
  modules: String
  phone: String
  state: String
  status: Int
  updated_at: String
  website: String
  zip: String
}

And here is the query I’m running (via axios) from my Vue app:

{
    accounts {
      account_guid
      address_1
      address_2
      city
      company_name
      country
      created_at
      display_name
      id
      modified_by
      modules
      phone
      state
      status
      updated_at
      website
      zip
    }
}

Here’s some additional information I was able to find:

  • It appears that the Realm function serving the GQL response is operating in US-VA according to the log entry.
  • My Atlas cluster and Realm cluster have been configured to operate in the US-OR region.
  • I’m getting the same slow querying speeds via Postman and GraphiQL (~23 seconds).
  • GraphQL queries on other collections run at about the same speed.

Are there any other things I can do to improve performance? Has anyone else noticed speeds this slow with their Realm-GraphQL endpoints? Using MongoDB Compass with our Atlas cluster performs well, as do our PHP and Node applications hosted on AWS EC2 and from my local machine. If Realm’s serverless functions and GraphQL hosting cannot perform reasonably well comparatively, then I’ll have to look for other backend-as-a-service providers. This is unfortunate as I had very high hopes for Realm.

Any clues/tips/suggestions would be very appreciated! Thanks.

Hey @Jason_Devore -

Do you mind sharing your schema and how’re accessing that data? Sometimes complex relationships might make queries slower and there might be ways to optimize how well your query is doing.

1 Like

Hi Sumedha! Thanks for replying. Here is the schema I’m using for my accounts collection. The GraphQL endpoint is serving a lot more than just this, but I cannot disclose it publicly as the application I’m working on is proprietary. To my knowledge, none of the other GraphQL types uses anything from the Account type and vice-versa.

type Account {
  _id: ObjectId
  account_guid: String
  address_1: String
  address_2: String
  city: String
  company_name: String
  country: String
  created_at: String
  display_name: String
  id: Int
  modified_by: String
  modules: String
  phone: String
  state: String
  status: Int
  updated_at: String
  website: String
  zip: String
}

input AccountInsertInput {
  display_name: String
  zip: String
  modules: String
  address_1: String
  city: String
  country: String
  status: Int
  modified_by: String
  state: String
  updated_at: String
  address_2: String
  phone: String
  company_name: String
  website: String
  created_at: String
  _id: ObjectId
  id: Int
  account_guid: String
}

input AccountQueryInput {
  phone: String
  state_lte: String
  modules_gt: String
  city_exists: Boolean
  _id_gte: ObjectId
  account_guid_gt: String
  address_2_ne: String
  id_lte: Int
  modified_by_in: [String]
  account_guid_lt: String
  company_name_gt: String
  website_in: [String]
  _id_gt: ObjectId
  display_name_lt: String
  website: String
  phone_nin: [String]
  zip_gte: String
  company_name_gte: String
  _id_ne: ObjectId
  display_name_exists: Boolean
  account_guid_nin: [String]
  created_at_lte: String
  created_at: String
  address_2_gt: String
  website_nin: [String]
  state_ne: String
  id_lt: Int
  address_1_nin: [String]
  id: Int
  _id: ObjectId
  created_at_ne: String
  state_nin: [String]
  status_nin: [Int]
  city_gt: String
  website_exists: Boolean
  _id_nin: [ObjectId]
  updated_at_lte: String
  city_lte: String
  status_gte: Int
  city_gte: String
  address_1_gte: String
  modified_by_exists: Boolean
  AND: [AccountQueryInput!]
  modules_nin: [String]
  phone_gt: String
  modified_by_lt: String
  modules_in: [String]
  city_lt: String
  address_1_gt: String
  state_gte: String
  modified_by_gte: String
  _id_lt: ObjectId
  modified_by_nin: [String]
  updated_at_gte: String
  updated_at_nin: [String]
  account_guid_in: [String]
  id_nin: [Int]
  modules_ne: String
  updated_at_gt: String
  phone_gte: String
  zip_lte: String
  modules_lt: String
  state_gt: String
  zip_nin: [String]
  company_name: String
  city: String
  city_ne: String
  country_in: [String]
  zip_in: [String]
  country_ne: String
  modified_by: String
  state: String
  website_lte: String
  address_2_gte: String
  zip_lt: String
  country_lte: String
  website_lt: String
  account_guid_lte: String
  OR: [AccountQueryInput!]
  zip: String
  website_ne: String
  city_nin: [String]
  id_gte: Int
  state_lt: String
  display_name_in: [String]
  phone_lte: String
  company_name_in: [String]
  company_name_lt: String
  modified_by_ne: String
  created_at_nin: [String]
  updated_at_ne: String
  address_1_exists: Boolean
  updated_at: String
  account_guid_exists: Boolean
  display_name_ne: String
  address_2_lt: String
  created_at_gt: String
  address_1: String
  display_name_gt: String
  modules_exists: Boolean
  country_gte: String
  display_name_nin: [String]
  created_at_lt: String
  id_exists: Boolean
  modules: String
  _id_in: [ObjectId]
  status_gt: Int
  country_gt: String
  zip_ne: String
  phone_in: [String]
  website_gte: String
  status_ne: Int
  status: Int
  address_1_in: [String]
  address_1_ne: String
  zip_gt: String
  modules_gte: String
  id_ne: Int
  country: String
  display_name_gte: String
  account_guid_gte: String
  display_name_lte: String
  modules_lte: String
  _id_exists: Boolean
  company_name_ne: String
  address_2_in: [String]
  address_2: String
  state_in: [String]
  updated_at_lt: String
  created_at_exists: Boolean
  address_1_lte: String
  id_gt: Int
  address_2_lte: String
  updated_at_in: [String]
  country_nin: [String]
  state_exists: Boolean
  updated_at_exists: Boolean
  address_2_exists: Boolean
  phone_exists: Boolean
  company_name_lte: String
  phone_ne: String
  modified_by_gt: String
  country_lt: String
  status_lt: Int
  created_at_gte: String
  zip_exists: Boolean
  account_guid: String
  id_in: [Int]
  status_lte: Int
  created_at_in: [String]
  account_guid_ne: String
  _id_lte: ObjectId
  phone_lt: String
  address_1_lt: String
  company_name_nin: [String]
  status_in: [Int]
  company_name_exists: Boolean
  modified_by_lte: String
  display_name: String
  city_in: [String]
  country_exists: Boolean
  status_exists: Boolean
  website_gt: String
  address_2_nin: [String]
}

enum AccountSortByInput {
  CITY_DESC
  STATE_ASC
  DISPLAY_NAME_DESC
  PHONE_ASC
  ZIP_ASC
  MODIFIED_BY_ASC
  ADDRESS_1_DESC
  COUNTRY_ASC
  DISPLAY_NAME_ASC
  STATUS_ASC
  ADDRESS_2_DESC
  MODULES_ASC
  WEBSITE_DESC
  STATE_DESC
  ACCOUNT_GUID_ASC
  PHONE_DESC
  ID_DESC
  CITY_ASC
  COMPANY_NAME_ASC
  ACCOUNT_GUID_DESC
  COMPANY_NAME_DESC
  COUNTRY_DESC
  UPDATED_AT_DESC
  ADDRESS_2_ASC
  CREATED_AT_DESC
  ZIP_DESC
  STATUS_DESC
  ID_ASC
  WEBSITE_ASC
  UPDATED_AT_ASC
  MODIFIED_BY_DESC
  _ID_ASC
  _ID_DESC
  CREATED_AT_ASC
  MODULES_DESC
  ADDRESS_1_ASC
}

input AccountUpdateInput {
  modules_unset: Boolean
  updated_at_unset: Boolean
  website: String
  id: Int
  status_unset: Boolean
  zip: String
  state_unset: Boolean
  created_at: String
  _id: ObjectId
  company_name_unset: Boolean
  updated_at: String
  id_unset: Boolean
  status: Int
  phone_unset: Boolean
  address_1: String
  modules: String
  account_guid: String
  city_unset: Boolean
  company_name: String
  modified_by_unset: Boolean
  website_unset: Boolean
  modified_by: String
  zip_unset: Boolean
  city: String
  display_name_unset: Boolean
  address_2_unset: Boolean
  status_inc: Int
  country_unset: Boolean
  address_1_unset: Boolean
  account_guid_unset: Boolean
  address_2: String
  _id_unset: Boolean
  display_name: String
  phone: String
  state: String
  country: String
  created_at_unset: Boolean
  id_inc: Int
}

UPDATE: I upgraded my cluster from 4.2 to 4.4 and removed all extraneous GQL schema defs. Now performance is acceptable: from ~20-30 secs to ~1 sec.

I’ll only expose my collections and their schemas/type definitions on an ad hoc basis for now on. Perhaps I’ll be able to identify which collections/schemas are weighing down the GQL endpoint. For instance, some of my schemas had 300+ field definitions for millions of documents. I bet some of those GQL schema defs could be weighing down the performance of the simpler schemas (like my Accounts schema).

Thanks!