Automatic license renewals: twenty months later

About twenty months ago, while sitting on a couch in Auckland, New Zealand, my team and I flipped the switch to enable automatic renewals for AffiliateWP. Two months later we did the same thing for Easy Digital Downloads and Restrict Content Pro. This was a move that we had been working towards for nearly a year and it’s one that we believed would fundamentally change the position of the company over the next one to two years. Now that it has been twenty months, maybe we can answer the question: were we right? Did it make a significant impact for us or was it all futile hopes?

Historically we, like many other online product companies, have struggled with low renewal rates. All of our products are sold with annual licenses that should be renewed each year so long as the products are in continued use. Renewal revenue is a critically important part of growing any online business because it reduces the expensive process of customer acquisition. Your revenue isn’t purely a factor of how many new customers you obtain, it’s a combination of your new customer acquisition and your existing customer retention. If you have great customer retention, you can grow your annual revenue year after year without having to rely on increasing the number of new customers acquired year over year.

Our goal with implementing automatic renewals was three-fold:

  1. Reduce friction and effort for customers. Easy systems == happier customers.
  2. Increase renewal revenue by reducing the number of “forgotten” renewals.
  3. Provide a predictable revenue stream we could rely on and adequately forecast against.

Let’s start determining if we were successful by looking at some previous year stats.

Easy Digital Downloads

Here are some quick stats on our previous years with Easy Digital Downloads:

  • Total revenue in 2014: $474,622.54
  • Total revenue in 2015: $561,269.06
  • Renewal revenue 2015: $80,799.26
  • Total revenue 2016: $597,352.61
  • Renewal revenue 2016: $139,850.03

In 2015 we brought in $80,799.26 in renewal revenue. That’s revenue from existing customers that renewed their license keys. This number means only 14.4% of our total revenue in 2015 came from renewals. Ouch. While $80,000 isn’t a small number and is a nice addition to our annual income, it’s abysmally small when you recognize how few customers were coming back and purchasing renewals.

Our 2016 renewal revenue was higher at $139,850.03 but still only accounted for 23.41% of our total revenue that year.

AffiliateWP

For AffiliateWP, we have pretty similar patterns between 2014 and 2016.

  • Total revenue in 2014: $119,651.50
  • Total revenue in 2015: $379,078.36
  • Renewal revenue 2015: $19,774.60
  • Total revenue 2016: $491,890.90
  • Renewal revenue 2016: $62,827.80

For 2015, our renewal revenue accounted for only 5.22% of our total annual income. This is super drastic, though it does look worse on the surface before realizing part of the reason the renewal revenue was so low was because 2015 saw incredible growth for AffiliateWP. We more than tripled our 2014 revenue by bringing in a lot of new customers so our new customer acquisition was rapidly out pacing our existing customer base from 2014.

In 2016, we saw $62,827.80 in income from renewals, accounting for 12.77% of our revenue that year.

Restrict Content Pro

Again, Restrict Content Pro shows pretty similar patterns of abysmally low renewal income ratios.

  • Total revenue in 2014: $67,211.75
  • Total revenue in 2015: $83,806.60
  • Renewal revenue 2015: $10,460.30
  • Total revenue 2016: $157,486.89
  • Renewal revenue 2016: $21,706.60

In 2015, we brought in $10,460.30 from renewals, accounting for 12.48% of the year’s revenue. And in 2016 we saw $21,706.60 in renewals, or 13.78% of the total revenue that year.

Easy Digital Downloads in 2017

Automatic renewals for Easy Digital Downloads were enabled on March 30, 2016, which means the first payments to be processed by the resulting subscriptions would occur on March 30, 2017. This is important because it means the first three months of 2017 had the same manual renewals as previous years. Based on speculations, automatic renewals should dramatically increase the amount of revenue that comes from renewals.

Did it?

  • Total revenue so far in 2017, January 1 to August 1: $463,835.92
  • Renewal revenue so far in 2017, January 1 to August 1: $166,716.98
  • Revenue from auto renewals in 2017, March 30 to August 1: $90,297.20

Thus far, 35.94% of our Easy Digital Downloads revenue has come from renewals. That’s 12.53% more than in 2016, so a really good sign that automatic renewals are having a significant effect.

Of the $166,716.98 in renewal revenue, $90,297.20 of it was from automatic renewal payments processed with subscriptions. So 19.47% of our total revenue in 2017 has come from automatic renewals. That’s pretty good on the surface, but actually it’s really good. Why? Simple: automatic renewals didn’t start processing until the beginning of the second quarter of 2017 and yet it has already accounted for nearly 20% of our total yearly revenue.

If we look at March 30 to August 1, the time period that automatic renewals have been processing, we see that renewal revenue accounted for 38.72% of our revenue.

Here’s a graph that shows monthly license renewals for 2017. Can you see the point when automatic renewals began processing?

AffiliateWP in 2017

Automatic renewals for AffiliateWP began processing on January 21, 2017, so most of 2017 has included automatic renewals, unlike Easy Digital Downloads and Restrict Content Pro.

  • Total revenue so far in 2017, January 1 to August 1: $443,996.90
  • Renewal revenue so far in 2017, January 1 to August 1: $101,453.35
  • Revenue from auto renewals in 2017, January 21 to August 1: $89,686.40

22.85% of our 2017 revenue has come from renewals, and 20.2% was from automatic renewals. Just 2.65% came from manual renewals.

In 2017 we have had $101,453.35 in renewal revenue. In 2016 we had just $62,827.80. We’ve nearly doubled our renewal revenue and there are still four complete months left in 2017. Obviously some of that increase is due to natural growth, which we’ve continued to see for AffiliateWP, but it’s still a significant increase that I believe is largely attributed to automatic renewals.

If we exclude the first 20 days of January, we find that renewals have accounted for 24.20% of our revenue in 2017.

Here’s a graph showing license key renewals over time for AffiliateWP:

I don’t think I need to point out when automatic renewals were enabled.

Restrict Content Pro in 2017

