Simulating EDGE and 3G Speeds

One of the more difficult aspects of testing iOS applications is ensuring that they behave in a reasonable manner on a slow connection. Setting up a “low bandwidth” environment normally requires the following steps: turn off WiFi on phone, disable 3G connection, build and run application on the device. This process requires a lot of upfront overhead which creates a disincentive to test slow connection speeds on a regular basis—putting you at risk of inheriting a lot of technical debt down the road.

Because we are Lazy Programmers we recognize tedious and repetitive patterns that waste our time and seek to rectify them. Using ipfw we can simulate slower connection speeds on our desktop and test our iOS app using the simulator.

Slowing your connection speed can be done by:

  sudo ipfw pipe 1 config bw 56KByte/s
  sudo ipfw add 1 pipe 1 src-port 80

Where “56KBytes/s” is the bandwidth and “src-port” is the port on which to throttle the bandwidth.

Restoring your connection speed can be done by:

  sudo ipfw delete 1

Of course, remembering these commands is not easy. So lets take another page out of the “Lazy Programmer” guide and abstract these set of commands using a script.

    slow_connection () {

      if [ -z $1 ]; then
        echo "Bandwidth must be provided"
        return
      fi

      default_port="80"
      sudo ipfw pipe 1 config bw $1KByte/s
      sudo ipfw add 1 pipe 1 src-port ${2:-$default_port}
    }

    edge_connection() {
      slow_connection 56 $1
    }

    3g_connection() {
      slow_connection 200 $1
    }

    alias restore_connection="sudo ipfw delete 1"
  

The above script allows you to simulate EDGE, 3G, or any connection speed. You can also provide a different port to slow your connection speed; it defaults to port 80. The bandwidth chosen for the 3G and EDGE networks were taken from here and here and are not guaranteed to be accurate.

Update

You can also simulate latency and packet loss via ipfw which would better represent the EDGE network. For example:

sudo ipfw pipe 1 config queue 30 delay 700ms
sudo ipfw pipe 1 config plr 0.1

Where the “700ms” represents the latency and “0.1” represents 10% packet loss and “30” represents the weight of incoming packets, which share the bandwidth of the pipe they are connected to proportionally to their weight.

Conversation
  • You can be even more lazy after installing the rather handy “Speed Limit” preference pane.

    https://github.com/mschrag/speedlimit

    I have my own fork (out of date) that adds percentage of random packet loss to the mix too.

    https://github.com/protocool/speedlimit

  • Trevor, that is cool. I’ll check it out.

  • Rick says:

    Why not just tether your iphone to your computer? Then you would get ACTUAL 3G/Edge speeds

  • Steve Hanov says:

    An important part of a cellular connection is the first-packet latency. After a five-second pause with no data, things shut down and it can take around a second to start things up again. And then, the data transfer rate slowly increases to the max.

    Is there a way to simulate that?

  • Steve,

    Great question. I quickly glanced through the ipfw documentation (man ipfw) and I couldn’t find anything about supporting upfront latency for one packet.

    My inclination would be to create a temporary queue that is weighted at 100 with a delay of 5000ms and the re-configuring that queue with a normal delay.

    It would be tricky to do however.

  • Simone Hackly says:

    I would configure an echo path with a recombinant delay quotient. This simulates the elasticity of packet shaper.

  • Comments are closed.