Never knew that additive changes could also be breaking. Nice one. Thanks for sharing!
HN user
tusharmath
Hello!
We've conducted benchmarks across various GraphQL backends and discovered that Hasura is performing significantly slower than its counterparts. We want to ensure the accuracy of these results and are eager to collaborate with Hasura experts to explore potential improvements. Could we discuss strategies to optimize Hasura's performance in our benchmarks? Looking forward to your expert insights.
P.S.: Please focus on the constructive aspects of these benchmarks, as they specifically test a feature present in Hasura, which is marketed to deliver "fast" GraphQL APIs on top of any data source.
My response to the blog above
https://blog.tailcall.run/writing-a-graphql-backend-by-hand-...
Looks interesting. Im building:
I wanted to integrate a better UI for our GraphQL playground. If you are open for a collab, send me a DM on LinkedIn in.
Hopefully this sums it up
Must Have:
- Strong understanding of GraphQL and related technologies.
- Previous experience in a developer relations, advocacy, or evangelism role.
- Proven ability to present technical concepts in a clear and engaging manner.
- Active participation in relevant tech communities.
Nice to Have:
- Experience with Rust or other modern programming languages.
- Familiarity with web proxies, networking, and related technologies.
- Established online presence (e.g., on GitHub, Twitter, blogs).
- Contributor to Tailcall - https://github.com/tailcallhq/tailcall
Additional Requirements:
- Passionate about connecting with developers and understanding their needs.
- Positive attitude towards collaboration and community building.
- Self-driven and adaptable to the evolving needs of the project.
Share your linkedin/twitter profile here and we will connect with you.
With Tailcall, you could compose API over multiple any of the following formats REST, GraphQL, and GRPC APIs to create a unified API endpoint. This could also be any of the above. So you could expose a set of REST endpoints atop, multiple GRPC APIs, where you are not just doing basic translations, but also sophisticated data transformation that has business logic inside it.
Actually, you might want to check out https://tailcall.run (Disclaimer: I am the core maintainer of the project)
It's an open-source API Orchestrator, in other words "a Zapier for APIs". If you find it interesting, hit our discord channel to learn more about it.
What are you using for GraphQL?
Tailcall is building something similar in that regard. The idea is to allow developers to specify their orchestration requirements using a DSL and then behind the scenes generate an ultra high performance backend for GraphQL. The query could span over REST, GRPC and other GraphQL services. Check it out — https://github.com/tailcallhq/tailcall
This sure seems very interesting. Have you written the GraphQL layer by hand? Have you tried https://github.com/tailcallhq/tailcall
With tailcall, you can quickly bootstrap a GraphQL service on top of existing APIs. I would love to collaborate on this and help you on board.
It's open source and free. Use it if you like what it offers.
Disclaimer: I am not promoting it, I am just stating facts :)
Yes, that is the best time to build a GraphQL API. It will save you many hours later. Like it or not, eventually if you are building a mobile app, you will move to GraphQL eventually. It's a massive pain to do it when you have everything running. GraphQL will save you from embarrassing errors on the client and improve performance for sure. My recommendation is — Build API and expose them using REST or GRPC. Use a solution like https://tailcall.run/ to create a GraphQL facade on top of it for your clients to consume.
I am not sure if I understand what you by the "frontend server"? I think Tailcall is closer to AppSync than Amplify.
Second part of your question: You can define a set of "allowed headers" that will be automatically forwarded upstream. In your case, you can set the allowed headers to `Authorization`.
Link to the doc:
The idea of tailcall is to move the graphQL abstract closer to the client. So for example, if you are building a web application, you don't need to depend on the backend teams to build a GraphQL implementation for you. You should be able to use the tailcall DSL and express your orchestration requirements using it. The DSL looks like a normal GraphQL file so there is no new language to learn. Because this file is for the client, it can be literally in the same repository as the client, effectively ensuring the GraphQL server and the client are always on the same version. A simple git ops is then implemented, to auto-deploy the orchestration logic and release the mobile application simultaneously.
Because you have a DSL to represent the orchestration logic, you can introspect how the orchestration would happen even before your server starts. So you can apply lint rules on the configuration, and also a ton of ahead-of-time optimizations. You can also identify n + 1 upfront, restrict them in certain cases, and allow for others. Moreover, you don't need to think about the performance and maintenance of this service. Once deployed on your/our infra, every time there is a configuration change, we just perform a reload and within seconds it is updated across the infrastructure.
This is a fundamental shift from how graphQL is maintained traditionally. It gives backend engineers an opportunity to think in terms of orthogonal APIs or migrate from monolith to microservices etc. without worrying. Secondly, it gives frontend engineers the power to design the schema that makes sense for them, without writing any code or being on-call for any outages.
Have you considered using https://tailcall.run It can automatically create a high performance graphql API.
If you are a cranelift expert and have worked with compilers wasm using rust we have something that might interest you. Just send us your prior work with cranelift to jobs at tailcall.run and we will get in touch.
Tailcall is a no-code solution for writing GraphQL backends. It is heavily focussed on building a high-performance implementation that can make GraphQL practical for service to service communication. Tailcall does a lot of AOT optimizations to get performance that's practically very hard to achieve while writing code by hand. You will clearly see in the benchmarks above that it's only slower than static rust.
Have you tried https://tailcall.run/ It's a fairly powerful and performance focussed solution to building GraphQL backends.
The configuration that is provided by the user, is text, however it's parsed into an AST, then converted into a low-level implementation called the blueprint. The hash is that of the blueprint and is free of any whitespaces or textual changes.
Writing your own backend for GraphQL doesn't scale. You should stick to no-code solutions that can auto generate graphQL on top of existing APIs. Checkout https://tailcall.run
The iframes can share service workers if they are all on the same origin. I would recommend using a service-worker which intercepts every graphQL request and caches on that layer. You can do a lot more on that layer once it's setup. For example — Enable batching, Rate limiting etc.
What's wrong with GraphQL? "CAN-OPEN-WORMS-EVERYWHERE"
The reasons mentioned above is exactly why we started Tailcall.
https://github.com/tailcallhq/tailcall
GraphQL community is quite small and fragmented. Mostly composed of frontend engineers who are focused on improving dev-ex with APIs.
It would benefit the ecosystem, if people with a system's background or platform engineering background could get involved. Fix various aspects of performance, security and maintenance.
Checkout our benchmarks — https://github.com/tailcallhq/graphql-benchmarks
We haven't even scratched the surface of what we can achieve in terms of performance. Our goal is to build something like Nginx or Envoy but on top of GraphQL protocol. With an ability to design your own plugins and extend it's capabilities. Would love to get some feedback from the community.
https://twitter.com/Dream11Engg?s=09
This is the new link. Some how the old link doesn't work if you have the app installed.
At Dream11 we love GraphQL :) It has made the lives of both — service owners and clients (Android, iOS, Web) much easier!
Over the years we had packed the server with almost all the graphQL optimizations we could find on the internet. The blog outlines some of the key optimizations we had put in to improve the performance of our application code (Which doesn't have a lot to do with GraphQL, as most people have already commented). I want to still give a bit of an "insider's perspective" as much as I can, so here it goes —
1. The graphQL team that did the optimizations had two engineers who were actively working on it. It seemed like a futile project at first. The goal was to find low-hanging fruits (if any) and prepare for our peak season (IPL 2021) but eventually, find other long-term alternatives. Killing graphQL altogether and moving that logic on the clients was still on the table. Fortunately, the team did a fantastic job of optimizing it so much that we are now committed to supporting it long-term.
2. We try to keep our microservices as discrete, pointed, and as unopinionated as possible. We also indulge the clients by letting them query huge amounts of data at once. All this makes our graphQL layer seriously complex. There is a huge amount of computation that happens on this layer. To get some perspective our /health call to the server is 10x faster than the most requested graphQL query. Needless to say, it's not a fair comparison because unlink the query, health doesn't make any network calls, or has any practical CPU load.
3. We have caching implemented on our graphQL clients, however, the reason we get such a high request rate, is because our concurrency is also very high. A typical user is barely making 10 requests in a minute but overall we achieve millions of requests in a second.
4. As a part of the long-term strategy, we did consider using Rust as our choice of the stack. We had heard a lot of noise about how RUST was beating all the benchmarks. So we did some POCs internally and implemented a part of our graphQL service in Rust. What we learned was that the Rust implementation was ~2.5x faster than our node.js implementation and also consumed relatively less memory. This was fine but wasn't good enough for us to migrate our large node.js codebase, and learn a completely new stack. Building a team with domain expertise in Rust in India is particularly hard.
5. It might seem like we are not pushing the production servers hard enough, you'd be surprised to know that it's true! Because our traffic is very unpredictable we like to maintain a comfortable CPU utilization for every possible extreme scenario that our Data Science team can predict. The risk of our edge layer going down is seriously revenue hitting. So even when our benchmarks say we can push the systems 5x more, the final call remains with Site Reliability Teams and the risk appetite we have for that particular game.
6. The blog briefly also talks about using multiple ELBs, to which we distribute traffic using DNS. The problem with DNS is that it doesn't guarantee a truly uniform distribution of the traffic. Even with a very low TTL, sometimes we observe a difference of more than 20% in requests/sec between two ELBs at an instant. This and other infrastructure-specific nuances have to be considered by the SRE teams to estimate capacity on production.
7. Lastly, the servers we use on production are small machines — 8 cores for the majority of our stack. This lies in the goldilocks area where we get the best cost to performance ratios. Scaling down or up the machine type has a significant impact on the cost.
It's been a journey of love and hate with graphQL and we continue to invest in making our edge robust and even faster. Feel free to connect with us on — https://twitter.com/D11Engg