The numbers for Restrict Content Pro in 2017 do share similarities with the other two products but it has one significant difference that needs to be noted. Throughout 2016 and 2017, one of our primary focuses has been to revitalize Restrict Content Pro and bring it back to a strong position within our product portfolio. I’ve written about these efforts and the results so far previously. I mention this because much of the growth Restrict Content Pro has seen in the last 20 months can be attributed to automatic renewals and extensive revitalization work.

  • Total revenue so far in 2017, January 1 to August 1: $184,686.45
  • Renewal revenue so far in 2017, January 1 to August 1: $28,503.85
  • Revenue from auto renewals in 2017,  March 30 to August 1: $16,165.80

In 2017, 15.43% of our revenue has come from renewals. 8.75% of that was from automatic renewals. This is an increase over previous years but not too terribly drastic. It is, however, still significant when we recognize that automatic renewals did not begin processing until the beginning of the first quarter of 2017.

If we look at March 30 to August 1, the time period that automatic renewals have been processing, we see that renewal revenue accounted for 19.22% of our revenue.

The graph below shows the growth of license renewals overtime. There is a pretty distinct increase in April that continues through the end of July. That increase is the result of automatic renewals.

Wrap up

I think the numbers mostly speak for themselves and really show that automatic renewals are having a significant impact on the financial state of the company. I look forward to seeing whole-year numbers after we’ve had automatic renewals processing for more than just a few months.

Restrict Content Pro’s 2017 revenue has already passed that of 2016, AffiliateWP is less than a month away from beating 2016, and Easy Digital Downloads is two months away from surpassing 2016. There are still four complete months left in 2017 and one of those includes our historically best month: November.

We need to make an important note here regarding the price increase we did at the end of 2016 and early 2017. The price increase did not affect any existing subscriptions, so the majority of the renewals we’ve seen so far in 2017 have been at the previous, lower price. So even though our renewal revenue is mostly at a lower price point than new sales, the percentage of the total that renewals account for is still significantly higher that it was previously. Once we are seeing the majority of renewals come in at the new, higher price, we’ll see even more significant results.

There are a number of really excellent effects automatic renewals have contributed to, but there are two in particular that I would like to highlight.

First is the ability to reliably forecast our expected revenue month-to-month. We now have a reliable data set that provides us with much more accurate predictions for future revenue, and that is incredibly valuable, especially when making decisions about company investments and weighing risks.

Second is our profit margin. One of downsides to increasing revenue through new customer acquisition is the added support and development burden that entails. The burden of adding $10,000 per month from new customers is not minimal at all. In fact it can be a real challenge. One of the reasons companies hire new employees is to help meet the demand brought on by the new customers. This often creates an endless cycle of growing your expenses as quickly as your revenue. Adding $10,000 to your monthly income doesn’t make much difference if you also add $10,000 in new expenses each month simply to help manage that new $10,000 you brought in.

Renewal revenue, however, doesn’t require the same maintenance that new revenue does. In other words, if we earn $100 from a new customer, it is likely that we will have to spend $80 helping that customer. If, however, we earn $80 in renewal revenue from an existing customer, we most likely won’t spend more than $20-30 helping them, if that. The reasoning is simple: renewing customers cost significantly less because the maintenance for them has already been done.

Existing customers are so much cheaper than new customers, so it only makes sense that we should do the very best we possibly can to increase the revenue generated from those existing customers. If we do that, our profit margins will get better and better, and that is precisely what we have seen.

Our previous years have all been profitable in the end, sometimes not very profitable but profitable nonetheless. 2017, however, has seen a completely new trend. We are not only showing profit every month, we are showing monthly profit that is greater than all previous annual profits, and we’re seeing it every single month but one so far. Which month didn’t see that level of profit? January, right before automatic renewals began taking place. Coincidence? Absolutely not.

I’ve previously mentioned that I believed transitioning to automatic renewals would likely be one of the best things we ever did. Today I’m more confident of that prediction than ever.

Reflection on a price increase

On December 14, 2016, my team and I pushed a significant change to our Easy Digital Downloads products: we increased the price on all extensions by 50-250%. Yes, you read that right: up to a 250% price increase on certain plugins. This change was done for a number of reasons, which I will get into shortly, and has resulted in a very interesting last three months. Since I have always been very open with my company’s financials, I would like to now share some reflections on the change that we made and to also share some of the aftermath of the change.

The backstory

Since the beginning of Easy Digital Downloads, and I imagine many products, customer support has always been our biggest challenge. Taking care of customers is hands down the most difficult job in the company. It is ripe with challenging problems to solve, long hours, relentless flows of new tickets, on-going conversations that spread not only over days but even weeks and months. Providing good and, when possible, great customer support is, to put it simply, exhausting.

There have been many times over the last 5-7 years where I thought to myself I’m sick of this; I just can’t keep taking care of these people, maybe I should quit. I have had those thoughts and every member of my team has had those thoughts. On one particular evening back in November, I was sitting on my couch doing my best to work through a not-abnormally sized support queue, and it hit me: this has to stop. This wasn’t the first time I (and many other members of the team) had spent insane hours working through support queues, nor was it the 50th time. Working late to help finish support requests is an every single day occurrence. It literally never stops. This time, however, I had had enough (fifty times too many) and decided it was finally time to take drastic measures to reduce support. I hopped into our Slack channel and told my team this and within a few minutes we’d made a decision: it was time to increase prices. It was past time, actually, but late is always better than never.

When a company is faced with an over burdensome support load, there are a number of ways that most companies look to address it:

  • Fix the bugs that cause problems to happen that then result in support tickets
  • Improve UX so customers better understand how to achieve certain results
  • Write more and better documentation
  • Hire more support team members
  • Move team members from non-support roles to support roles
  • Outsource support
  • Release fewer updates
  • Release more updates
  • Remove problematic features / products

All of these methods are 100% viable and our team has implemented all of them. There is, however, another method that people tend to gloss over or ignore, and it is perhaps one of the most effective of them all.

To lower your support load, all you need to do is have fewer customers.

It may seem like the opposite of what most companies want, after all customers are the people that make it possible for companies to pay their bills and their team members. Without customers, companies cease to exist.

The real answer to lowering support burdens is to have fewer but more valuable customers.

On that evening in November, my team and I decided it was time to try and drastically reduce our support burdens by dramatically raising prices, thus reducing the number of customers while simultaneously increasing the average value of customers. Theoretically this would allow us to keep our revenue about the same (which was just barely covering our monthly expenses) or, if all goes well, raise our revenue and lower the total number of support tickets we received each month.

