I would say that most cloud developers coming from web2 expect not just scalability, but having the complexities of that scalability abstracted away so that they can focus less on infrastructure and more on the business logic of their applications. The current architecture works for isolated or individual-centric applications like blogging/drive storage, but will struggle to support the web 3 generation of social media applications.
If I’m coming from web2 and have built a web application that’s geared towards hundreds of thousands to millions of users, I’m used to Firebase/FireStore, AWS, GCP, Azure - data storage that scales and API gateways that load balance, throttle, and auto-scale without breaking. Coming to the IC from the web2 world is a bit like running straight into a wall. Part of this is because the DevX (developer experience) of web2 managed services is just that good, but the other part of this is because of lack of ready-to-go IC solutions that developers can use to build their own automation and management tooling on top of. I think this will come in time as the developer built tooling matures, but for many developers (like myself) who were originally attracted to the IC by the promise of “infinite scalability” and “BigMap”, it was a bit of a let down to realize that this abstraction did not yet exist and we had to build our own data storage scaling solutions from scratch.
As @jzxchiang mentioned, a developer looking to prototype an application can move pretty quickly if that application is contained in single canister - one can go pretty far with 2-4 GB, but this eventually becomes a liability. Not just in terms of data storage, but also in terms of application throughput - a canister can only handle so many query and update calls per second.
This means that even in a multi-canister application, if a single canister is responsible for running a pivotal part of that application a high traffic or denial of service event could shut down most of if not the entire application. The start of some work to throttle requests with inspect_message
should help, but there’s still quite a bit of work to be done.
This throughput concern, plus the limitations with the current state of inter-canister calls make common architecture designs such as the API Gateway Pattern infeasible for the majority of application use cases, and has forced many developers to embrace client-centric multi-canister architectures when designing their applications. While this approach to scaling will “work”, it is not ideal to rely on the client as heavily as there is a limit on the amount of work the client (brower, phone app, etc.) can be expected to do and data it can be expected to store in local storage. Exposing the client directly to a wide variety of micro services also has security implications as it widens the attack surface to a particular application, vs. with the API Gateway pattern a developer just has to secure a single point of entry.
I believe improvements in the following areas would remove some of these barriers.
- Introduce a “load-balancing” scalability option to canisters that are pivotal in a multi-canister architecture, such as indexing, management, or transactional canisters that may need to handle high query or transactional (update) volume.
- Start long-term research into solving the performance issues with inter-canister calls, which could potentially mean re-architecting how inter-canister query and update calls work on the IC and breaking backwards compatibility. I think the IC can go pretty far with client-centric architectures, but when the data gets large enough, the client will eventually be overwhelmed without the capacity to do SSR or pre-computation with tools like Map Reduce on the backend. I don’t think that a patchwork solution to inter-canister query and update calls will suffice - we’d just be kicking the can down the road.
- Efficient canister forking/cloning of canister code and state/data will allow developers to easily re-partition the data in those canisters to scale out when a canister fills up and lessen the workload of the client application.
- Improve heartbeat. Building managed services on top of web3 infrastructure will eventually require some sort of cron-job/ heartbeat usage. Currently, heartbeat is pretty expensive for developers to use as it executes every heartbeat. DFINITY has suggested that the community build shared heartbeat canisters to “share the cost”, but this involves trusting other parties or entering into a DAO/SNS, which is way too much complexity for a simple cron-job.
Also, just speaking for myself, but I would appreciate if the marketing for the Internet Computer product and its presence as a new IT/cloud stack shifts to speak to the strengths that currently exist, and don’t use buzzwords like “infinite scalability”. Nothing scales infinitely (not even the centralized cloud providers), so providing specific metrics and data will give developers the confidence they need to an develop scalable designs and architectures for their applications.