Monday, August 22, 2011

Development Cycles

I don't know how many of you have noticed this, but we tend to go through development cycles with this project. We release an update, there's a flurry of activity as we polish it and fix any lingering issues, and then... silence. We don't issue updates until the next large iteration.

This isn't something I'm proud of, or something I'd like to continue, but I'm afraid it has to be the case. I'm still doing the majority of software writing for this project, and I'm still a student working a few jobs to pay the bills. I still can only engage this project in my "free time", such as it is. That means that the development pushes tend to be around when I can clear out some time in my schedule to knuckle down and focus on this project. We're in one of those times now (summer is awesome, isn't it?).

The impetus for writing this post was because we're coming to the end of this little push. I'll be fixing up the major issues that remain (things that prevent people from using the app), but minor inconveniences may or may not get done. A week from today, I start classes at my college again, and those will be taking up a good portion of my time. Development will continue, but it will be slow, and updates won't be as frequent.

I'd love to say this is a temporary problem, but the future is uncertain. When I graduate, I'll need to take a look at my financial situation and see what my options are. If I can, I'd like to continue writing software. I'd like to be able to devote myself to this every single day. I doubt that's going to be the case (this project is still in the red in terms of money) but it's nice to dream. If I can't do this full-time (which, really, is absurdly unlikely), I'll probably have to continue this cycle.

All I know is that the project has grown in leaps and bounds since last year. I'd like to see similar growth this year. I'm going to work hard on it whenever I can, and hopefully I can get it to the point where other people will start working on it, too.

Thanks for your support over the last year, and I hope you'll stick with us as we stumble our way through this one.

Paddy Foran
2cloud Lead Developer

Friday, August 5, 2011

About the Quota

Seeing as we just started rolling out 2.1, I thought I'd take a moment and try to expound a bit on our quota system, our thoughts about administering it, and the plans we have in regards to it.

Anyone who is not new to this project knows we've been fighting with monetisation since the very beginning. We haven't found a way to make the project sustain itself yet, and so far we've just been burning holes in the pockets of our developers and our community members, trying to keep this service online. When you think about it, it's a bit silly. We have over 12,000 active installs, according to the Android Market. That number's a bit low based on our metrics (doesn't cover custom builds, people using non-Market apks, etc.), but we'll use it as a minimum number we can rely on for accuracy.

We have 12,000 users with the app installed. The server costs $31/month, give or take, to maintain. This app should be sustainable if even one half of a percent of our users donated one dollar a day (keeping in mind that Google takes a cut). Put another way, if every user donated a dollar once every 23 years (again, keeping in mind we get seventy cents of that dollar), the app would pay for itself.

We've tried a couple things. The donations model seemed promising, but there wasn't enough of a steady flow of cash to keep things paid for. We tried ads, but... well, that was a bad idea. Our app wants to get out of your way and not be noticed. Hard to implement display monetisation on something that tries not to display. Our efforts were... well, failures. Since the launch of our ads, we've made four whole dollars. Actually, we've made nothing; we don't get a payout until we make fifty dollars. Which seems unlikely to happen, so we literally got nothing from ads.

Tino (our project manager) and I sat down to think a bit on this and how to make it work. The first important breakthrough we had was that users didn't realise this costs money to run. A lot of you read this blog, subscribe to the mailing list, and follow us on Twitter. And really, thanks for that. We appreciate it, and hope you enjoy hearing from us as much as we enjoy hearing from you. But you're a tiny percentage. Probably less than a percent. Being overly generous and assuming there are no duplicates, we have almost 330 followers on Twitter. Out of over 12,000. So 97% of our users never see our money struggles. Not good.

The second realisation we had was that it's not easy to give us money. Yes, you can run across a donation link. If you use PayPal, that's fairly simple. But if you don't use PayPal or don't run across the link, the barrier is too high. You can buy the donation version from the Market, but you can only buy that once. And if you don't have the Market/can't buy apps on the Market in your country/want to donate more, you're out of luck.

The third realisation we had was that we can't keep this up forever. I'm too busy with classes, my jobs, and iterating on 2cloud to devote myself to writing entirely new software for Second Bit, software that will bring in money to support this. So we're a company whose only product is burning through money like it's that Yule log you see on TV. That leads to bankruptcy and/or server shutdowns pretty quickly. Neither of which is really what we want.

