Troubleshooting latency
When a dapp or canister is running with a high amount of latency, there are some steps that developers can take to troubleshoot or optimize the performance of their canisters.
This document will detail some troubleshooting methods and performance optimizations that developers can use when troubleshooting latency.
Troubleshooting subnet latency
On subnets with low loads, query calls are answered in about 100 milliseconds and update calls are answered in about 2 seconds.
On subnets with higher loads, your application may experience elevated latencies or reduced accessibility. To get more information about the subnet your canister is running on, view the canister's information on the ICP dashboard. Look for subnet your canister is deployed on, then compare the number of "Million Instructions Executed Per Second" for that subnet to other subnets.
Recommendation: Consider moving the canister to another subnet.
If your canister is running on a subnet that has a consistently high load and thus elevated latency, consider adding a compute allocation setting. A compute allocation of 1% will guarantee your canister is scheduled for execution once every 100 rounds.
Troubleshooting best practices
Recommendation: Use query calls instead of update calls when possible.
Query calls are executed on a single node within a subnet and do not go through consensus, therefore they can be returned much faster than an update call. For some applications, query calls can be used in place of update calls to reduce latency.
However, the security trade-offs of query calls must be considered. Since query calls do not go through consensus, it is not recommended that they are used for retrieving sensitive information that requires data assurance. For example, returning financial data on a decentralized exchange dapp should not use basic query calls, as it is important the call return data that has been validated through the subnet's consensus. As an alternative, certified queries may be used.
Recommendation: Use efficient query calls.
You can improve the efficiency of query calls by:
Avoid using unnecessary calls to the
balance()
andtime()
system APIs.Utilize system API calls into places where their use is optimized.
Learn more in the improving query latencies blog post.
Recommendation: Request data from heap memory instead of stable memory.
Requesting data from heap memory instead of stable memory can reduce latency in some applications.
Recommendation: Skip inter-canister calls when possible.
Inter-canister calls are a slow operation since they use await
methods. Skipping inter-canister calls when they are not necessary can help reduce canister latency.
Recommendation: Follow canister best practices.
To assure that your canister is optimized, both for latency and cycles cost, be sure to follow the canister general best practices, which includes ways to implement efficient Motoko and Rust code.
Recommendation: To troubleshoot network latency, obtain the boundary node address and request IDs your canister is using before reaching out to the DFINITY team.
In order for the team to troubleshoot network latency, they will need the boundary node ID and, if possible, the request ID. This information can be found by looking in the networking tab of the developer tools. The boundary node address will be listed as Remote Address
and the request ID will be listed as the X-Request-Id
.