That was the hope anyway.

The change

We threw a lot of numbers back and forth while discussing the possible changes we’d make to pricing. In the end we had several goals:

  • Raise the average customer value
  • Lower the number of customers, thus lowering the number of support requests
  • Keep overall revenue steady or raise it

Due to the sheer number of plugins sold through easydigitaldownloads.com, there were a lot of different price points. We sold plugins as low as $6 and as high as $149. Our primary plugins were priced at $29, $49, and $82, and just one was priced at $149.

As a general rule, we came up with the following guidelines on picking new plugin prices:

  • Plugins that power fundamental aspects of a store, such as licensing, multi-vendor marketplaces, subscriptions, etc, would be priced at the top tier of $199. These were previously priced between $82 and $149.
  • Plugins that are priced at $49 (mostly payment gateways) would be increased to $89.
  • Plugins priced at $29 (email marketing plugins and some other miscellaneous plugins) would be increased to $49.
  • Plugins priced between $12 and $19 would be increased to $29. This was determined to be the lowest price point we’d offer.
  • Bundles, such as the Core Extensions Bundle and the Digital Marketplace Bundle, would be increased according to the new value of the plugins included in the bundle.

In some cases, this resulted in plugins having $10 added to their price tag, and in others the increase was as much as $117.

The results

There are a number of statistics we can look at to help gauge the effectiveness of our price increase and we’ll go over those shortly, but there’s a non-scientific metric I want to look at first.

Team happiness and morale.

I do not need a psychology degree to tell you that the price increase has significantly affected the happiness and day-to-day mood of the team. For more than 12 months, our team has been faced with the problem that is Easy Digital Downloads. Yes, I mean that: the problem that is Easy Digital Downloads. You see, EDD is seen around the WordPress community as this great plugin that is wildly successful and a model to look up to in the commercial plugin ecosystem. While this is a reputation that we take great pride in, the honest truth of the matter is our team has struggled with EDD for months because in many ways it has felt like a sinking ship. We’ve seen stagnated revenue growth (even declines), higher-than-ever maintenance costs, relentless support queues, and a whole series of other challenges that our other two primary projects (RCP and AffWP) simply do not have. In comparison to EDD, those projects are cake walks.

The price increase has been enormously successful in making the team feel good, and the importance of that should never be ignored.

Support tickets

One of the primary results we needed to see in order for this change to be successful was a significant decrease in support tickets. It has now been three months since the price increase, so how’ve we done?

  • New tickets submitted: down 0.2%
  • Total tickets handled: down 43%
  • Total customers interacted with: down 35%
  • Conversations per day: down 42%

The total number of tickets submitted barely changed, but the other three statistics are incredibly significant. A 42% decrease in the number of tickets handled each day. That means EDD handled 10-15 fewer tickets every day, which translates to a considerable less amount of time spent working on tickets for our team. We have an average handling time of 5 min and 49 seconds per ticket, meaning we have removed one to one-and-a-half hours of support work per day by increasing prices.

Assume, for a moment, that we pay $25 per hour for support technicians. Removing 1.5 hours per day equates to approximately $37.50 in savings each day, or, when extrapolated out, approximately $13,687 per year in reduced support costs (if assuming zero volume change).

Revenue and sales

Along with a decrease in support burdens, we hoped the price increase would also provide a much needed boost to our monthly revenue. As mentioned in my 2016 in review post, Easy Digital Downloads operated at a loss for much of 2016, so increasing our revenue was an important measure on the success of the price increase. If we managed to decrease support and increase revenue, we’d consider it a home run.

To gauge the effect the price increase had on revenue, I decided to compare three different time periods:

  • January to February, 2016
  • August to September, 2016
  • January to February, 2017

These time periods are good representatives of our average revenue as they do not include any special promotional sale periods and they allow us to compare similar periods from before and after the price adjustments.

The summaries below provide a good overview of the revenue statistics for each of the time periods used for this comparison.

January to February, 2016:

  • Sales (including free): 3,861
  • Refunds processed: 106 – $8,765.40
  • NET revenue: $100,530.39
  • Average order value: $28.31
  • New paying customers: 664
  • Average value for new paying customers: $131.30

August to September, 2016:

  • Sales (including free): 3,930
  • Refunds processed: 74 – $4,454.95
  • NET revenue: $100,262.55
  • Average order value: $26.65
  • New paying customers: 565
  • Average value for new paying customers: $116.57

January to February, 2017:

  • Sales (including free): 3,009
  • Refunds processed: 65 – $7,530
  • NET revenue: $114,376.70
  • Average order value: $40.57
  • New paying customers: 373
  • Average value for new paying customers: $154.95

There are a few primary changes I’d like to highlight here. First, notice that the NET revenue increased by ~$14,000 in 2017 compared to the two 2016 time periods. With that NET increase, however, the total sale count decreased significantly, by more than 800 in fact. This also resulted in our average order value increasing from $28.31-26.65 to $40.57.

The total amounts refunded also possibly suggest that higher value customers are less likely to request a refund, perhaps because they do more ample research before committing than lower value customers.

This change also caused our average customer value (for brand new customers) to jump up to $154.95 from $131.30 and $116.57.

We are only part of the way through March, but the numbers are already looking even better than January and February. This is partly due to the promotional sale we ran for the end of winter, 2017. We shall see if the remainder of March and April hold up with the trend so far.

The price change has also had an interesting effect on commissions amounts that we pay to 3rd party vendors. In 2016, we paid an average of $16,000 per month to 3rd party extension authors. For February and January, this average has dropped to a little over $12,000 per month. While this is not an overly positive change for most extension vendors, it is a change that we see as an overall positive change for our company. This change primarily happened because of a decrease in the total sales, though it is also due in part to us reducing the number of 3rd party products we sell through the site. We have repeatedly learned just how difficult running a multi-vendor marketplace is and, as a company, we’ve determined that is not something included in our long term goals so we have continually worked to reduce the number of 3rd party vendors we directly work with. I hope to share more on various changes we’ve made over the years that have affected vendor commissions soon.

