Buying or upgrading Xamarin.iOS, Xamarin.Android or Xamarin.Mac?
Follow this link and get 5% off!

Bandwidth vrs Latency

From the "things that kicked me in the arse" files.

Everyone knows bandwidth. I have a 3 meg connection. you have 10meg. My phone has between 600k/sec and 2meg/sec depending on the cellsite. Whatever.

Most people (ie, me) tend to forget about latency, especially when coming from desktop apps, which are generally very low latency, to mobile, while are usually very, very high.

UPDATE: Juha said: "That’s a good blogo, but you haven’t explained why the latency issue munts TCP/IP connections." See the bottom for more info.

Background.

Bandwidth is how much data I can fire down a line in 1 second. This is how big my pipe is. If I have a 1meg connection, and I want to push down 0.5meg, it'll basically take slightly more than 0 seconds. If I want to push 2 meg down, it'll take 2 seconds. Etc. Pretty easy math.

Latency is how long it takes for data to get from A to B. This is usually the "ping" time, and measured in milliseconds (1000's of a second). For example, my "latency" to google at the moment is around 20ms. It takes 20ms to send something from me, thru teh internetz, to google, and back.

However, if you have 100MB/sec with massive latency (eg 5000ms), you connection is going to feel very, very slow. Web pages are going to take a long time to load, but if you want to download a very big file using multiple streams, ie bittorrent, it'll be very very fast. (Chances of this happening are low - high bandwidth is usually low latency)

Conversely, if you have a fairly "slow" connection - maybe 512k/sec (0.5meg/sec), but crazy low latency (say, 2ms), the connection will feel very very fast for some things, until you try to do a lot of things at the same time, and saturate the pipe (ie, push more than 0.5meg/sec)

Example: a carrier pidgin carrying a 32GB memory stick is high bandwidth (32GB!) but also very high latency (takes 10 days to fly from here to spain).  It's even slower if you want to move 32GB + 1 byte of data (ie, two trips)

The kick in the pants.

Developing desktop apps, you don't have to care about latency much. Most people are on a DSL connection, usually wired, so packets get to the destination very quickly.

Mobile apps are another story. It takes a while to move a packet from you to the cell site, and more time to get it off the carrier's network. Often, the latency is more the 2 seconds. This is why you can't do Voice over IP (or Skype) very well over a 3G connection, unless that network has been optimized for it (which I think the "3" network in the UK has). VoIP needs low latency or the voice breaks up.

Think about that for a second. On a 2meg connection (DSL or 3G) it takes maybe 1ms to move 100 bytes - so basically zero, because the volume of data is so much smaller than the available bandwidth.

But if that 100 bytes takes 20ms (0.02s) vrs 2000ms (2 seconds) to get there and back (latency), one of these is going to feel so much slower, as you can't do anything else until that data has finished moving.

Why this bit me in the arse.

I'm writing an app which talks to a remote server over HTTPS. This means that when I'm testing it - on my home network - my latency is very low. HTTPS adds a bit, but generally, it's small (<100ms).

Once it's on a device and on a 3G network, the latency jumps by 10x or 100x. So if my timeout is too low (the time before my connection gives up and says "this failed, took too long to reply, is anyone actually there?") - and it was too low - then things crash.

Worse yet: it works fine on 3G for me, as I'm in London which has fairly good infrastructure and fairly low latency. One of my testers is out in the sticks (I think) and most likely has very very high latency, so the chance of him getting timeouts is extremely high - so high is happens every time.

How I fixed it / found it.

The fix was easy - set the time out quite high (30 seconds). The finding was easy-ish, thanks to the Charles proxy, which lets me set the latency and bandwidth. Once I'd set it to a decent value (around 100k/sec, 1500ms latency), I could reproduce the problem, and the fix took about 5 mins.

Definitely something for mobile (iPhone, Android etc) developers to remember - test in the field! And speaking of, I'm off for a bike ride! (or should that be "off to test London Bike App")

UPDATE: why it "munts" TCP connections.

This is going to get techie :).

TCP is the protocol of the internet (well, Internet Protocol is (IP), but TCP sits on top). TCP stands for Transmission Control Protocol. It's often written as TCP/IP.

Basically, it controls the flow of packets, so there is a very good chance that if you send 4 packets - ABCD - you get ABCD at the other end, not CABD. Ordering matters. TCP can retry packets if some get missed. It's quite magic. The problem is, TCP usually waits for a reply, so it goes like like:

  1. Source: Hi!

  2. Dest: Hi back at ya!

  3. Source: here's a packet ("A")

  4. Dest: Thanks, got it, send the next one

  5. Source: here's a packet ("B")

  6. etc

This is a generalisation, btw. There are optimisations like the source sends 5 packets, and gets one reply with 5 "thanks, got it". But the general idea is solid.

Now, if you have low latency (say, 20ms), this will take 20ms x number of conversation lines, so in this case 100ms ( 5 x 20ms). If your latency is 2 seconds, it'll take 10 seconds to do the same thing. (5 x 2000ms). That feels SLOW. As the amount of data being moved is low, bandwidth is pretty much irrelevant here.

On the up side, if the destination doesn't reply (ie, something bad happens), then the source can retry. This is good as your packets will get there or not, and you will know one way or the other. It's a reliable connection.

There is also UDP (User Datagram Protocol) which also sits on top of IP (UDP/IP). UDP doesn't care about order. You can send 4 packets - ABCD - you may get DCBA, and UDP is just fine with that. UDP also doesn't wait for a reply. The source sends, and forgets. UDP is a unreliable protocol, however, so if you send ABCD, you may get ABD back. Or just A. Or even nothing. And the source will be none the wiser. In a lot of cases, this is just fine.

Satellite is a good example of something which works well in one case but not another. A satellite is very, very high latency - it takes a while for the signal to bounce off the satellite and come back down. But they are stupidly high bandwidth - most can take 100's of HD video streams. This is great for TV (who cares if the TV is 2 seconds behind the live game - as long as you can see it in HD!), but totally crap for internet (4 seconds to get one image off a website sucks if there are 100 images on the page!)