Have a look at the historical data on monthly new subscribers for my app’s mailing list:
See the significant increase starting December 2015? That’s due to the tricks I’m about to show you.
More precisely, only 8 people from 2,301 sessions (according to Google Analytics) signed up in November 2015, while in January, 71 people from 3,848 sessions signed up. This gives us the following conversion rates:
8 / 2301 = 0.35 % 71 / 3848 = 1.85 %
That’s probably still bad, but already an increase by a factor of 5.3! As the subscription rate may have been influenced by other factors, let’s “only” assume a quadrupling of the conversion rate, though.
And the measure to accomplish this was ridiculously simple.
Here’s How I Did It
Here’s my website before the changes:
After December 8th:
After January 8th:
I made a few more tweaks in January, but the most important change was simply to offer a 10% discount code for my app.
Books like Start Small, Stay Small tell you to give something away in order to make people sign up for your mailing list. A great example for this would be an email course or a mini-ebook on something your audience will be interested in. (As I learned today, these things are called “lead magnets”.)
But I didn’t have anything like that at hand. So, instead, I came up with something I could create immediately: a discount code.
I didn’t want to give each subscriber the same generic discount code (e.g. “NEWSLETTER10”), though. It just feels better if the code looks individually generated, just for them.
Now, this could be a lot of work — you need to set up a script that generates discount codes so that each subscriber gets a unique one.
But the code doesn’t need to be unique — it just needs to appear unique. So I simply went to random.org and picked a string that looked nice. I then created a discount with this specific code in FastSpring, my current payment provider (as explained in this guide).
The only thing left was to make the mailing list send out that key automatically. You could set up an automated email specifically for that. But each subscriber already gets an automated email: the subscription confirmation message! So I simply put the key in there.
Done! This small change took me about 15 minutes and already boosted my subscription rates enormously.
Impact on sales
Giving away a 10% discount to your app of course isn’t free, though: You might end up losing up to 10% of your revenue after all!
However, I could not identify a significant impact on sales. Customers do use the code, but my suspicion is that the potential loss of revenue per customer is offset by additional revenue from customers who wouldn’t even have purchased the app without the discount code!
Offering a lead magnet for subscribing is definitely the most important measure to boost your subscription rates. However, there are a few other tricks to make sure that no potential customer falls through the cracks.
Put the signup form on every page
Some visitors might not enter your website via its homepage. If you don’t have a signup form on every page, they might leave before having seen the signup form at all! To fix that, I added the form to every page:
If you do this, make sure to define the form as a common block in your CMS so that you only need to tweak it in one place.
I also added an option to subscribe on the contact form — people enter their email address there anyway, so why not subscribe already:
My metrics show that by far the most subscribers sign up on the homepage, but a few do come from the other pages.
Which brings us to the next point…
Track signup sources
Knowing which pages bring you the most signups (and have the highest conversion rates) can be incredibly valuable analytics data down the road. In order to track that, I’ve set up some extra fields in MailChimp, my current mailing list tool:
Make sure to mark these fields as hidden — you don’t want them to show up for your subscribers! Then, you only need to append &SOURCEPAGE=index, &SOURCEPAGE=faq etc. to your subscription form’s action URL and the data will show up in MailChimp. If you are using PHP, you could even generate that snippet automatically with e.g. &SOURCEPAGE=<?php echo basename($_SERVER[‘SCRIPT_NAME’], ‘.php’) ?> (most CMS have similar placeholders for this).
Only provide the discount code if you have to
If you watched closely, the screenshot above showed two more hidden fields. One of them is labeled “Provide Discount Code”. This is to avoid sending the discount codes to subscribers who were not offered it. Imagine a customer subscribing to your newsletter during the order process just to be told “Oh, look, you could have just saved 10% with this code!” afterward. Not a good experience. For this, all the forms that actually offer the discount code have an extra &DISCOUNT=1 appended to their action URL. The corresponding field is set up like this:
It is used in the MailChimp “Final welcome email” as follows:
This way, the discount is only shown to anyone whose DISCOUNT field is set to 1.
Change the copy for mobile users
When visitors are browsing your website from their phone, chances are they will completely forget to check it again later on their computer, when you could actually make the sale. In order to avoid that, my copy is slightly different for anyone not visiting the page on a Mac:
In this case, the signup form is simply offered as a means to get reminded about the app again later. There’s also a hidden REMINDERfield to track conversion rates for this copy, but I haven’t really investigated them yet 😉
And to make it even easier for them to get started, every signup email and page contains a direct link to download the app’s trial version:
Change the copy of the “Subscribe” button
Simply labeling your form’s button “Subscribe” is a bit bland. Something like “Get Discount!” or even “Get My Free Copy!” (in case you have a proper lead magnet) is supposed to work much better. And for mobile visitors, the button is accordingly relabeled as “Remind Me!”.
“No spam” promise
In order to make it more likely for someone to give out their email address, you can promise not to spam them. (Of course you shouldn’t spam them, anyway.) However, space on landing pages can be tight. So I decided to integrate the promise into the email box via the placeholderattribute:
No extra space wasted!
Only A/B test the important stuff
The color of your “Subscribe” button and whether its label includes an exclamation mark are things that are unlikely to have a big impact on the conversion rate. Instead, trust your gut and spend the precious A/B testing time on more important things — like significant copy changes (more on that in another article) or different lead magnets.
In the future, I’m planning to actually build a proper lead magnet (probably an email campaign on time tracking or improving your productivity).
For that, I’m planning to switch to Drip, as it makes setting up email campaigns much easier. Plus, I need to email my list more regularly.
I might also do an A/B test to see if changing the form’s copy to “Enter your email address for a 10% discount” further increases signup rates.
Lastly, I have recently doubled my website’s trial download conversion rate, just by changing the sales copy. Stay tuned for a post on that!
Conclusion: Fake It Until You Make It
You don’t need to wait for anything to improve your newsletter signups.
You don’t need a complex email campaign.
You don’t need a proper lead magnet.
The most important thing is to get started now — just hack something together! It might already be better than what you had before and you can figure out further improvements along the way.
What are your experiences with improving conversion rates? Hit me up on Twitter!
Happy holidays, everyone!
The latest episode of Startups for the Rest of Us is about setting annual goals. This inspired me to reflect on my own goals for 2016. Given that my last day at Google will be January 14th and I’ll have to rely only on my Indie business for income afterward, having clear business goals is more important to me than ever.
Actually, I think this is important to every entrepreneur serious about their business. Otherwise, how are you going to make decisions on which measures you should focus your limited attention on?
When making goals, the most important thing is to ask yourself:
Where do I want to be one year from now?
Having a clear vision of where you want to go makes it much, much easier to take actions that bring you there. Don’t just set vague New Year’s resolutions like “I want to make more money” or “I want go get healthier” — have a clear target in mind! Next year, you then can (and should) retrospect on how well you did.
Also, make sure to share your goals with friends (or publicly)! The extra accountability of telling someone else makes it much more painful to slack off on them, which really helps to follow through.
But how do you actually formalize and write down these goals? In this post, we’ll use the Objectives and Key Results (OKRs) framework, which were originally a practice at Intel, but have since spread to companies like Google, Twitter and LinkedIn.
What are OKRs?
The principle is simple: First, you define objectives that represent your high-level goals. For each objective, you then come up with key resultsthat contribute to it. These need to be measurable, as they will be used for scoring: At the end of the planning period (usually a quarter or a year), you review your key results and assign each of them a score between 0 and 1 based on how well you performed on that metric. Weighting all the key result scores of an objective by priority and taking the average then gives you the objective’s score.
A score of 1 isn’t desirable, though — it indicates that the goals were not ambitious enough. Achieving a score of around 0.7 is considered optimal , meaning that the goals are high but not unreasonably so.
By the way, at Google the company-wide OKRs and the company’s subsequent performance on them are shared with all employees. This provides some extra accountability and helps keep the employees
OKRs are not set in stone, though — they can and will change over time as the demands on your business change.
Here are my OKRs for the upcoming year. Hopefully they can help you define your own goals!
Objective 1: Grow the Business
Increase yearly profit (revenue minus expenses) before tax to XXX € for the whole year, YYY € in the last 3 non-promo/non-launch months
Revenue OKRs would be obfuscated at Google and I’d rather not share the numbers here, either. We’re talking about a 60–100% increase over today’s numbers, though.
While very measurable, this metric is not so actionable. To achieve the result, lots of small steps need to be taken over the course of the year that all contribute a tiny bit.
Grow timingapp.com’s average daily visitors to 150 in the last quarter
Currently, this number hovers around 60. The following key results should help with achieving this oral, though.
Get 12 new articles mentioning Timing
This can hopefully be achieved by carefully pitching bloggers and other influencers.
Rank consistently on the first page of Google’s search results for “mac time tracker”
This could be huge for the organic inbound traffic for Timing.
Release Timing 2
Without a clear specification of what that release is to contain, this one is quite spongy. On the other hand, speccing everything out beforehand would be very “waterfall” and not very “agile” 😉 I have already collected a ton of ideas for the update, but which ones will make it into the final version (and in what form) will very much depend on feedback of my beta testers.
Grow the Timing newsletter to 2000 subscribers
Currently, the newsletter has 420 subscribers acquired over the course of almost four years, so it will need to grow much faster than before. To accomplish this, I’m going to distribute much more useful content to the newsletter and give away some content to subscribers. Giving away a 10% discount code to subscribers this month has already improved growth substantially.
Conduct at least four sponsorships or other substantial promotional measures
The first one (sponsoring Six Colors) is already planned for January. Bundles don’t count (unless they’re extremely popular), as they often have virtually no impact outside a little extra revenue.
Objective 2: Provide useful information
This area is fairly new to me, as I’m only getting started with blogging and content marketing, but it is already starting to feel increasingly important to me.
Create 25 pieces of original content
This includes posts like this as well as articles on the Timing blog (which doesn’t exist yet) and possible email courses for newsletter subscribers. Indie Weekly episodes are not included unless they include substantial amounts of original content.
Grow Indie Weekly to 500 subscribers
Indie Weekly is a newsletter for independent app developers, with a focus on marketing and Indie life as opposed to the technical sides of development (for which there already are plenty of other newsletters). The first episode is currently scheduled for the week of January 11th and will be sent to the about 40 people who have already subscribed.
Although Indie weekly is about business, I see it as an effort for the community, so it’s not part of the “Business” objective.
Objective 3: Personal Development
Not all goals need to be about work — never neglect growing yourself! Anyone can build a business, but the only person who can actively make life more awesome for you is yourself.
This objective might actually be the least ambitious of the three (for now), but I might add more points to it over the course of the year. Here are some other personal development goals that might be suitable for you:
- Read X books
- Sleep at least X hours per day on average
- Meditate every day
- Learn a new language
- Watch at most X hours of TV per week on average
- Spend at least X hours focused on deep work (see Cal Newport’s blog for details on what that means)
- Work at most X hours in total per week
Come up with at least one more side project
I love side projects as a hobby. Building something usable from start to finish and releasing it, all in a few days, feels amazing. And if you’re starting to feel burned out from your main projects, they can also be a welcome distraction.
Attend at least 4 conferences
I’ve had a great time with amazing people at all the conferences I’ve been to, so I’d like to repeat that experience. Plus, every time I come back from a conference I’m super pumped and motivated to get back to doing great work.
Here are some conferences I have in mind:
Give at least one talk (e.g. at a meetup or a conference)
I’d love to share the experiences I’ve made with more people and help them grow without making the same mistakes I did. For this, I might give a talk about my first several months as a full-time Indie developer, for example.
Spend at least 28 days in foreign countries
There’s finally an affordable gym close to my place, so I took the opportunity and signed up for it. I mostly want to focus on cardio and condition training in the beginning with some core strength for windsurfing.
In order to have a clear target in mind, I came up with a few vanity fitness goals:
- Do 50 push-ups in a row (currently around 30)
- Do 15 pull-ups in a row (currently around 6)
- Get visible abs
Each of these key results by itself should be fairly achievable over the course of a year (except for maybe the revenue one, which is harder to control as it depends on many other factors), but their sheer number will make it hard to accomplish them all. That’s fine, though — I’m aiming for the aforementioned 70% completion rate.
I mostly focused on the first half of the year, during which I plan to double down on Timing and create a big update for the app. In the second half, I hope to dedicate more time to PocketCAS, which so far has no goals on this list.
These are my goals for 2016! What are yours?
Lately I’ve been wondering:
If I were to build a startup whose main product was a web service (i.e. where the website was an integral part of the product, not just an elaborate ad), what setup would I choose?
(That situation might actually not be so unlikely.) This article is my personal semi-educated answer to this question.
This setup assumes a small team (1–4 engineers) with a mostly-monolithic app (except a split between UI and API, see below) and only a few dozens of QPS — larger services have somewhat different demands that I think most people don’t need to plan for from the outset. Incorporating Microservices should not be too problematic, though (up to the point where you need a more sophisticated system for deploying and managing all of these jobs).
Of course having a great product is way more important than a “good” stack and there are many, many ways to build a great product. But there are still a few (a lot?) of foundational picks to make. The ones in this article are one point to start from.
What would be your picks?
- One main SSD-equipped dedicated root server, hosted either with Hetzner or OVH. This is quite cheap (less than € 100 per month) and provides lots of power.
- A second (smaller) root server or VPS that only does load balancing via nginx or HAProxy. This way, the main server does not need to be exposed to the public web at all, hopefully reducing the surface area for attacks (especially database hacks).
- Alternative: Put everything on AWS. This is better for horizontal scaling, but a few beefy servers can actually get you quite far, as StackOverflow demonstrates. It might also let us avoid having to set up and run our own database (e.g. with Amazon RDSor DynamoDB).
I don’t have enough experience with AWS to tell whether their services make deployment so much easier to warrant the somewhat higher cost already. If there are other important things that you get “for free” with AWS, let me know — I’m probably missing something.
Every day, a script should back up the service’s database(s) and upload it to a remote storage service (e.g. Amazon S3). Other data on the servers should not need to be backed up, as we should have scripts that can set up a server with a production configuration from scratch. This script should also be used daily to set up an additional server and fetch and restore the database. This ensures that we can quickly recover from an outage. Plus, this server provides us with a system that we can failover to quickly in case something goes wrong with the main machine.
(We also need a service that monitors the successful completion of these scripts so that we know if anything is not in order.)
In order to make the setup of new production, staging and development machines easier (and more reproducible), the servers themselves should need as little individual configuration and state as possible. This can be achieved by running them on CoreOS with Docker for containerization.
This also lets us create a development environment that mirrors production, which avoid subtle bugs due to inconsistencies between the dev and prod environments.
(Especially for this part, there are a gazillion alternatives.)
- Backend: A RESTful API hosted with Django served by nginx. I would actually prefer a compiled, statically-typed language, but Python+Django let you get started extremely quickly and there’s tons of Python libraries for any imaginable purpose (although Python’s package managers are a bit weird).
Now that Swift is open source, it will hopefully be possible to write solid web services with it soon. But the current state of Swift web frameworks (e.g. Perfect) is not very impressive.
- Database: PostgreSQL for a relational database. I have little experience with non-proprietary key-value stores, so no opinion there. Protocol Buffers are also great for data storage (especially if you need to extend your schema later), but it seems like only Riak supports them out of the box.
(This article is not concerned with datasets large enough to warrant the use of e.g. Redis and Hadoop yet.)
Again, lots of options here (and you can be happy with any of them):
- Slack for internal communication.
- Google Apps for Work for Email, Calendar and documents.
- Google Hangouts for video chats.
That’s it for now, but I intend to update and extend this list from time to time. So if you think there’s something missing, let me know.
Building the library with open sourcing in mind from the beginning meant that I didn’t let myself take any shortcuts, which means that the result is rock-solid (and has good test coverage at least for the data structures). I’m pretty sure that the end result is much much better due to this approach 🙂
In addition, I decided to write the library purely in Swift, while maintaining at least some level of Objective-C backwards compatibility (as Timing is still written in Objective-C).
The library’s main data structure is a DateRange enum which lets you specify:
- A custom date range
- The past N days
- A calendar unit (e.g. day, week, month, quarter, year), with a specific offset from the current date. E.g. (0, month) corresponds to this month while (-1, quarter) represents last quarter.
As an enum, this structure unfortunately is not available from Objective-C, but the control itself provides e.g. KVO-observable start and end date properties for backwards compatibility. In addition, the control follows the target-action pattern. You can also serialize the currently selected date range to and from an NSData object in order to persist it between launches of your app.
If this sounds useful or interesting to you, please have a look at the project on GitHub. Feedback and pull requests are more than welcome!
Which means that I’m going to be a full time Indie developer starting next February.
Making the decision to quit a great, safe job with a terrific employer (and carrying that decision out) was not easy (scary, even), but in the end the need to “do my own thing again” was stronger. I’m uncomfortably excited for what’s coming next!
So what is coming next?
In addition, I’m preparing a newsletter for Indie developers [UPDATE 16/09/04: defunct by now, and replaced by this blog instead]. If you’re interested in life as an Indie developer, marketing, and development, please subscribe.
But to be honest, I don’t think that my two apps are going to be my main focus for a long time, either. I don’t know yet what will take that place, but hopefully having more spare time than before will let me explore several new areas (Software as a Service and Machine Learning come to mind, although I have no clue yet what I’m going to do in either field) and find my “next big thing”. I’m also going to do more experiments, e.g. by prototyping a few products super-quickly to see whether there is a need for them.
Last but not least, I’m currently reading Start Small, Stay Small, which should help with mastering Indie life in general as well as getting new products off the ground.
P.S.: I was considering to append “Here’s what happened next.” to the headline, but decided to spare you the clickbait 😉
Today I witnessed a conversation about tons of unused iOS simulators on Twitter.
I had the same problem recently and looked for an easy way to clean up all the unused simulators. On StackOverflow I found out about xcrun simctl, which lets you list and delete arbitrary simulators. I ended up creating this little shell one-liner to delete all simulator data packages for which the simulator is no longer installed:
xcrun simctl list | grep unavailable | cut -d “(“ -f 2 | cut -d “)” -f 1 | while read sim; do xcrun simctl delete $sim; done
This lists all the simulators, filters for the unavailable ones, extracts the simulator IDs, and then iterates over them and deletes them. Be aware, though, that this also deletes your simulators for iOS 9 and watchOS 2 if you did not xcode-select the Xcode beta for your command line tools (and if you did, it might actually delete your simulators for iOS 8.4). In that case, you may want to first output the list of simulators to a file:
xcrun simctl list > simulators.txt
Then edit that file, leaving only the simulators you wish to remove, and execute
cat simulators.txt | cut -d “(“ -f 2 | cut -d “)” -f 1 | while read sim; do xcrun simctl delete $sim; done
Done! Your simulator list should look like this again:
P.S.: Ortwin points out that you might need to do a
P.P.S.: There are of course also other ways to accomplish this, but this one doesn’t require you to install any extra tools.