Tuesday, April 23, 2013

SaaS(Multitenant) Application Design Best Practices

Overviw: Now-a-days with the increasing popularity and penetration of the cloud, SaaS (Software as a Service) is rapidly becoming the preferred software delivery model for organizations across the world - software buyers as well as vendors. In SaaS model, software is centrally hosted by the vendor (service provider) in the cloud and accessed by the users over the Internet using a thin client e.g. a web-browser or a smartphone. There are many business benefits of adopting SaaS. For the customer, it means reduced cost of ownership, fast deployment, no maintenance headaches, and a smaller learning curve leading to a higher adoption rate in the user community. For the vendor, it means reduced cost of customer acquisitions, faster sales cycles, more upsell opportunities and an easier rollout of new features.

SaaS model has emerged to give companies a cheaper alternative to in-house solutions: Software-as-a-Service (SaaS). A client pays a per-user fee for a pre defined period of time to access the solution. In exchange, the software resides in one central location, managed outside of each client. All clients access the same software, though certain features may be enabled or disabled for specific clients depending on what they choose to pay for. As the software is upgraded, all clients receive the upgrade without any physical intervention on their end. Hardware, networking, even disaster recovery are all handled without any staffing costs.

At the core of most reliable SaaS offerings is a well-designed, secure, fault-tolerant database design. Perhaps more so than for their enterprise counterparts, SaaS databases must be able to keep problems isolated as much as possible. While it is true that a database crash could bring down an enterprise application, causing a company to lose productivity until the issue is remedied, a crash of a poorly-designed SaaS database could cause an outage for multiple companies, possibly causing all of them to lose faith in the product and take their business elsewhere. On the other hand, if reliability is favored at the expense of performance, companies may not feel that the application can scale to their needs and will refuse to sign up in the first place. Finally, as a SaaS database will contain data from multiple companies, it is imperative to design it in a secure, isolated fashion. Failing to ensure that no client can see another's data could spell the end for a SaaS offering.
From an engineering perspective also, SaaS is a great way to build and deliver software. It is a perfect fit for software delivery teams that have adopted an agile development model. As the software is centrally hosted, you can:
  • Deliver new features to your customers faster than before
  • Receive user feedback and implement changes in real time
  • Fix production issues quickly
  • No need to worry about any environment dependencies, different software versions, their upgrades, etc.
  • Focus on single application instance instead of 100 customers with 100 instances in 100 different location.
  • You can reach to new clients from all over the world.
So, excited about building a SaaS application? OK, let's see what you must know for building SaaS software. The following are the key architecture/design blocks of a SaaS application:

Multi-tenancy: Multi-tenancy is the ability to serve different customers from a shared hardware or software instance. It gives you economics of scale by catering to a growing customer base without any significant increase in your resources. From a software design perspective, multi-tenancy influences all aspects of software including database model, application logic, user interface, etc. At the database level, multi-tenancy can be achieved either by storing data for each customer in a separate schema or by partitioning the customer data by adding a customer qualifier field to all entities (i.e., Customer ID should be part of all tables as a primary key field). The second approach is straightforward and can be implemented very easily. It may suffice for systems that do not have a large volume of data. However, for systems that deal with large data volume it is best to store each customer's data in a schema of its own. In both cases, you must spend some time building data access frameworks to hide the underlying data partitioning scheme from developers. This not only makes your developers' lives easier but also helps you to migrate from one scheme to another when the need arises. Mainly you can design your SaaS application in any one approach from below list:
  • Shared Application with Shared DB (True SaaS but Maintainance and Security problem)
  • Shared Application with Shared DB and separate Schema (Maintainance problem)
  • Shared Application with Separate DB (Recomended for big applications)
  • Separate Application with Separate DB (This is not an multitenant application)
Scalability: Well, scalability is important for any software system worth its salt. However, it becomes extremely important for a SaaS system because any performance impact directly affects all your customers. If one of your customers starts uploading large volumes of data, it should not start impacting other customers. Database multi-tenancy discussed above takes care of scalability from the database operations side. To ensure that your application servers are scalable, you must ensure that your applications are cluster enabled and you can add cluster nodes as your data volumes grow. It is best to make all your application services stateless so that you do not need to worry about session persistence/replication, etc. Another design principle to follow, while designing scalable systems, is modularizing your services. This not only makes your system more fault-tolerant but also allows you to scale the different components based on the number of requests each component receives. Another important tool you should exploit is cache. In a SaaS system there is a lot of data that is common across customers (e.g. country codes). Such meta data can be cached and be made accessible across the system. This will avoid unnecessary database operations and boost system performance.

Security: As the data for all customers is stored in the same data-store, it is very important to ensure that one customer's data is not accessible by another. This means deploying several levels of defenses. For instance:
  • At the database level, you must encrypt all confidential data - preferably by using a unique key for each customer.
  • At the network level, you must ensure that all the communication happens on a secured channel (e.g., HTTPS should be used for all requests from the browser to application server).
  • At the application level, you must ensure that all the workflows authorize the user before granting access to any data. Authorization must be performed on the server side for each request rather than depending on the client for it. Also, ensure that your website conforms to security best practices.
  • All the application layers(Controller, Service, DAO, Client etc) should be well secured.
Customizability: If you have been in the enterprise application space for more than a few months, you would know that no two customers are the same. Each customer has different requirements for data modeling, UI workflows, integration with legacy systems, etc. As a SaaS system developer, you should realize this early and ensure that the system provides customization capability for all important elements, e.g., the UI look and feel, data interchange formats, definition of entities and business logic, as well. When designing your data model, think how your users can extend it. When designing your business logic, think how the user can alter it. It is a good practice to model business logic as a template that can be changed by your users. When designing your UI look and feel, think of different themes, logos, icons, etc. Customization becomes very important if your business model involves partners to resell your solution; they'll probably want to rebrand your solution and customize the workflows.