All tests run on an 8-year-old MacBook Air.
You're transferring a batch of large files over MTP. The first one flies at 45 MB/s. Then the second file starts — and you're at 30 MB/s. The third is slower still.
Nothing changed. Same cable, same device, same app. So what's happening?
The Cause Is in the Protocol Itself
Between every file, MTP requires a full negotiation cycle — SendObjectInfo followed by SendObject. This isn't an implementation detail you can optimize away. It's how MTP works.
During that gap, a few things happen in sequence:
- The Android device's flash controller is still committing the previous file to storage
- The USB pipe is flushed and re-established for the next object
- The device's MTP stack is processing metadata before it's ready to receive data again
The result is a speed dip at every file boundary. The longer the previous file, the longer the device needs to catch up.
What I Tried
Building HiyokoMTP, I went through the obvious candidates:
- Tokio thread pool exhaustion — sync Read/Write calls blocking async threads were a real issue. Fixing it improved overall stability, but didn't eliminate the inter-file dip.
- Chunk size tuning — adjusting the USB bulk transfer buffer (up to 4 MB per chunk) helped peak throughput, but not the boundary behavior.
- Intentional cooldown between files — adding a short pause actually helped in some cases, giving the device's flash controller time to breathe before the next transfer starts.
Why It Can't Be Fully Fixed
The inter-file overhead is structural. MTP was designed as a stateful, command-response protocol — not a streaming pipeline. Every file is a discrete transaction with its own negotiation. There's no mechanism to pre-stage the next file while the current one is still writing.
Non-async bulk transfer pipelining (similar to io_uring or Zero Copy USB) could theoretically reduce this, but it would require deep nusb-level changes and device-side support that most Android MTP stacks don't expose.
MTP vs ADB: A Fair Comparison
It's worth comparing MTP to ADB push, since both are common transfer methods:
| MTP | ADB | |
|---|---|---|
| Peak single-file speed | Fast | Moderate |
| Inter-file overhead | Higher (protocol negotiation) | Lower |
| Batch transfer efficiency | Drops between files | More consistent |
ADB has lower overhead per file, but its raw transfer speed on large single files tends to be slower than MTP. Neither is universally better — it depends on what you're transferring.
The inter-file dip is unavoidable, but HiyokoMTP minimizes it to the extent the protocol allows. If you're hitting this wall, you're not doing anything wrong — MTP just works this way.
One-time purchase, no subscription.
→ https://hiyokomtp.lemonsqueezy.com/checkout/buy/2e966b64-554e-42a0-b865-4240281978a1
Have you found a way to squeeze more speed out of MTP batch transfers?
