When combining the increase in revenue with the decrease in support burdens, this price change has so far appeared to be incredibly positive for us. It is a single move that might just be one of the most important changes we have ever made.

Customer response

Gauging the success of a price change based on customer reactions provides some really interesting insights. Using customer satisfaction as a metric, however, is something you must be careful with. In much the same way that star ratings tend to highlight the most unhappy and, oftentimes, unreasonable customers, the customer reactions to price changes typically show those customers that are the most unhappy. It’s unfortunately rare to hear from the happy customers or those that support your price change.

Within hours of pushing the price change live, we received our first reaction from a customer that who been considering a purchase during the time we were updating the prices:

Can you please confirm what is going on? How price jumped to the sky in a matter of seconds, I’m client of you and want to include multi-vendor option, it is even an effort to invest those 91 USD.

That reaction is fully reasonable, especially if he’d already added the items to the cart (our system could not account for already-in-cart items).

The second reaction we received:

Did the price of the Recurring Payments plugin really increase from $83.00 to $199.00 since January?? This was an unpleasant surprise. :/

Technically this was true, though with a brief explanation from Sean, her reaction completely turned around:

Awesome. Thanks for the explanation. I’ll look forward to exploring the features.

This customer did end up completing her purchase and has not contacted us since.

So within a few hours, we’d had two negative reactions but one of them turned into a positive experience for both parties. Over the next few weeks, we continued to receive emails from customers reacting to the price change. Many customers, interestingly, asked if the price increase was some kind of error.

Is there an error on your website or did your price in the last week just over double in cost? I was looking at making a purchase when I just did a refresh and saw the huge price increase.

We knew we’d get a decent amount of  flack for our price increase, especially as we chose not to alert customers (new or old) of the price increase before it happened. Whether this was the right choice or not, it was one we made intentionally. We felt there was a good chance that publicly mentioning our price increase before it happened would simply provide a place for people to pile negativity on us, and it would create a permanent record of that negativity for others to stumble upon. Doing it silently was like ripping the bandaid off in one fell swoop. It’s done, it hurts, but then it’s forgotten a short time later.

I still don’t know if doing it silently was the right choice, but there were numerous customers that were irate because of that particular decision. One person’s response was perhaps the most difficult to stomach. They started out perfectly reasonably:

I am in the process of renewing my plugin licenses again, everything looks good but I noticed that you’re now charging $199.00 (139.30 discounted) for Software Licensing? What is up with that?

I paid like $42 last year and certainly can’t afford to shell out $140 or more every year for a plugin. Not to mention the additional $40 every year for the other EDD plugins I’m using…

Please, tell me that a 200% price increase is some kind of mistake..

To that I gave a calm, collected, though perhaps too generic response, which really did not go over well, as can be seen by his reply:

Wow, so calm and collected.

Well, regardless of what YOU think about it:

1) It’s a 350% price increase (!!!)

2) It’s called gouging the customer

3) It’s called betraying all those people who got on board for 350% less, thinking that, even if the price increases, it will remain an affordable deal despite the annual renewals

4) You should grandfather existing customers at the original price instead of screwing them over

5) I expected much more from you, Pippin.

6) Maybe it’s time to create a similar competing plugin, sounds like it’s a very lucrative market, and would be much less expensive than getting screwed for a 350% price jack.

7) You won’t get away with it

8) It was a horrible decision

9) Even if I do renew this year, I’ll be looking for a complete replacement of the very overpriced EDD plugin suite that I have to keep paying for, over and over and over and over again.

10) Raising prices by 5%, 10%, or even 25% is reasonable. 350% is just greedy.

11) Do your current customers get 350% more value? Nope. They get the same old thing, only YOU benefit.

12) This list will be the outline of my next blog post

13) A textbook example of a bad move, how not to raise prices, and how to screw over your customers.

Seriously unbelievable move. I was all on board with you guys. Not anymore.

350% price jack = unbelievable gouging of your “valued” customers.

I could go on and on, but I’ll save it for the post.

I have had a fair share of people throw derogatory remarks my way, but this one was a bit different. This felt incredibly personal because it came from a person I’ve respected and looked up to for a long time. In fact, this response came from one of the very first people I looked up to in the WordPress community. Having them express their extreme displeasure at my decision to raise prices and method with which we chose to implement the change was painful.

It should be noted that we did grand father in all customers that had an active subscription (one that automatically renews). The only affected customers were those with manual renewals and new customers.

When you get these kind of reactions, it’s important to keep a fact in mind: companies do not need to justify their prices.

Perhaps the most telling thing from all of the reactions we received was just how horribly undervalued Easy Digital Downloads (and similar platforms) are in many customers’ minds. Here we had a customer that was seriously unhappy about paying $140 per year for plugins that provided the functionality they needed to operate their own store. Previously this customer had paid just $42 per year to run their store with EDD.

I’ve had friends, colleagues, and advisors tell me our prices have been too low for years, and I couldn’t agree more. It is absolutely crazy that we’re more accustomed as a society to pay $5 for a latte from Starbucks, which we will consume in a matter of minutes, than we are to pay $12-$20 per month for platforms that allow us to operate our businesses. We are accustomed to paying $80-$100 per year for subscriptions to Netflix and Hulu but we react with revulsion and disgust when a company asks for $150 per year to provide software that businesses literally rely on to bring in their own revenue. In the United States (where the customer above lives), we’re used to paying $50-$100 per month for cable TV subscriptions, but we expect software to be provided for so much less.

As a world, we are better at paying for things that rot (figuratively and literally) our insides than we are paying for things that help us provide for the health and wellbeing of our families and employees.

This disparity in pricing expectations is asinine. Unfortunately, huge companies like Apple and Google have perhaps single handedly helped to create this through the rock-bottom prices of their respective app stores. Between the 1980s and early 2000s, it was common for video games, which take hundreds of hours to create, to cost $40-$50. This price was normal and expected. Once the app stores rolled around, however, expected prices dropped so low that companies now get practically eviscerated if they try and charge just $10 for a full length game in the Android or iOS app stores.

Quote from a review of Super Mario Run:

With a £7.99 price tag, Super Mario Run certainly isn’t cheap, but it’s easily one of the best smartphone games around.

