Device Bandwidth/Data usage

How low can we go?

At resin.io, connectivity plays an important role. In order to provide our users with a clear view of their devices, the resin device Agent constantly keeps our API informed about the devices' conditions and applies any changes, like downloading new application updates or environment variable changes by negotiating with our API.

While a quick reflection of actions is great during development, it comes at a cost of increased data usage. Some of our users running devices in environments requiring extreme control of data usage requested a few levers to reduce the consumption.

In the beginning there was ...

We started our journey to get the usage as low as possible by measuring data consumption of resin.io-powered devices.

Measurement procedure:

  • A separate ethernet network with only a Raspberry Pi 2 and our measurement computer.
  • A Raspberry Pi 2 was provisioned before the start of the measurement with no running application.
  • Data was logged for a duration of 30 minutes after the device appeared on the dashboard.

Initial Results

We were consuming about 678MB/month in the default state which indicates an average usage of 275 bytes/second

The approximate breakdown by components used by Resin was as follows:

Data_Usage.png

Lets break down the usage per request and per second so that we can better understand whats going on.

Service Usage (Including DNS overhead)
API poll (Once per 60s) 6650 Bytes per request
Resin Agent update poll (Once per 300s) 6693 Bytes per request
VPN enabled 43 Bytes / second
TCP check cost (When VPN disabled) 47.36 Bytes / second
NTP 0.08 to 5 Bytes / second

We quickly realized that we weren't using Pubnub Pings for devices' online state, so we turned those off, shaving 58MB. We also changed our connection checking logic to assume that VPN connectivity meant there is no need to do additional connectivity checks, shaving off another 93MB. The total usage now was dropped to about 527MB per month.

Why do we poll our API with device state?

We poll our API to work around networks that block VPN and also to mitigate any timing issues causing a push via our VPN to be missed by a device. While a 60 second poll allows for a consistent device responsiveness to updates, some of our users expressed a need to have the devices check-in only once a day.

Resin Agent (Supervisor) update poll

We love redundancy at Resin. Our Resin Agent update poll allows us to update the Resin Agent on the device and also ensures that we recover if it crashes for any reason - including a botched Agent update. We realized that a 300 second poll was an overkill and changed the poll duration to 24 hours.

Why do we run a VPN?

Devices on resin.io are connected via VPN to our servers. Running VPN on the devices enables us to access devices behind complicated NAT setups and provide Device URLs. While this is a great feature for most of our users, users with bandwidth constraints requested an ability to turn off the VPN.

Levers

In order to give our power users control over data flow we enabled a few RESIN environment variables.

Variable Allowed Value Action
RESIN_SUPERVISOR_VPN_CONTROL true/false Enable / Disable VPN
RESIN_SUPERVISOR_CONNECTIVITY_CHECK true/false Enable / Disable connectivity check VPN is disabled
RESIN_SUPERVISOR_POLL_INTERVAL 60000 to 86400000 Resin API Poll interval in milliseconds
RESIN_SUPERVISOR_LOG_CONTROL true/false Enable / Disable logs from being sent to Resin

Side-effects/Warnings

RESIN_SUPERVISOR_VPN_CONTROL: This defines the ability to send instantaneous updates to the device. Turning off the VPN means that any application or environment variable update is reflected only when the device polls for these changes. The Web Terminal does not function when the VPN is disabled.

RESIN_SUPERVISOR_CONNECTIVITY_CHECK: Defines the device's ability to test and indicate (via an LED when available) that it has issues with connectivity.

RESIN_SUPERVISOR_POLL_INTERVAL: This defines the time interval when any changes made to the application, i.e either new code pushes or environment variables changes or VPN control changes are propagated to the device. Think of it as the interval when the device checks in with Resin API to ask for new updates. Making this interval long, would mean that any change is only reflected in the device after this interval, if the VPN is not operational. (We suggest limiting this to less than 24 hours)

RESIN_SUPERVISOR_LOG_CONTROL: Any logs written by the user container or the device Agent are not sent to the dashboard when this variable is set to False.

Conclusion: How low can we go?

Down to approximately 1.3 MB of usage for 30 days.

The following settings tune the data usage to the lowest possible number:

  • Disabled VPN
  • Disabled CONNECTIVITY CHECK
  • Change POLL interval to 24 hours
  • Disabled LOGS

Out of this 1.3 MB approximately 0.4 MB is used by Resin and 0.90 MB is used by NTP to keep the clock in sync. Having a battery-backed RTC and reducing the frequency of NTP sync could further reduce the usage. Since most of our users have devices that are not battery-backed, we decided to not reduce the NTP sync interval.

We love the constant feedback from our users that makes us push our stack to the limits. We would love to hear your suggestions and thoughts; leave us a comment or come and chat with us on gitter!

comments powered by Disqus
Terms of Service | Privacy Statement | Master agreement | Copyright 2019 Balena | All Rights Reserved