The fourth realisation was that downtime sucks, but some types of downtime suck less than others. For example, if we can fail gracefully and explain that the server is down, that's better than the app just... not working. If we can explain why the server is down, so much the better. And if we can offer a way to keep the app working anyways, then that's probably the best situation we can hope for.

So we came up with a quota. Normally, I hate quota systems, but I am actually pretty excited about this one. I'll get to why in a moment. First, let me explain how it works. One particular piece of our app is the expensive part: the connection between the server and Chrome. As long as Chrome is open, we need to keep that connection alive; that takes some CPU power, and CPU can get pricey. So what we're doing is keeping track of how many of those connections we make. Based on that, we can calculate our CPU usage. Based on that, we can create a "soft quota" to limit how much CPU we use in a day to be something we can reasonably support for a little while with our current funds. That quota is variable; we have an interface to set it based on our available cash on hand and the statistics we have on how many connections/day we're averaging. Our goal is to keep the number of times we exceed that quota a month to one or two, but still be able to pay for everything.

When the quota is exceeded, your links won't open. At all. But we will still store them for you, and open them when the quota resets the next day. Because it's our own imposed quota, we can do that. If that gets too CPU intensive, we may have to turn that off—but rest assured, we'll let you guys know when we're reaching that stage.

This is the cool part, though: you can pay to get around the quota. When you try to send a link and the server is over quota, you'll get a popup explaining that the server is over quota and offering a way to pay. By paying roughly $1 (depending on your country; it's calibrated to be the lowest round number the Market will accept), you gain immunity to the quota. For now, we're saying you get the rest of the day immune. In the future, we may toy with that; you may be able to buy, say, immunity for the next three times we're over quota, as opposed to immunity for a certain amount of time. You may get an entire week for your $1. We're still figuring out that part of this, and hope you'll bear with us and offer feedback. What your immunity buys you is pretty simple: as long as you're immune, you get to use the app, regardless of its quota.

This brings me to our fifth and final realisation, and the reason I'm pretty excited about this quota, instead of dragging my feet. Ready for this? You are not our enemies. We are not here to work against you. You are not trying to take things from us. You don't want us to go bankrupt or shut down the server any more than we want those things. And we know that. And we respect that; we respect our relationship with you. We've worked hard and made a lot of tough decisions about this system to ensure that it would never harm someone by accident. Our payment verification system is less secure than we'd like because we'd rather have ten people slip around the quota than one person get denied on accident, or have the user base jump through hoops. In the end, it's pretty easy to cheat our quota system; the caveat is, we'll know. We just need to manually catch cheaters, which is more desirable than automatically catching cheaters and accidentally catching a couple honest users. We're extending our trust to you guys in the spirit of cooperation; please don't abuse it.

We're also going to be doing a few things to try and mitigate the impact this will have on our users' lives. Our friend Eva has helped out quite a bit on this end. At her suggestion, we'll be randomly choosing one active user a month to be exempt from quotas that month. We're going to take it a step further though; we want to reward people who are consistently paying to get around the quotas. So we're also going to select one user a month who paid to escape the quotas in the previous month (e.g., for October, we'll choose someone who paid in September) and we'll give them immunity for the month. Finally, I'm working on a way to make the cost of immunity go down the more you buy it. Think of it as the bagel card; buy ten, get one free. It's possible that, in future versions, every fourth quota exemption you buy will last a week, and every tenth quota exemption you buy will last a month.

As you can tell, we're trying pretty hard to come up with ways to reward you guys for paying. We're not trying to separate you from your hard-earned money by deception, coercion, or trickery. We just want to keep the server online, possibly recoup some of the cash we've invested in this project over the last year, and maybe even make a modest profit on our hard work. But we want to do it the right way, and we want to do it honestly. We don't want your money unless we've earned it and you're willing to give it to us.

