---
# System prepended metadata

title: 'SEE 08.06.2022 Notes - Performance, API, BFF...'
tags: [SEE]

---

#    SEE 08.06.2022 Notes - Performance, API, BFF...

## Overview / Current contex

We have an application where we rely on a monolithic GraphQL code-first server application written with nodeJS, typescript and nestJS. We have the following layers when querying our data:

![](https://i.imgur.com/74QKtnI.png)

We have recognized multiple problems on the server when querying the data via GraphQL:
   - our monolithic server scales per server, so the application isn't logically split per domain and if certain domain services are slow, they can't be scaled independently. GraphQL is query language, a standard, that can be used with anything behind the queries, mutations, field resolvers, and we haven't harnessed that power.
   - we are overfetching a lot of data on the client - we have a set, a `library` of generic queries that are reused in the application, backed up by GraphQL fragments. With that approach we don't construct fit-for-purpose queries that query only the required GraphQL data. An example below:

![](https://i.imgur.com/nFMvtWy.png)
![](https://i.imgur.com/1SKSmNQ.png)

   - we are using typeORM with multiple eager loaded relationships + repositories. The way we use the DAL, typeORM generates massive queries overfetching the data from the database - thus we have 2 times overfetching the data, once client-server via massive GraphQL requests, then through GraphQL - typeORM - DB through massively inefficient queries. Notice below the difference in execution times of these resolver fields + queries (real logs from production):

![](https://i.imgur.com/qsXoGvC.png)

   - we have some highly inefficient services
   - we have authorization service requests on each call, resulting in an extra call to the DB + very inefficient authorization service, slowing up the application massively
   - we are not caching any data, all our requests are going to the DB via DAL
   - we don't have an aggregated overview of our performance metrics
   - we query `all` when we need `n` entities
   - we don't have QoS quotas on k8s, meaning our services can be a victim of other `hungry` services, starving us of vital resources to make the application performant


## Goals of the meeting

   - discuss our approach and pain points
   - identify potential solutions
   - prioritize pain points / approach about prioritizing pain points
   - agree what's the `low hanging fruit` if there is any
   - evaluate solutions from all aspects

## Possible solutions

  - BFF (backend-for-frontend)
      - https://medium.com/tech-tajawal/backend-for-frontend-using-graphql-under-microservices-5b63bbfcd7d9
      - https://www.infoq.com/presentations/graphql-bff/
   - Dataloader
       - https://rahmanfadhil.com/graphql-dataloader/
   - Redis + memcache
   - Improved typeORM usage, smaller, fit-for-purpose queries
   - Different ORM, e.g. Prisma
   - Architectural split of the services per domain to enable horizontal scaling
   - Faster authorization service + cache? 




## Actions
  - Typeorm upgrade
  - Evaluate which queries / resolvers are the slowest
  - Evaluate performance on select x,y,z where ... in typeorm, instead of select * ...
  - elastic in production
  - spike: investigate useCallback / useMemo ?


## Agreements
   - [Andrew] to fill in...



###### tags: `SEE`