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.
- 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.
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:
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.
In order to give our power users control over data flow we enabled a few RESIN environment variables.
|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|
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!