wezm.net/content/technical/2013/01/speed-up-slow-ios-downloads-with-proxy.mkdn

82 lines
4 KiB
Text
Raw Permalink Normal View History

Whilst developing the [Radiopaedia iOS app][radiopaedia-app] I ran
into the problem of very slow download speeds within the app. The app
has packs of content available for purchase and download. The download
speed was fine in the simulator but on the device it was painfully
slow<sup>1</sup>. Both the Mac running the simulator and device were
connected to the same Wi-Fi network. Profiling the code didn't reveal
any issues either.
[radiopaedia-app]: http://radiopaedia.org/articles/radiopaedia-ios-radiology-app
Some searching revealed people complaining about YouTube videos
downloading faster over 3G than Wi-Fi. There were a number of theories
and proposed fixes, including [people seeing faster rates when
downgrading their access point to 802.11b][80211b]<sup>2</sup> but I
found one particular article (that I can no longer find) that said the
power management in the iOS Wi-Fi stack interfered with download speeds
when communicating to a high latency destination over a high speed Wi-Fi
connection. For example YouTube servers in the US from AU<sup>3</sup>.
[80211b]: http://web.archive.org/web/20120511020134/http://qelix.com/blog/2008/08/31/get-better-wifi-speeds-on-iphone-3g
With this in mind I tested hosting the content packs on an Australian
server, instead of in Amazon S3 accessed via CloudFront. This showed a huge
improvement in download speed. At the time CloudFront didn't
have an Australian presence so we switched to hosting the packs on
RackSpace's CloudFiles, which uses the much more extensive Akamai CDN
and ensured that users of the app would have the best possible download
speeds no matter where they were.
<div class="seperator"><hr class="left">✦<hr class="right"></div>
Fast forward a year or so and I started managing podcasts on my phone
instead of via iTunes. I noticed that some of the podcasts I was
subscribed to were horrendously slow to download. Some would take hours
to download, particularly ones hosted a long way away, such as in the
UK or The Netherlands. I also noted that podcasts that used a CDN
downloaded quickly.
This seemed to be the same problem I had encountered with the Radiopaedia app.
I wondered if telling the iPhone to use a proxy on the local
network would work around the issue.
To test my theory I set up [Squid][squid]<sup>4</sup> on the Mac mini
that's connected to my TV. I configured the iPhone to use the proxy and
compared the speed with and without the proxy in use. You can see this
in action in the screenshots below.
[squid]: http://www.squid-cache.org/
In the first screenshot the phone isn't using the proxy. I have let
it download a third of the file to be well clear of [TCP's slow
start][slow-start] and it is estimating 57 minutes to download the
remaining 176.1 Mb (53 kb/sec). The second screenshot (only a minute
later) shows the result after I paused the download, changed the proxy
settings and then again let the download warm up a little. The estimated
time to complete the remaining 143.8 Mb is now only 5 mins (491 kb/sec)
-- a huge improvement.
[slow-start]: https://en.wikipedia.org/wiki/Slow-start
<figure>
<img src="/images/2013/01/podcast-download-without-proxy.png" width="320" height="480" alt="Podcast download without proxy" />
<figcaption>Podcast download without proxy, 53 kb/sec</figcaption>
</figure>
<figure>
<img src="/images/2013/01/podcast-download-with-proxy.png" width="320" height="480" alt="Podcast download with proxy" />
<figcaption>Podcast download with proxy, 491 kb/sec</figcaption>
</figure>
After the successful experiment I left the phone using the proxy and configured
launchd to start squid on boot:
<script src="https://gist.github.com/4521952.js"></script>
----
<sup>1</sup> Tested on iPhone 3GS and iPhone 4S.
<sup>2</sup> Original article linked from [Apple support discussion](https://discussions.apple.com/message/9564410#9564410).
<sup>3</sup> It appears there's YouTube end-points in AU these days.
<sup>4</sup> I installed squid using [Homebrew](http://mxcl.github.com/homebrew/).