Isn’t cheap? Seriously? It’s roughly the cost of just two lattes or one-three pints from many pubs, both of which are gone within a matter of minutes.

It’s high past time software providers charge appropriately based on the value they provide. If we cannot even ask for a decent price, how can we possibly continue to build platforms that power the web and the world around us?

My final reply to the angry customer was lengthy and has served as a good sounding board as I worked through this reflection post. I ended with:

Perhaps our definition of “appropriate” is different, but the last time I checked, EDD provides me (with the ability to run my stores) far more value than any monthly TV subscription or coffee service. Would I pay $500-$1500 per year to operate the stores that provide for my family and employees?

Absolutely.

Perhaps it was my explanation of why we chose to increase prices so severely or perhaps it was the price disparities provided that convinced this customer, but they did end up sticking with us.

Thanks Pippin.

This makes sense, I understand where you are coming from.

I went ahead and upgraded. The renewal discount always is appreciated.

Thanks for the great response. Enjoyed it.

Going forward

At this point, we are very happy with how the price change has worked out for us and Easy Digital Downloads. We were happy enough, in fact, that we decided to implement a similar price increase on Restrict Content Pro and AffiliateWP, which went live on March 1, 2017, just a few weeks ago. We did end up making some adjustments to how we rolled out those price changes and so far the changes appear to have worked well. It is too early to tell just how effective they will be, but we are confident that it will prove to have been the right choice in 3-6 months.

Do you have thoughts or reactions? I’d love to engage with you in the comments.

The monster that is a poor database schema

Step back in time two, three, four, or even 10 years and take a look at the development decisions you made then. What do you notice about them? Unless you are a one-in-a-million statistic, you probably look at those past decisions and say to yourself what was I thinking?! Why did I do it that way?! Welcome to the real world of actual development.

As developers, we grow and learn over time; we get better at making design pattern decisions; we get better at writing performant code; we get better at all aspects of development.

Take a look at any project that has been around for a number of years and you will find gremlins hiding in its shadows and crevices. There will be internal APIs that are convoluted; there will be data structures that make zero logical sense; there will be function names that seem asinine; there will be blatant problems and it will appear that these are the results of poorly made development decisions. While this is sometimes true, it is far more likely that these gremlins are actually the result of inexperience that leads to a lack of foresight and understanding of the future consequences of non-well-thought-out designs.

Smooth resolutions of bad design patterns

Imagine a project that begins as a small, internal system for doing one thing and only one thing, and imagine it as a project you build specifically for yourself. Due to the nature of it being a small, personal project, it is likely that you will take short cuts; it is likely you will make some decisions simply because Y provided a quicker solution than X; it is likely that you will name variables or API methods poorly; and it is guaranteed that you will make some decisions that have a severely negative impact on your small, personal project four years later when that project has grown far beyond a simple, personal project.

This is the reality of the real development world and the truth for all projects that grow over time. Poor data schemas and difficult APIs are the skeletons in our closets, the spider webs behind our furniture, and the ghosts in our machines. They exist in every project and are a natural product of development growth.

The real achievement is not in building a project with zero gremlins, it is learning how to get past those weaknesses and poor decisions in a smooth way that has little to no negative impact on the users of the project.

Let’s go back to the imaginary project above for a moment. Assume that when first building that project you made the decision to store large amounts of data in a poorly designed database schema, or perhaps even a database with zero design schema that applies to your project. At the time this database schema worked fine because it was easy and, after all, it was only you using the project, so who really cares? Now fast-forward four years and imagine that your project is now used by over 50,000 websites and tens of thousands of users and hundreds or even thousands of developers. Each of these users makes use of the project in a slightly different way and each of the developers builds new tools on top of the project. At this point those poor design decisions (or perhaps even the complete lack of a “design” decision) begin to have negative effects on the project by reeling their ugly heads and presenting your users with severe limitations and scaling issues.

Bad data schema designs can result in severe performance issues. Poor API design can make it difficult for other developers to use or extend the project. Poorly thought out relationships within your code and your database can become the elephant in the room that no one wants to talk about but are abundantly clear and really start to get in the way.

The question that all developers need to ask at some point is this: how do we get past the design decisions of the past so we can continue to grow and excel in the future?

This is precisely what my team and I are working on for Easy Digital Downloads now.

Quick and easy in the beginning

Four years ago, when Easy Digital Downloads was brand new, I made some poor design decisions related to the database structure used in the plugin. Relationships between various pieces of information stored by the plugin were created haphazardly and we chose to rely on the data structures provided by WordPress core. This means that all of our eCommerce data (payment records, order items, order meta data, customers, etc) were stored in the wp_posts and wp_postmeta table. At the time this worked fine. It was easy, quick, and more than flexible enough for what we needed. What I failed to see, however, was just how cumbersome storing eCommerce data in the core posts table was going to be once the plugin scaled up to a lot of users and large websites processing significant sales volumes.

The decision to use wp_posts and wp_postmeta for our eCommerce data is a decision I regret and one that has created significant challenges for us, but none of the challenges are so significant that we cannot get past them.

When faced with the reality of bad data schemas, there are really two ways to address the problem:

  1. Simply live it with and do what you can to mitigate the problems
  2. Work out a plan for resolving the problem completely by re-building the data schema from the ground up

The first option is the easier of the two for many reasons. First, it requires the least amount of change. Second, it avoids the significant risk of severely breaking backwards compatibility. Third, it does not require any cooperation with third party developers that have built on top of your bad data schema.

Option two, however, can be much better for the health of the project in the long run. It does, however, present a serious risk to the project’s health and continued adoption by users and developers. When making significant changes, backwards compatibility must be kept an absolute priority. If backwards compatibility is ignored or implemented poorly, it’s very possible that the migration process to the new and improved schema will go poorly, resulting in developers and users abandoning future reliance on the project. It can also cause a support nightmare if hundreds or thousands of websites are suddenly breaking due to the changes implemented.

Building a backwards compatibility layer can be challenging, but it is a challenge that will be worth it in the end. Frankly, I would go as far as to say you should not even consider resolving a bad database schema if you do not plan to also introduce and maintain a complete backwards compatibility layer. Choosing to ignore backwards compatibility in a scenario like this is negligent and harmful to your users. With that in mind, how does one go about building a backwards compatibility layer? There are really a few parts of it.

