How We Built It: Spotify Lite, One Year Later
What if, for some users, the very best Spotify is a little less Spotify? Spotify Lite started as an experiment that had to be proven, both from a technical and a product-market fit perspective. In 2017, we found that a significant portion of registrations in some of our fastest-growing markets were happening on Android devices much older than what we were used to seeing in North American and European markets. Because of storage constraints, many of our potential users couldn’t install Spotify, and the ones that could weren’t getting the full “Spotify experience”.
Our mission was clear: we needed to make Spotify accessible to users with constrained resources, i.e., unreliable networks or phones with limited storage, memory, and low-resolution screens. Now we needed a team.
A flexible, Lite team
The main Spotify Music Android client is divided into multiple features, all owned by separate teams. But for Spotify Lite, we formed a single, autonomous team to fully own the entire process of designing, developing, and releasing the app. This allowed us to roll out an MVP product in record time.
Before building the new app, the Spotify Lite team — a cross-functional mix of insights, design, product, and engineering — travelled to a number of locations where Lite would be available in order to experience the network and device constraints firsthand. It was absolutely critical to design Spotify Lite with our users in mind, and to experiment and iterate on the streaming experience for cases when devices have poor connectivity or are completely offline. Only then were we able to come up with an optimal, performant solution.
It should be noted that we wouldn’t have achieved success had it not been for the existing tooling that we were able to reuse — tools for enabling recommendations, playback, search, browsing, and instrumentation. We were building on all the work, experience, and knowledge that came before us, giving us the ability to focus on finding solutions for our users.
Spotify Lite: Spotify’s first separate app
Creating a more performant and smaller version of the Spotify app proved to be more challenging than we liked, as the codebase hadn’t been modularized. With these challenges in mind, we decided to build a new separate app from scratch, giving us the ability to quickly iterate, obtain feedback, and innovate freely.
Spotify Lite was initially built on an entirely different playback stack than the regular Android app. This allowed Lite to be as small as possible, with minimal memory and network data usage. Having a separate app enabled us to test new performance ideas and to gain insights, such as understanding how application size impacts the new user funnel. We no longer use the initial playback stack, and have evolved towards a tailored setup that guarantees stability and playback quality on unreliable networks.
Building Lite was a lot like packing a backpack for your travels. With limited space, you have to be selective in what you bring. Only the most crucial and necessary components were carried forward.
A balancing act
Shrinking the original Spotify app to create Spotify Lite brought up two crucial questions: What key elements of the original Spotify should remain intact to ensure listeners still get the “Spotify experience”? And what sacrifices do we need to make to ensure Spotify Lite does, in fact, remain light?
In answering the first question, we knew that keeping the brand look and feel was absolutely critical to giving listeners a Spotify they could recognize. So, we used the same design philosophy as the original Spotify Android app. However, given a range of constraints (smaller screens, quick/performant interactions), we had to adapt some of our design choices. For example, information density has to be reviewed with smaller screen sizes and lower resolutions in mind, as well as whether information is still readable on a broken or scratched screen (these phones have been around for a while!). We’ve recently added our heuristics for how to design for these constraints to the overall design strategy so that this is kept in mind for other apps and surfaces, as well.
Along with streamlining the design, we also had to shrink things down under the hood. The team put a lot of work into implementing all the known techniques for binary size reduction, as well as making tradeoffs when selecting features. As the app includes a native shared library for playback, we have experimented with many compiler and linker flags to prioritize a small app size. This includes, for instance, switching to the lld linker, employing link time code optimizations, and disabling certain language features like RTTI.
On the Android side, it was the use of App Bundles for application publishing, optimizing our R8 shrinking, carefully choosing dependency libraries, and stripping unused translations. We made an effort to reduce the install size, too. We store the shared library unpacked in the APK without copying it to the install folder, and allow users to store both the app and its cache and downloads separately on the SD card.
After the initial larger gains, it became harder and harder to reduce the app size. It was a constant balance between keeping it small while adding additional requested features. Along with monitoring the app download and install sizes in the Google Play Store, we added checks to our continuous delivery pipelines to prevent size bloat.
Lite is different
Because Lite was a brand-new concept, some of our work went beyond the app itself, leading to improvements to Spotify systems that other teams could benefit from, too.
Before Lite, developers could safely assume there was only one Spotify app for any given platform — the Android platform and the Android app were considered one and the same. Backend services — including those providing application views and deciding which features are enabled — were built with that assumption in mind. Some of these assumptions cascaded through many different parts of our internal systems.
When we added Lite to the mix, developers needed to know exactly which app a user was using, not just what platform they were on. We generalized that issue beyond our own app and built ways to identify all the apps in the Spotify ecosystem. That work paid off again each time anyone introduced a new Spotify app to the Android platform, including our sister apps Spotify Kids, Spotify Stations, and Android Automotive.
We also had to redesign parts of Spotify’s playback library with Lite constraints in mind — taking into account smaller download and installation sizes, memory usage, and the reduced feature set. Similar considerations have been applied to Spotify’s music and image transcoding services.
Making Lite a big deal
Our ambition is to be the best-in-class Lite app. We are constantly modifying and updating the app to adapt to our users and their ever-evolving needs. As we’ve seen positive adoption of Spotify Lite since launch, we’ve invested in performance improvements, quality, and resilience. We recently rolled out an overhaul of our client architecture to cater to our growing user base and to reduce playback latencies.
The birth of Spotify Lite has given us flexible solutions that our other apps have benefited from. One such example is our backend service that scales down images to use less network traffic. Another is the support for App Bundles, which has allowed us to reduce the app size significantly so that users only download the assets needed for their particular device. Creating a separate app was a first for our build system — one that laid the groundwork for building native dependencies, sharing code components, and setting up crash and ANR reporting for tracking app quality.
We are continuing our work to lower the barrier for people to access Spotify. We have our backlog full of ideas and performance improvements we want to keep investing in, not only for Lite but also for our other apps to benefit from.