Making a picture paste fast made my typing slow
Pasted pictures took 40 seconds or more to reach an agent on another computer. My fix was as fast as SSH. Then every keystroke had to wait behind it.
Once, someone pasted the same picture ten times. Six minutes later, ten copies arrived.
The picture was for a coding agent that ran on another computer. For a long time, nothing showed up. So they pasted again. And again.
On 3 November, I made my app, Kodosi, carry the picture itself. It moved as fast as an SSH copy. Then I noticed my typing. Every keystroke now waited behind the picture.
If you send big files over a connection that people also type on, you will meet this problem. The hard part is deciding how much to send at once.
The picture took the long way
In Kodosi, a terminal often runs on another computer. It can be my own computer at home, or a friend’s. The agent in that terminal reads the clipboard of the computer it runs on. But I press paste on my laptop.
So the picture had to cross over some other way. It went through the operating system’s own clipboard sharing. That took 40 seconds or more. Kodosi couldn’t see it, so the screen showed nothing while it happened.
Carrying it myself
The new way is in one pull request. My laptop cuts the picture into pieces of 32 KiB. It sends them through the terminal’s encrypted channel.
The other computer saves the picture as a file and pastes the file’s path. The agent opens the file from there.
While the picture travels, the terminal shows how much of it has arrived. A second paste of the same picture sends nothing more.
I tested it between a Mac and a Linux computer over the internet. It was a normal home connection, with about 9 Mbit/s of upload. A round trip took 70 to 93 ms.
At that speed, 13.4 MB can’t move in much less than 12 seconds. A 13.4 MB picture took 12.78 seconds. An SSH copy of the same file took 12.99. The link was the limit.
Then my typing slowed down
In a terminal, the letter you type shows up only after the shell sends it back. That’s called the echo. On that link, with nothing uploading, a keystroke echoed in 0.07 seconds. That’s about one round trip, as good as the link allows.
During the upload, the echo took 0.44 to 0.71 seconds. I was typing in a different terminal. My keystrokes waited anyway.
Since October, all the terminals of a device share one connection. So a keystroke for any terminal travels in the same queue as the picture.
How much to send at once
To keep a link busy, a sender keeps some data in flight. That’s data it has sent, but the other side hasn’t confirmed yet. Data in flight is either moving on the link or waiting in a queue on the way.
The first version kept as much picture in flight as the link carries in half a second. It copied the rule Kodosi uses for terminal output. On this link, that was six times more than the link needed to stay busy. The extra waited in a queue, and every keystroke waited behind it.
Network engineers have a name for a queue like this: bufferbloat. I had met it once before. In October, on a test link of 128 kbit/s, a Ctrl-C took up to 3.6 seconds to show. It sat behind output that was already on its way.
So I cut it down. The upload now keeps as much as the link carries in two round trips. It never keeps more than half a second.
One round trip of data keeps the link busy. The second is a margin, so the link never waits. A keystroke now waits behind about one round trip of picture.
The fix that lasted three seconds
For the first 3 seconds of the upload, typing kept up. Then it slowed again. The echo crept back to 0.40 seconds and more.
To know how much two round trips is, my laptop measured the link’s speed. It timed the confirmations that came back from the other computer. On this link, the confirmations arrived in clumps.
A piece sent right before a clump got credit for the whole clump. So the link looked faster than it was. The code keeps the highest speed it has seen. One bad reading was enough to let half a second back into flight.
I fixed it twenty-four minutes later. Now the other computer stamps each confirmation with the time it got the bytes. My laptop works out the speed from those stamps. Clumps on the way back can’t change them.
| Nothing uploading | 0.07 s |
| Half a second in flight | 0.44 to 0.71 s |
| Two round trips, my laptop's clock | 0.40 to 0.46 s |
| Two round trips, the other computer's clock | 0.17 to 0.25 s |
What I’d tell you
Size the queue in round trips. Half a second sounds short. On that link, it put six round trips of picture in front of every keystroke. Two round trips keep the link busy and cost a keystroke about one.
Measure speed where the data lands. My laptop saw the confirmations in clumps. The other computer saw when each piece arrived.
Show the wait, or people repeat it. Ten pastes became ten pictures because nothing moved on the screen. Now the terminal shows how far the picture got, and a second paste sends nothing.
Where it stands
Ten pastes of one picture now make one upload. A 4.9 MB picture pasted ten times arrived in 5.73 seconds, as one file. While a picture travels, a keystroke echoes in 0.17 to 0.25 seconds. That’s still slower than with nothing uploading, because each keystroke waits behind one round trip of picture.
Two things are still open. Text you type while a picture travels reaches the agent before the picture’s path. And nobody has tried picture paste in the iPhone or Windows app yet.