Abstraction layers for backwards compatibility

The very first step in providing backwards compatibility is to ensure there is an abstraction layer for your database. An abstraction layer is simply an API for interacting with the database. It provides developers standardized methods for reading and writing to the database without writing actual queries. For example, WP_Query is an abstraction layer for the wp_posts table that provides methods for querying data from the posts database without writing any actual SQL. Why is this valuable? There are numerous reasons but for this particular discussion, it provides project maintainers the ability to change the database schema without disrupting external projects that utilize the data.

In Easy Digital Downloads, we have built abstraction layers for payments, customers, and products. These abstraction layers are fundamentally important when it comes time to change the underlying database structure.

Let’s look at a quick example.

Assume we wish to retrieve the first and last name of a customer record. In the current version of Easy Digital Downloads, both the first and last name are stored in a single column in the database, but perhaps in a future version we decide to separate them into two columns. Through the EDD_Customer object, getting the name of the customer is simple:

$customer = new EDD_Customer( 47 );
echo $customer->name;

That will output the customer’s full name, such as Elizabeth Johnston.

Where’s the value in this abstraction layer? well, it becomes very apparent (at a simple level) when we consider the following possibility.

Assume now that the EDD_Customer object was not originally available so a third party developer decides to directly query the database for the customer’s name:

echo $wpdb->get_var( "SELECT name FROM edd_customers where id = 47 LIMIT 1;" );

Since storing both the first and last name in a single column was probably a poor decision, we later on decide to separate the names into two columns, first_name and last_name. In this scenario, the first example, which relies on the abstraction layer of EDD_Customer, will continue to function exactly as is. The second example, however, will suddenly fail because the name column no longer exists.

This is a simple example but it does accurately illustrate the importance of having abstraction layers. Consider now how important it will be when you’re preparing to change not only a single column in the database but the entire database. Every single column. Without a proper abstraction layer, making that transition will be nearly impossible.

If an abstraction layer isn’t already present, build one immediately. That’s the very first step anytime a database schema needs to be changed.

After you have an abstraction layer in place, you need to work hard to ensure that everyone uses it. If a platform has been around for a while, it will be necessary to push and shove work hard to encourage developers to update their code to use the abstraction layer. This is something we’ve begun to do for the recent introduction of EDD_Payment.

With the creation and adoption of a good abstraction layer, the process of migrating to a good database schema becomes a lot simpler, though it is still a very, very significant task that has a lot of challenges. For example: how does a project maintainer account for all of those developers that ignored or simply didn’t see the news about the abstraction layer? Or how about all of the project’s users that did not update to the latest versions? For those, the best one can do is provide as much backwards compatibility as possible.

For Easy Digital Downloads, building a backwards compatibility layer will involve a number of factors. First, we will have to intercept and re-route every single call to get_post_meta() that is made against all EDD payment metadata. Thankfully, the WordPress metadata API includes number filters and action hooks that make this possible. Second, we will have to intercept and re-route every query to the wp_posts table that contains the edd_payment post type. Again, the prevalence of filters in the WordPress core codebase will provide ample ways for us to do this. Third, we will also have to intercept and re-route every write and deletion to the wp_posts and wp_postmeta tables for all EDD-related queries.

Slow and careful

This kind of migration process takes a long time and needs to be executed with extreme care. We will likely spend 6-12 months building this backwards compatibility layer. The most significant challenge for it will not be writing or handling the re-routing of queries; the real challenge will be finding and knowing all of the data points that we need to include. For example, we know very well what all of the meta_key values are that we use in Easy Digital Downloads and all of the officially maintained extensions. What we don’t know, however, is the meta_keys that third party developers have used in their own extension. There are some assumptions we can make, such as assuming that any meta_key containing “edd_” belongs an EDD plugin, but we’ll never be able to cover 100% of the data out there.

In the end, there should be several goals in defeating the monster that is a bad database schema:

  1. Introduce a new and well thought-out schema that resolves all problems the original schema created
  2. Introduce and maintain complete abstraction layers for the database schemas so that future changes are less difficult
  3. Make the transition from old to new schemas as smooth and invisible as possible
  4. Protect the user base that does not have the luxury of updating or is simply unaware of updates by providing complete backwards compatibility

There is no reason poor database schemas cannot be improved, they just have to be done so slowly and with great care.

Note: would you like to learn how to build a database abstraction layer or read more about the reasons for why you should use custom tables in WordPress? I have a complete tutorial series on the subject.

Hardships and victories in four years of eCommerce

Four years ago, I started out on a journey to build an eCommerce plugin for myself so that I could sell a few of the plugins I was building. A plugin to sell plugins, how meta. As with most of the projects I choose to dedicate my time and energy to, Easy Digital Downloads was built for me by me but in such a way that others could make use of it if they wished.

Today, Easy Digital Downloads is installed on over 50,000 websites, has reached nearly one million downloads, and has grown to a sustainable business that supports the livelihood of an ever-growing team comprised of full time employees and active contractors. I don’t think I ever thought we would be where we are today four years ago. It has certainly been an adventure and continues to bring new challenges and excitement every day. I would like to take a few minutes to look back at some of the challenges, hardships, and triumphs we experienced in getting to today.

Usually in these types of posts, I primarily cover the revenue numbers and other accomplishments. While I’d like to still include those in an effort to be ever transparent, I want to focus primarily on some aspects of this journey that I feel are more important and provide better value to others working on similar projects.

We are all imposters

Easy Digital Downloads has done well for me and my team, I will not deny that. We have seen upwards and continuing success constantly over the last four years. We have consistently grown our team and have managed to stay profitable as we do. Easy Digital Downloads is 100% bootstrapped and fueled by profit. We’ve never taken out loans to meet payroll or cover development investments and we do not plan to change this in the future. We are here and here we will stay. These are facts I’m very pleased to claim, however . . .

We are all imposters. We’re constantly exposed to the success and greatness of others that we place ourselves ever in a shadow of doubt. It is easy to look at the accolades of products and developers in similar ecosystems and compare your own success to them, and in comparison, look sadly upon yourself and wonder where you went wrong.