I know there has been a lot of money talk on this blog. You've all been amazing about accepting it on faith. For those of you interested or who doubt the financial claims we've been making, I'm going to release the financial records from the start of the project. All project-related expenditures and project-related income is reported here. I can't promise one of these reports frequently (they take some time to put together, and we'd rather be working on software than compiling financial reports), I'll make a public announcement next time I update it, and will do my best to make it some reasonable frequency, but I can't promise anything.

Thanks for all your support in the last year. If you have questions, comments, concerns, ideas, or cool ways we could reward loyal users, we'd love to hear them!

Thursday, August 4, 2011

2.1: In With The New, Out With The Old

I'm pleased to say that 2cloud 2.1 is nearing the end of its beta phase. Our beta testers have worked hard and deserve a big round of applause for all the testing they've done on such short notice. Really, this project owes a lot to them (especially after the 2.0 debacle—we're pretty sure that won't be happening again).

Here's the important bit: we're going to be rolling out the update to the Android Market and the Chrome webstore at 11pm, EST Friday the fifth. Saturday the sixth at noon (again, EST), the server will begin returning errors. In an attempt to shake off some legacy users who never updated and are costing us some CPU, we've moved hosts. The new extension and Android app default to the new public server: All data from will be ported over to the new server. This doesn't mean much now, but it hopefully will in the future.

I'm really embarrassed about the lack of new features in this version, but hopefully you can forgive that for the other improvements. We're pretty proud of the work we did in the short time we had, and feel pretty good about the base we have to build off of now. We already announced that we're deprecating support for Android 1.5, 1.6, and 2.0 to focus on providing a better experience for the 2.1+ crowd. But we've also done a bit of reworking in our software:

  • We've also gotten a lot more robust. Now our errors actually talk to you! Not literally (though that would be kind of cool.. or annoying), but through dialog boxes. If the app runs into a problem it won't crash or fail silently, leaving you with no idea what's going on (except in very rare cases, and we're trying to remove those one by one). Instead, the app throws up an error with some options. If it thinks an error log will help, it offers to send an error report to us as an email. You can click a button, check the information it will send (it just opens your default mail client), and send it off as a bug report. We'll get back to you with more information and a fix, because it's hooked right into our lovely help system (graciously provided by Tender).
  • We've implemented a quota. I'm not going to talk too much about that here because we've got an entire blog post about it set up for a bit later, but suffice to say it's a bit nicer and more verbose than the server just shutting off and the app ceasing to function with no explanation.
  • The Chrome extension has gotten its icon back! But this is a new, improved icon-on-steroids. It has a status indicator (green for connected, white for disconnected, red for error, blank for connecting) and context-aware clicking. Click when connected to disconnect. Click when disconnected to connect. Click when there's an error for more information.
  • The Chrome extension also has a much prettier install experience. Dylan put his design genius to work again, creating an aesthetic install flow that puts my old hacked-together wizard to shame.
  • This probably doesn't matter to most of you, but we have much better documentation now. Information on the project, on contributing, on the license, on installing or building your own clients... all this and more is available in our lovely README file and our website.
  • All our source is on Github, and is much more structured and readable than it was. We have a long way to go yet—we swear, unit testing is at the top of our priorities! (right next to Firefox...)—but this is a marked improvement over where we were just six months ago. We're going to keep learning and improving, and hope you guys will bear with us. Fork us! We ♥ pull requests!
  • This one's for the developers out there: we're ready to commit to endpoints! We've got the 2cloud-dev mailing list set up for people who want to build this functionality into their applications, and we've got documentation on how to create a client or server on each of the Github repos' wikis (Android, App Engine, Chrome) coming very soon.

As you can see, we've kept busy. We've got a lot of stuff we're looking at for our next versions, too:

  • Chrome In-App Payments
  • Link history in Android and Chrome
  • Device dropdown
  • Native account support
  • C2DM
  • Firefox support
  • iOS support
  • Tablet-friendly!
  • Sending links to friends
  • Binary content (images, videos)

Of course, we're going to try to keep improving our code, fixing bugs, and improving our administration at the same time. Also note, we can't promise any of those features. They're just things that have caught our eye and appended to our wishlist.

We hope you enjoy 2.1, and we hope you'll give us feedback on what we're doing right and what we're doing wrong. Both are useful in their own way.