NIO fail when writing more data than reading
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
In Java NIO, writing faster than the peer can read does not usually mean the API is broken. It means your code is hitting backpressure. A non-blocking SocketChannel.write call may write only part of the buffer, or even zero bytes, and if you ignore that fact and keep producing data, your outbound state eventually becomes inconsistent or unbounded.
Partial Writes Are Normal In Non-Blocking I/O
A core NIO rule is that readiness is not the same as completion. Even when a channel is writable, a single call may not flush the whole message.
If buffer still has remaining bytes after the call, you must keep that buffer and continue later. Throwing it away or assuming everything was sent is a bug.
Why Writing Can Outrun Reading
TCP already has flow control, but at the application level you still need to handle it correctly. If the remote side reads slowly:
- kernel send buffers fill up
- '
writebegins returning smaller counts' - eventually
writemay return0in non-blocking mode
At that point, your application has to stop pretending the data is gone.
A Correct Outbound Queue Pattern
A common NIO server pattern keeps a per-connection queue of pending outbound ByteBuffer objects.
This pattern keeps partially written buffers until they are fully drained.
Register OP_WRITE Only When Needed
In selector-based NIO, OP_WRITE should usually be enabled only when there is pending data to flush.
Then, after the queue becomes empty, remove OP_WRITE interest again.
If you leave OP_WRITE enabled all the time, selectors can wake up continuously because sockets are often considered writable most of the time.
Do Not Allocate Infinite Outbound Memory
If producers can enqueue messages faster than the network can send them, an unbounded queue becomes a memory leak under load. Real systems need a policy such as:
- backpressure to the producer
- dropping low-priority messages
- disconnecting slow clients
- bounding the queue per connection
NIO itself will not choose that policy for you.
Reads And Writes Are Logically Separate
Another common misunderstanding is expecting writes to succeed because reads are also happening on the same connection. Reading inbound data does not magically free your outbound pressure problem. Each direction has its own buffers and flow.
That is why a server can read perfectly fine while writes stall, or vice versa.
A Minimal Selector Sketch
The important behavior is not the exact boilerplate. It is the discipline of keeping unsent bytes until the channel can accept more.
Common Pitfalls
The most common mistake is assuming channel.write(buffer) sends the whole message. Another is discarding or reusing a buffer even though it still has remaining bytes. Developers also often leave OP_WRITE permanently enabled, causing wasteful selector wakeups. Finally, if outbound queues are unbounded, a slow reader on the other side can turn one connection into a memory pressure problem for the whole server.
Summary
- In non-blocking NIO, partial writes are normal and must be handled explicitly.
- Writing faster than the peer reads creates backpressure, not an API failure.
- Keep partially written buffers in a per-connection outbound queue.
- Enable
OP_WRITEonly when there is pending data to flush. - Bound your write queues or apply a clear slow-consumer policy.
Related reading
- Node JS discovering slow async calls
- Node.js maxing out at 1000 concurrent connections
- Node.js vs .Net performance
- Noisy training loss
- Non-intersecting line segments while minimizing the cumulative length
- Normalizing Rewards to Generate Returns in reinforcement learning
- Normalizing Rewards to Generate Returns in reinforcement learning
- Normalizing the edit distance

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.