I watch spectacles like the recent WooConf and am in awe of their success. What is it that lead projects like WooCommerce to be so incredibly successful? I don’t intend to actually try and answer this question because it’s due to many, many reasons and debating their success, or the success of anyone else, is not the purpose of this post, but seeing this kind of success always makes one be a bit introspective.

It has been a true pleasure to watch the team behind Ninja Forms take their plugin from a small form builder that did okay to a truly dominant player in the market. I have watched, and been behind the scenes, as they have gone from a few downloads per day to thousands of downloads each and every day. They recently passed 2,000,000 downloads and are now active on over 400,000 websites. I love to see them excel and succeed like that, but then I wonder why it is Easy Digital Downloads has not reached those kinds of numbers? Sure we have passed 50,000 active installs and are approaching one million downloads, but our growth pales in comparison to Ninja Forms.

How about WP Job Manager, a side project for Mike Jolley? It has more installs than EDD and (from what I hear) has a higher monthly revenue than we have ever had.

It’s incredibly easy to get down on ourselves when watching the success of others fly past us. I don’t mean to belittle what we have achieved as I firmly believe our team has done great things with Easy Digital Downloads and I’m exceptionally proud of what we have produced and where we are going in the future. I do not bemoan others for doing better; no, I applaud them for their efforts and the rewards which they have truly earned.

I am not blind to my own status within the WordPress development community. I am very aware that many look up to me and my team for what we’ve done, so do not think these are the words of an ignoramus or someone that is blind to their own success. I believe it is important to understand that every one, no matter how high they have climbed and no matter how many people look up to them, is susceptible to feeling like an imposter among giants.

A bold face lie would be to tell you that I’ve never felt down or burdened when looking at the success of others.

About a year ago, a friend said something to me that had a great impact on me. He said something along these lines:

You are miles and years behind WooCommerce.

At first I was a bit disoriented. I didn’t really know how to take that. For the last three-four years, I had been working incredibly hard to make Easy Digital Downloads what it is today and here was my friend telling me I had essentially failed because EDD was nothing compared to WooCommerce. We didn’t have the massive customer base they did; we didn’t have the millions in annual revenue; we didn’t have media coverage outside of the WordPress world; we were not even a blip on most eCommerce radars. We were nothing. When he said that, he did not mean it to belittle or criticize our efforts; he was simply pointing out that if we wanted to dominate, we had to get moving and that we should consider partnering with those that could really propel us forward.

It took me a few minutes to (or perhaps months or years) to come to terms with that statement, but once I did, I realized something incredibly important. It did not matter.

At Pressnomics 2016, Brian Krogsgard gave a presentation on the state of business in WordPress. One of his poignant comments was that not everyone wants to be the best or the biggest. Not everyone is striving to win this competition that we’re all seemingly in, whether we choose to or not. The competition of who is the best, who has the best product, who makes the most money, who has the biggest and most badass team.

In response to my friend’s comment, my answer is this:

I know, and that is okay. Our goal is not to be the biggest or to own the market. Our goal is create something awesome and love doing it.

If your goal is to be the biggest or the most badass or to have the most market share, power to you. That’s awesome. I salute you, but that is not my goal and that is not the goal of my team or the goal of our products. Easy Digital Downloads is not the biggest, it is not the best, it is not the most valuable, and all of those things are entirely okay because those are the not accolades we strive to achieve. Instead, we strive to create a great product that customers love to use and one that allows our customers to create their own successful businesses online.

One of our customers told me recently that Easy Digital Downloads had changed his life. He said it had provided him the means to sell his plugin, which had grown to a point where it provided 100% of his revenue and enough to employ several full time team members.

That is the difference that we strive to make. Those are the accolades we are after.

I, and millions of others, feel like an imposter every day. If we allow ourselves to get caught up in that, it will consume us, so remember: it’s not about beating everyone else. Someone will always do better than you, and that is okay.

Own your product or be owned

A few months ago, I published a blog post titled Be a little selfishThe premise of that post was that in order to thrive, both personally and professionally, we all have to be willing to be a little bit selfish and make sure that we are taking care of ourselves. I stated that I felt it was fundamentally important to be ever cognizant that if you or your team is unhappy or unhealthy, you cannot possibly run a company that maintains happy customers, and I stand by that belief today.

Of all challenges we have faced in the last four years of building Easy Digital Downloads, the realization that we had begun to lose control of our product was perhaps the hardest and most painful to deal with. Last summer we began to realize that we had grown too lax with how well we controlled the extensions and developers that we actively promoted within the Easy Digital Downloads ecosystem. We had permitted too many subpar plugins to be published on our marketplace and we had allowed ourselves to become victims of those developers and our own inaction.

Early on, I made the decision to promote Easy Digital Downloads as having an open marketplace that any developer could get their EDD extension listed in. I wanted all developers to have the opportunity to piggyback off of the growing market that Easy Digital Downloads was creating. It made sense to me at the time: we promote other developers and other developers build things for us. Easy win! What I had not anticipated, however, was the severe challenges that running an open marketplace presents. I had no idea that the management, review, and support involved with publishing dozens of plugins from other developers would be so incredibly challenging. Looking back on it, I was clearly naive. How could that not be monstrously challenging?

Three months ago, we made a very deliberate decision: we were here to own our product. We did not set out to provide a platform for customers to set up sites that worked okay; we set out to build something awesome, and in order to do that, we had to take firm control of what we produced, what we supported, and where we chose to exert our efforts.

That decision meant that we were no longer running an open marketplace for any and all extension developers. Today, we still run an extension marketplace for Easy Digital Downloads, but we don’t allow just any one in. We are very, very choosy with who gets a plugin published on our site. Along with much stricter publishing guidelines, we also thoroughly evaluated every single plugin sold through the site and discontinued a large number of them for one reason or another. At one time, Easy Digital Downloads boasted over 300 extensions available in the marketplace. Today it has 164. In three months, who knows. I’d like to see the number go down actually.

Before we chose to take better control of our product, we were fueled by the idea that more is better. More extensions, more options, more choices. These can only be good things. Right? No! WordPress core got it right:

Decisions, not Options

