Best Practices for Optimizing Canister Performance

Hi everyone,

I’m new to working with Internet Computer canisters and would like to understand how to optimize their performance for a scalable application. I’ve noticed some latency issues in my dApp during peak traffic times, and I’m wondering if there are any specific tips or best practices for:

  1. Efficient memory usage in canisters
  2. Managing inter-canister calls effectively
  3. Handling high volumes of user interactions

I have not found any solution. Are there any tools or techniques the community recommends for monitoring and debugging performance issues? I’m using Motoko, but I’m open to advice applicable to Rust as well.

Thanks in advance for any guidance or resources you can share!

It is recommended to use stable structure for stable memory. Serialization can be handled with the bincode crate, which helps manage stable memory securely and effectively.

For inter-canister calls:
If it’s a query request within the same subnet, consider using composite queries instead of a combination of update call + query.
For update call + update call, you can use the cdk’s spawn method or the future crate’s join_all method to reduce latency.

For handling a high volume of user interactions, when a canister processes many requests, the queue may become congested, leading to increased perceived latency for users:
• One solution is to use the compute allocation setting in canister configurations. This increases the probability of messages in the canister’s queue being executed within each execution round, thereby accelerating the processing speed and improving perceived latency.
•Alternatively, consider splitting operations across multiple canisters or subnets, which can reduce execution delays caused by operating within the same subnet.

For performance monitoring, the primary tool is the instruction counter API in the CDK. This API can analyze the number of instructions executed between two entry points.If the instruction count exceeds 5 billion, the ingress message will trigger Deterministic Time Slicing (DTS), effectively spreading execution across multiple execution rounds. This can also increase perceived latency. Reducing the number of instructions executed within a single update call can help lower latency.

You can find more information in this blog: