That is a question we often get. Particularly considering our background at AdventNet, where we offer more than 60 software products you can download, this is a very interesting question. About 2 years ago, we seriously considered this option. In fact, both Zoho CRM and Zoho Virtual Office (which later got renamed to Zoho Mail) were offered as downloadable products for a period. But we discontinued the product to focus on the web service – thereby hangs a tale.
To cut the story short, the answer to that question is “We would love to offer a product, but sorry we can’t”. I don’t say that lightly, knowing how AdventNet makes its living. Zoho is approaching its second anniversary, and we have accumulated considerable experience now in providing web services. We also have a 11+ year experience in shipping and supporting software products. It turns out these two are quite different animals. Trying to do both at the same time is a mistake – and having gone through that a couple of times, we are in no hurry to repeat it.
First there are the obvious issues everyone knows about: a software product means versions, patches, upgrades and so on. Then there are platform dependencies – right about now, many AdventNet products are getting support questions on Windows Vista, which we haven’t officially supported in every product. Compared to the combinatorial possibilities inherent in products, web services are a piece of cake. In this post, I want to highlight some not so obvious differences.
When we write a product, we pay attention to issues like download size, how much CPU/RAM does it take to run, compatibility with other software that could be running on the user’s machine and so on. We know that we cannot assume that our product would be the only one running on a machine, so we have to play nice. We have to assume a certain minimal configuration, which cannot be too large. For example, assuming that a user would have 4 GB of RAM minimum could be disastrous. But in web service code, on the server side specifically (where much of the code resides), we can and should assume that an entire server is available for that particular service. There is no prize to be had for playing nice on the server side. And we can test the server code in just the one configuration – and within reason, that configuration is in our control. So if a minimum of 16 GB RAM is needed, well, 16 GM RAM it is. In fact, it is stronger than that. It pays to write server code assuming and optimizing for a lot of resources. In memory caching of objects is an example of such an optimization.
N > 1
A second non-obvious difference is what Joe Gregorio has eloquently called N > 1. In writing a product, you assume that it will run on one computer system. Even if a product is capable of running in a distributed fashion, a default mode where it runs on one system is essential – otherwise it would massively inconvenience users who want to test the product. With a web service, it is actually counter-productive to make server code run on one system. We can make all kinds of optimizations, if we can assume multiple servers would be available. Just to give one example, we can run non-user facing servers “hot” all the time (at permanently high CPU utilization), while keeping user-facing servers “cool”. This extra degree of freedom makes you write code differently.
Service Reliability != Component Reliability
This is an interesting one and a corollary to N > 1: when you ship a product, your product is only as reliable as its least reliable module or component. If you have a slow memory-leak in one rarely accessed module, it will still impact the reliability of the whole system. In a web service, you can “handle” that kind of problem differently – simply restart that component every so often, before it has a chance to leak any memory! That may sound weird to anyone coming from a traditional software product background, sometimes periodic restart may be the best solution. You depend on the fact that more than one instance of that module is available, and load can be moved to other instances when one instance is restarted. So the entire service is available, but its components periodically become unavailable, intentionally.
In theory, it might be possible to take these into account all these in designing the code. A future operating system or perhaps more appropriately, a middleware stack could address these differences, and self-configure itself based on whether it is running a product or a service. We are quite far from that goal today.
Now, a note on Zoho Mail. The reason it got delayed was it fell victim to the product vs service distinction. We are proud of our Zoho Virtual Office product – it packed a lot of functionality in a compact download. But alas, that focus on product also made the web service difficult to optimize for. We could make serious progress on the web service, only after we decided to discontinue the product (my sincere apologies to customers we disappointed with that decision) and focus our energies full time on the service.