We have a service that uses graphQL. This graphQL file is parsed into an AST. It is a huge map (~7 Mb) that contains atoms, small binaries, lists, and maps.
The problem is that we have to analyse the schema every time a request comes to our server. So the AST gets copied to the process heap. For example, if we have 100 concurrent requests, it takes 700 MB of memory. We expect the schema to grow so it will be worse.
My question is, is there a better way to store the AST or any trick what we can use, to optimize the memory usage?
Thanks, we might write it back.
We used to use the persistent_term function, but the schema changes from time to time, so it drops the performance for seconds.
If the updates are relatively few and you’re okay with ”leaking” memory for a while, consider placing the schema under a new persistent_term key for each version (index it by an atomic or whatever). That way you can shift the cost of garbage collecting the old schemas until off-peak hours.
The way it works is that a request came to the server, we do different kind of traversal, find operations on the AST based on the graphQL request. Usually the same requests have been made to the server, so the result can be cached.
We used to use persistent_term but, when a schema changes we need to erase multiple items which kicks multiple gc on the vm.
We already using the schema versioning because we need to deal the request during the schema change. Now I just need to figure out the off-peak hours.
We do Graphql schema federation. In simple terms, basically different parts of the schema belong to a different services and we have to figure out how to execute based on the query and the given schema.
Could it be broken up into those sub-schemas and only the needed parts be loaded by each process?
A technique that could be a good fit (though I’ve not seen it used in some time) is to compile the data into a module, taking advantage of the literal pool. Updating a module is fairly expensive, but it doesn’t stop-the-world like persistent term does. The mochiglobal and fastglobal libraries are built around this idea.