When making decisions these are the users we consider first. A great example of this consideration is software options. Every time you give a user an option, you are asking them to make a decision. When a user doesn’t care or understand the option this ultimately leads to frustration. As developers we sometimes feel that providing options for everything is a good thing, you can never have too many choices, right? Ultimately these choices end up being technical ones, choices that the average end user has no interest in. It’s our duty as developers to make smart design decisions and avoid putting the weight of technical choices on our end users.

By producing every option under the sun and striving for even more options, we were crippling our users and crippling ourselves. What we thought was benefiting us, was actually killing us. We recognized this early this year and took action. To say that making a conscious decision to re-take control of our product made a difference would be an understatement. Since making the first set of changes that lead to better ownership of our own platform, revenue has increased, customers are happier, support tickets are down (and/or easier to solve), and our team’s morale is greatly improved. That’s the definition of a good decision if you ask me.

Highlights and victories

Over the last four years, the Easy Digital Downloads team has had some great highlights that I’m exceptionally proud of. I cannot cover everything, but there are a few I’d like to tell you about.

Continual growth

Since Easy Digital Downloads was first launched, we have experienced nearly constant growth. Each year we have done better than the previous and have experienced monthly growth more months than not. The graph below shows how EDD’s revenue has increased over time:

EDD Revenue over time

2015 saw only little growth, and a bit of fluctuation up and down throughout the year, but still ended very well, and 2016 has proved to be on a good path so far.

Revenue by year:

  • 2012: $25,500
  • 2013: $203,000
  • 2014: $489,000
  • 2015: $576,000
  • 2016 (so far): $194,000

While we have managed to continue the upward trend of revenue through https://easydigitaldownloads.com, the true indicator of our efforts will come in March of 2017. Last month we turned on automatic renewals through subscriptions for every purchase made through our website. This will have a significant impact on revenue next year.

So far this year, only 19% of our revenue has come from license renewals. Because license renewals have always required a manual process by customers, the renewal rate for license keys is incredibly low. While some customers do not renew because they choose not to use the plugins anymore, a huge portion of customers never renew their license keys because it’s a hassle, they miss the emailed expiration alerts, they think “I’ll do that tomorrow” and then forget, or some other reason that results them in dropping out. We managed to increase our renewal rate quite significantly by being much more aggressive with our email and license expiration notification strategies, but even those have only a minimal impact compared to what automatic renewals will have.

Imagine for a moment that a site that requires manual renewals has a renewal rate of 15%. Now convert this to an automatic renewal system, and take a guess at what the renewal rate will be. Hint: it’s significant even on the lowest estimates.

While only time will tell, we expect to nearly double our revenue in 2017 through automatic renewals alone. That’s the impact of automatic renewals through subscriptions.

Transitioning the extension sales to a subscription model took nearly a year’s worth of work and planning, but it was (and will be) worth the effort. As a happy side effect, the work we did on our systems to make subscriptions possible also literally more than doubled the monthly revenue of one of our more popular extensions. Talk about dog-fooding for the win!

Growth is about more than just revenue though. Our download counts on WordPress.org have been steadily increasing as well, as have the total number of active sites. We recently passed 50,000 active sites. The numbers below represent the total at the end of April each year.

  • April 2012: 1,585
  • April 2013: 83,763
  • April 2014: 278,002
  • April 2015: 584,058
  • April 2016: 994,820

I have no idea how many sites we’ll have running Easy Digital Downloads by this time next year but I am excited to see how far we can reach.

Traffic to easydigitaldownloads.com has also been on a near constant rise.

EDD site sessions

EDD site pageviews

Something interesting that I had not expected and only discovered when looking at the stats as I was writing this post, is the significant increase in page views and sessions  between May and June, 2015. Remember what happened on May 19? Automattic announced the acquisition of WooThemes and WooCommerce. I am not going to dive into hypotheticals or make proposals for why our traffic and page views went up right then, but I do find it super interesting 🙂

Overcoming technical debt

Perhaps one of the most difficult aspects of any long-term project, at least from a developer perspective, is dealing with technical debt.

Easy Digital Downloads has had its fair share of technical debt. It’s a problem that all projects spanning numerous years encounter, but I’ve come to realize that the technical debt in an eCommerce platform is significantly more severe than most projects. This is for a very simple reason: eCommerce platforms are depended on by businesses to keep their business running. Changing things just to get rid of technical debt is simply not an option in many cases. You have to constantly keep old data structures, or API methods, old everything in mind so as to not disrupt businesses’ revenue flows.

If an update for a purely presentational plugin goes awry and affects the display of a site, the revenue of the business may be affected due to unprofessional appearance, but if the update for an eCommerce platform goes awry, sales potentially grind to a complete halt. Obviously this is not always the case as not every update-gone-awry is so drastic, but it is an important lesson to keep at the forefront of every developer’s mind when building eCommerce.

In 2015 alone, we managed to eliminate a huge amount of technical debt that had been hurting our growth, hurting our flexibility, and making it more difficult and cumbersome for 3rd party developers to build on top of Easy Digital Downloads.

Later in 2016, we have continued efforts planned to even further remove some of our technical debt, and that excites me.

Getting great people

In the end, business is about people. Or perhaps I should say great business is about people. While I do not know if we fit in the category of a great business, I do know that we have managed to build a great and talented team around Easy Digital Downloads.

I have never felt qualified by any measure to lead a team but for some reason, these individuals let me keep my job, and for that I am incredibly grateful and blessed.

Today, the Easy Digital Downloads team is spread across four countries and even more backgrounds.

Sean Davis, Andrew Munro, Chris Klosowski, Topher DeRosia, John Parris, Chris Christoff and Phil Johnston are the folks working day and night to keep Easy Digital Downloads running. Honorable mentions go to Sunny Ratilal, Dan Griffiths, Kyle Maurer, Barbara Atkinson, Michael Beil, Spencer Finnell, and Adam Pickering. We also work actively with an ever-growing list of contractors and 3rd party developers to make improvements across the Easy Digital Downloads ecosystem.

These folks have all of my praise and deserve endless thanks. They make me better in so many ways and I’m humbled to get the opportunity to work next to them.

Onwards and forward!

Perhaps the most exciting aspect of the last four years for me, is the realization that we’re only just getting started. At times I feel like I’ve been working on Easy Digital Downloads my whole life, but it’s really been a brief period and we have a long runway in front of us.