| # Zircon Kernel IPC Limits | 
 |  | 
 | ## Introduction | 
 |  | 
 | The Zircon API is asynchronous for both sending and receiving. It requires that kernel buffers | 
 | data on behalf of the senders until receivers can drain it. If the total rate of sending data | 
 | is greater than the rate of reading the data over an extended period of time system can run out | 
 | of kernel buffers to service even critical tasks. | 
 |  | 
 | The experience is that for asynchronous systems that (in very rare occasions) return error codes | 
 | such as "try again", the application handling code is rarely correct; these paths are hard to test | 
 | and hard to get right: in particular the simple treatment of retry in a loop converts an | 
 | asynchronous service into a synchronous service, leading to livelocks and deadlocks. | 
 |  | 
 | Instead, when programming for Zircon, developers should assume that sending IPC messages at a | 
 | reasonable rate in a healthy system always succeeds. The kernel in turn implements some limits on | 
 | the amount of data it can buffer and when the limit is crossed, a | 
 | [policy exception](/docs/concepts/kernel/exceptions.md) is raised in the calling thread for the | 
 | following syscalls: | 
 |  | 
 |  - [`zx_channel_write()`] | 
 |  - [`zx_channel_write_etc()`] | 
 |  - [`zx_port_queue()`] | 
 |  | 
 | The precise limits are enforced per each instance of a kernel object and are not disclosed in the | 
 | form of constants to applications to prevent code from depending on these limits, which can be | 
 | further modified by product-specific considerations. | 
 |  | 
 | It is not expected that the application or library handles the exception; in most cases the | 
 | appropriate action so to let the exception propagate to the crash analysis service. | 
 |  | 
 | ## Strategies to Avoid IPC Limits | 
 |  | 
 | At a high level the main strategy is to equalize the rate of buffers being added and being drained | 
 | from each pair of consume and producer. There are many possible schemes such as flow control, | 
 | request/response, request-expiration, sidecar VMOs, etc. The most appropriate method depends | 
 | on the nature of the service. | 
 |  | 
 |  | 
 | [`zx_channel_write()`]: /docs/reference/syscalls/channel_write.md | 
 | [`zx_channel_write_etc()`]: /docs/reference/syscalls/channel_write_etc.md | 
 | [`zx_port_queue()`]: /docs/reference/syscalls/port_queue.md | 
 |  |