Building mobile apps at scale is incredibly difficult, but there are several things you can do to put your team in a position to weather the storm without sacrificing velocity. While growing pains are inevitable, good planning will pay dividends down the line.
In this blog post, we’ll cover the top 5 growing pains mobile teams encounter and what they can do about them:
- Separation of Concerns
- Delivering Performance at Scale
- Maintaining Release Velocity
- Streamlining Issue Remediation
- Establishing a Monitored Feedback Loop
Separation of Concerns
This is a software architecture design pattern for separating an application into distinct sections. Mobile teams will want to break their application into distinct sections to enable easier onboarding, scaling, and adjustment.
This design pattern is usually implemented through the use of modular code, enabling teams to work separately and not interfere with another team’s code. Individual teams are responsible for their own code modules with a given set of responsibilities. Check out this eBook to learn more about the benefits of a modular architecture.
As mobile teams grow, adopting modularity allows the transition from generalists (where everyone shares mutual responsibility) to specialists (where the responsibility for a certain task falls unto a specific team or individual). Enabling teams to be hyper-focused on specific responsibilities can greatly accelerate engineering velocity. You can increase engineering productivity through limiting their focus and preventing bottlenecks from shared code. Additionally, when the code inevitably breaks it’s easier to pinpoint the source and and assign the ticket to the appropriate team.
There are many additional opportunities to introduce more efficient workflows. For example, a dedicated tools team can evaluate tooling choices, accelerating your mobile engineering with standardized tooling.
Delivering Performance at Scale
Without adequate planning, performance and stability will degrade as you grow your mobile footprint. The same systems and codebase that supported thousands of users won’t seamlessly handle millions or tens of millions. Without effective monitoring, it’s easy to let issues slip by that, before you know it, result in thousands of bug reports daily.
What can you do to prevent regressions in your mobile applications?
- Proactively identify problems with mobile-first monitoring
- Prioritize issues by their impact to spend engineering resources more efficiently
- Optimize the app for real world conditions (e.g. limit asset downloads, implement caching, build for varying network connectivity levels)
- Simplify startup by removing unnecessary work
As your mobile app scales, your team will need far more than error monitoring solutions to continuously deliver great user experiences. There will come a point where logging and collecting basic metrics will hit a visibility ceiling when it comes to solving the toughest issues.
At that point, you need a mobile data platform that provides observability. Observability allows you to uncover issues, see the root cause, and identify their impact, giving you the ability to make business decisions based on data and not guesswork. After all, you cannot address an issue if you don’t know about it. You need tooling that proactively surfaces unknown issues and gives you high-fidelity data to effectively prioritize them.
There is a lot of innovation in the mobile tooling space, so look for providers that continually stay on the forefront and deliver true mobile-first insights.
Maintaining Release Velocity
The only way to keep users coming back is to continually delight them. Creating a great product is the first step, but expanding your value systematically is crucial for driving retention.
Unfortunately, as the app scales in size and features, so too does the complexity of issues that can crop up. If there isn’t a system in place to ensure the app can adjust to a changing codebase, the entire app may collapse due to any change. To ensure consistent release cycles, your team must remove bottlenecks in the development and testing workflow. Earlier, we mentioned Separation of Concerns where the app is broken down into distinct sections to enable greater transparency and confidence when making changes. Some other best practices include:
- A robust A/B testing system — If a feature needs to be tested, the A/B test tracks should be pre-built for easy testing of different versions.
- iOS App Store/Google Play Store review process — The final step in mobile is almost always getting it approved for the App Store and Play Store. These two platforms have different guidelines so your team should maintain a different build system and pipeline for each.
- Automated rollout pipelines — If new features or updates need multiple greenlights before it reaches production, consider if certain stages can be automated.
- Sharing and maintaining libraries — You don’t want different teams reinventing the wheel whenever they need specific functionality. Minimize failure points by creating reusable libraries that are shareable across teams.
The team should always be evaluating: if something needs to be done once (such as testing a new feature), will it need to be done again? If yes, can it be automated? If it can’t, how can we reduce the friction of repetition as much as possible? Any bottleneck or friction in the release process should be documented and evaluated. Even if it doesn’t provide a problem now, there’s no guarantee that it won’t be a problem in the future.
Always seek to leverage what’s already working. If a current process or code will suffice, there’s no need to build a new module or process. Remember to make adequate use of tooling that optimizes your team’s ability to gain insight into what is wrong or what is an inefficient workflow that is causing bottlenecks. If something might be a problem in the future, write it down where the entire team can see it. When the day comes that a section of the team introduces a solution, they should go back to that note and indicate their fix so that the entire team can capitalize upon it.
A good example is deobfuscating iOS Bitcode symbols. This is a task that will come up repeatedly for iOS teams, and it makes no sense to manually deobfuscate each time your team receives an obfuscated stack trace. In that blog post, we added a section on how to automate the process to reduce any bottlenecks in workflow, thus reducing overall time to resolution whenever an issue crops up. The individual(s) that introduces the automation process should indicate to the team they have built the process so that other team members can also benefit. Reducing manual processes is a great way to prevent release delays.
Streamlining Issue Remediation
The process for resolving issues should be as seamless as possible for all teams.
To do so, teams need the following at all times:
- Observability: Collect actionable data to uncover and solve both known and unknown issues in production.
- Proactive monitoring: Be the first to know when things go wrong, whether a server outage, bad code, or failing third-party dependency.
- Comprehensive session-level data: Reproduce any issue in production with high-fidelity data on every user experience.
Each step in the issue remediation process needs to be clear for the team. For example, if a user submits a complaint about an issue and it doesn’t contain a stack trace, what’s the step the team can take to gain visibility into said issue? Many teams might choose to ignore it without a corresponding stack trace, but there’s an easy to investigate the problem.
It comes down to empowering each of your teams with the tools to enable maximum efficiency. The customer service team should be able have a clear path from vague complaints to triaging the issue. The product team should immediately know the impact of an issue on their users so they know whether to prioritize it with allocation of engineering time.
Use tooling that’s built to reduce the time spent understanding the issue so your entire team can get back to spending time where it’s creating the most value.
Establishing a Monitored Feedback Loop
By utilizing continuous integration and continuous deployment, the team is able to monitor each moving part as it’s added to the app. This in turn should create a monitored feedback loop for each part of the team that periodically fixes and adjusts the app based on incoming information.
First, let’s establish what Continuous Integration and Continuous Deployment are:
- Continuous Integration (CI) is the process of automating the building and testing of code every time code is committed to the code repository. CI encourages developers to commit their code as often as possible so it can be merged with changes from others to validate the code base through the build and test process. This process allows errors to be picked up and resolved much faster because each time new code is added, it can be tested against the existing repository as the newest “variable.” Any errors that pop up during this testing phase can be reasonably attributed to the new code being added, and therefore the team already knows what to narrow it down to.
- Continuous deployment (CD) builds on CI by automating the deployment of the solution after the code was successfully built and tested. In large corporate environments, this normally translates to automated deployments to several environments when the solution passes certain stage gates. Similar to above, just because the newly integrated code passes internal muster doesn’t mean it’ll necessarily continue to work after deployed to the wild. Each time newly tested code is deployed, your team monitors how that new addition affects the app as a whole and should be capable of disabling it immediately if there are any alarming metrics.
One great solution to run experiments with new features is through feature flags. You can selectively disable ones that are failing and review them internally while allowing the features that show no negative impacts to continue functioning. Make sure your team identifies possible failure points such as SDKs so you can disable them on your backend at a moment’s notice!
Both CI and CD feed into the team’s monitored feedback loop by having a self-sustained
information → update → collect new information process for iteration. This monitored feedback loop can be designed for each individual segment of the app (see Separation of Concerns) and the individuals responsible for that segment. Taken a step further, your team can configure alerts to notify the specific individual(s) responsible for any sections that need updating. This sends feedback directly to those who need to know and reduces noise for engineers on issues that don’t concern them.
Minimizing Growth Pains
Ultimately, mobile teams experiencing or expecting growing pains can have their symptoms alleviated with best practices in design, architecture, and team structure.
We understand that smaller teams won’t be able to put some of these best practices into immediate use due to size limits, but that doesn’t mean they shouldn’t always keep this in mind and look for the symptoms. Always be monitoring the health of your mobile team and how it impacts your app so you can proactively implement these best practices before it becomes a technical or management debt.
How Embrace Helps Mobile Teams
Embrace is a mobile data platform that provides observability, debugging, and proactive alerting for mobile teams. We are a comprehensive solution that fully reproduces every user experience from every single session. Your team gets the data it needs to proactively identify, prioritize, and solve any issue that’s costing you users or revenue.
We're hiring for many different roles! Check out our openings and see if you'd be a good fit for our growing team!
Want to see how Embrace can help your team grow your mobile applications with best-in-class tooling and world-class support? Request a customized demo and see how we help teams set and exceed the KPIs that matter for their business!
Want to learn best practices for scaling your mobile applications? Check out these helpful eBooks!