Every early-stage startup is going through three major phases: the hard working phase of building the MVP; the super exciting phase of launching the MVP; and the cold reality of MVP-enhancement-support-scaling-customer-acquisition-marketing-accounting-taxation-etc phase.
It is a real challenge for co-founders to take care of everything, staying sane at the same time. Increasing the team size, have one person responsible for a separate stream is an obvious way out of this situation, but we are talking about the early stage of a startup when all you have is a bunch of like-minded mates who left their day to day jobs and studies to build something great.
In what follows I’ll try to convince you that with a little self-organization and technology support, any team, no matter how small it is, can keep up with product development and still offer a first-class support to their customers.
The topics are presented in no specific order and cover both technical and non-technical aspects. Some of them have been thought through in advance and paid us back from the very first minutes of launching Visely. The others have been learned from the field for the last 6 months Visely is running live.
Check our CEO’s insightful article on how we bootstrapped a startup to find out how the whole venture started and what other challenges might expect you as a co-founder on your journey towards success.
1. Simple Onboarding
As in any type of relationships, the first impression is what matters the most. Same goes for the customers that are installing your app or are using your service for the first time.
Make the whole process fast, dynamic and visually engaging. Don’t leave the customer staring at a faceless spinning gear or an infinite progress bar while you are setting things up. If it takes time, make sure you provide insights into what is currently going on.
Don’t ask the customer for details that are not vital for the service operability. Yes, it’s nice to greet your newly onboarded customer by his first name, but is it really that important? Use OAuth or Single Sign-On to authorize the customer with your service so they don’t have to remember yet another set of credentials. Both, usually, provide some basic personal information, as well as explicitly state the scopes your app or service is asking access for.
Split your onboarding flow into sub-flows. Decide which of the sub-flows make sense to be presented to the customer and which don’t. Focus on usefulness, don’t just try to fill up the space. Use an animation or a splash screen with a dynamic, stackable list of messages to update the customer on the progress.
Don’t overwhelm the customer with instructions like “Copy and paste this code snippet into…”. That’s not cool anymore and is extremely error prone. Explore the alternative, automated ways of integrating your services into the customer’s system.
2. Clean UX
UX is a huge topic and a science on its own. Here is the key takeaway: a simple, intuitive and responsive UI is key for a less frustrated and open for exploration customer.
Use Progressive Web Application approach to smoothen app loading and the transitions between different sections. It helps address slow network issues by making your app responsive and keeping your customer engaged.
Design your app to be self-explanatory. Keep text copies short and use pictograms or drawings to explain a concept.
Have a main overview section the customer can use to get a whole picture of system’s capabilities and status. Deep-link into specific sections from there and provide a convenient way to navigate back and forth through the app sections.
Start with a bare minimum of configurable options and evolve based on customer’s engagement. To get an insight into customer’s behavior add a tracking library like Google Analytics into the app to capture navigation patterns, time spent on different pages, actions and events triggered by the customer, etc. Have a weekly or bi-weekly routine of going through the collected metrics and adapt your UI accordingly.
Provide visual feedback on actions triggered by the customer. Don’t leave your customer wondering whether she actually clicked on that button or not.
Keep accessibility in mind. Choose the right font type, font size, and color scheme to make sure your app suits the preferences of a broader audience.
If you collect any KPIs about your app or service, like conversion rates, click-through funnel, client engagement level, etc., share them with your customers. Don’t wait for the customers to ask for them.
You can either have the metrics embedded into the admin dashboard, available for the customer at any time or send them in a digest email to customers that opted-in for updates. Stay connected with your customers.
Sending statistics through email proved to be a better option. If possible, make it visual by using infographics. If you choose to go the automated way, carefully consider the frequency to minimize the noise level.
4. Team’s Reachability
Always be “there” when the customer needs you.
The most effective solution is to integrate an online chat into your site, app, and admin dashboard. Personalize it by adding a photo of the team and a short bio for each of the team members.
Make sure you leave a phone number your customers can use to reach you. Most of the people are hesitant to make any phone calls at all. In 6 months we had only one call, but having it there builds credibility.
A good FAQ section can be of a great help. You can think of it as an “ever online” member of the support team. Two things to keep in mind about the FAQ page: keep it up to date and keep it short. An FAQ page that spans hundreds of topics might well be an indicator of app complexity. Always ask yourself “Can I show not tell?”.
Beyond the classical FAQ page, the exact same knowledge base can be fed to a chatbot integrated into the online chat, bringing it closer to a human-to-human interaction. A perfect cover for the support team when it’s not available for an immediate engagement.
Providing a 365/7/24 support is not an easy task. Especially, when the team is located in Europe and the product is available to anybody around the world. The hints above, when combined, should give your team a decent coverage.
5. Fault Tolerance
Integration of your app or service with a customer’s system should not have an impact on the overall stability and performance of that system.
Ensure your script is loaded and executed asynchronously. This will allow the main content to load faster and smoother. All the communication with the backend service should be asynchronous.
Wrap every call to the backend service in a circuit breaker. Think of it as a shelter for your backend server. In the event your server performance starts to degrade, the circuit breaker will throttle the requests initiated on the client side, avoiding complete saturation of the backend until the system recovers.
Keep the footprint of the library as small as possible to save on internet traffic and increase loading speed. Provide minimized versions of your library alongside with map files or plain versions for debugging purposes.
Take a modular approach when coding your library. Ensure it is well scoped and doesn’t leak into global space. This is going to lower the likelihood of your integration breaking other integrations.
6. Reactive Architecture
The reactive architecture is basically the cornerstone of a resilient and fault tolerant system. It can be applied to the app UI, client-side libraries as well as backend services.
Most of the modern UI frameworks have the reactive approach at their core. Pub-sub protocol for inter-component communication, two-way binding for efficient rendering and update of the components, server-sent events technology for a more efficient communication with the backend services, etc.
On the backend, favor push-based communication with the client side instead of a pull-based one. You‘ll have more control over the workload your servers are exposed to if you do so.
Opt for a message-driven model to decouple the components of the system. Choose frameworks that offer a durable and replayable message store.
Apply reactive principles to all integration points within your backend system. Use the resources wisely. Don’t block on I/O.
7. Real-time System Notifications
The sooner you find the issue, the sooner you can provide a fix without the customer even noticing it.
As previously mentioned, a smooth onboarding process is key to success. Follow your customer’s journey during onboarding. Identify couple checkpoints in the flow, say, installation triggered, initial onboarding completed, data import completed, uninstall triggered, etc. For each of the checkpoints send an email to the team. Whoever is available can jump in and do a sanity check to ensure everything is OK.
Enable verbose logging for critical paths of your system. Using a data processing tool and a data analysis/visualization tool you can define your own rules to watch for specific error groups and send out alerts in the event such errors are encountered.
There are solutions you can use to monitor your client-side code. Usually, these are lightweight libraries that aggregate the error logs recorded by the browser and push them to your server for further processing.
Be proactive in fixing issues as they pop up. It’s much harder and stressful to implement and deliver a proper fix while you are chatting with a few customers that need your help.
8. Smart Deployment Pipeline
The ability to release new features and hotfixes to production, reliably and fast, is always a competitive advantage. Doing it in stealth mode from the customer’s perspective is an uber-advantage.
Automate everything. It shouldn’t take more than a couple of clicks to promote any code changes to production.
Choose your deployment strategy wisely. If a downtime is absolutely a no-no, go for blue-green or rolling deployment. Both ensure no downtimes and offer a relatively painless rollback, the former at a higher price, the later at a higher complexity.
Canary deployment is an alternative for teams with a modest budget allocated for infrastructure. In this case, services are deployed on the same instances. To minimize service interruption time, there are a couple of things to consider.
Split your monolith into microservices. You can spin them on and off whenever needed. Usage of lightweight containers to host your microservices, is enabling you to kick-off granular deployments that will finish in minutes or even seconds.
Having reactivity “on duty”, the downtime of a microservice has almost no impact on dependent microservices. These services will gracefully handle the temporary disruption and employ a failover mechanism with a backpressure retry strategy until the service they depend on comes back.
Message-driven model, assuming it is backed up by a durable, replayable message store, will ensure the freshly deployed service catches up with everything that happened while it was down.
Most of the topics above should be familiar to you. We know them, we read about them, and we forget about them.
Even though thoughts like “How are we going to support it with the growing customer base?” are sometimes crossing our minds, we often find ourselves saying something like “Lots of customers? Nah, we’ll be fine. That’s a nice problem to have, we’ll make it through”.
Yes, you will. But you can do it prepared, investing just a little more. At the right time. Into right things.
If you liked this story you can check the other two from this series:
If you happen to be a Shopify store owner, visit our page on the marketplace.