<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Tenmiles Blog</title>
	
	<link>http://tenmiles.com/blog</link>
	<description>Official Tenmiles Blog</description>
	<lastBuildDate>Mon, 06 Sep 2010 05:15:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Tenmiles" /><feedburner:info uri="tenmiles" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Inbound Marketing for Startups</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/UsQ4OCNaw5g/</link>
		<comments>http://tenmiles.com/blog/2010/09/inbound-marketing-for-startups/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 03:20:54 +0000</pubDate>
		<dc:creator>Shalin</dc:creator>
				<category><![CDATA[Insights]]></category>
		<category><![CDATA[customers]]></category>
		<category><![CDATA[inbound marketing]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[revenue]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=443</guid>
		<description><![CDATA[Inbound marketing is one the best marketing tool for a startup. The easiest way to make that happen is by investing your time and effort in leveraging the internet (your website) to enable a sale. Getting your first few customers is not a catch-22 situation. You also don&#8217;t need the biggest brands as your first [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F09%2Finbound-marketing-for-startups%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F09%2Finbound-marketing-for-startups%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Inbound marketing is one the best marketing tool for a startup. The easiest way to make that happen is by investing your time and effort in leveraging the internet (your website) to enable a sale. </p>
<p>Getting your first few customers is not a catch-22 situation. You also don&#8217;t need the biggest brands as your first few customer to prove that your product is great. Selling a <a href="http://www.sahilparikh.com/selling-saas-offline" target="_blank">SaaS-based application offline</a> could be hard and expensive. Learn what your prospective customers are looking for and searching for. Get them when they want you. You&#8217;ll save yourself from out-of-scope feature requests and get real relevant feedback. </p>
<p>Focus on great customer service instead of cold-calling. </p>
<p>Our first customer for our <a href="http://www.helpdeskpilot.com/"  target="_blank">help desk software</a>, volunteered for translating it in German language out of the love for the product. This in a way is a true power of a good product and inbound marketing.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/UsQ4OCNaw5g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/09/inbound-marketing-for-startups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/09/inbound-marketing-for-startups/</feedburner:origLink></item>
		<item>
		<title>How to Hire Better</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/5H6KHZM9kMY/</link>
		<comments>http://tenmiles.com/blog/2010/08/how-to-hire-better/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 10:53:15 +0000</pubDate>
		<dc:creator>Shalin</dc:creator>
				<category><![CDATA[Insights]]></category>
		<category><![CDATA[company]]></category>
		<category><![CDATA[employee]]></category>
		<category><![CDATA[hire]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[people]]></category>
		<category><![CDATA[programmers]]></category>
		<category><![CDATA[startup]]></category>
		<category><![CDATA[team]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=421</guid>
		<description><![CDATA[The best business lessons are learnt while not at business. The subconscious mind is continuously learning things from our day to day activity we perform and indirectly help us do better at work. I couldn&#8217;t help mulling over the hiring process while shopping for vegetables at a grocery store. My dad was instructing me how [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Fhow-to-hire-better%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Fhow-to-hire-better%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>The best business lessons are learnt while not at business. The subconscious mind is continuously learning things from our day to day activity we perform and indirectly help us do better at work. I couldn&#8217;t help mulling over the hiring process while shopping for vegetables at a grocery store. My dad was instructing me how to handpick quality vegetables and I followed every single tip he gave me. So, there is more than just recipe to all the good food that mom cooks. Quality Ingredients.</p>
<p><img title="recipe-food" src="http://tenmiles.com/blog/wp-content/uploads/2010/08/recipe-food2.jpg" alt="" width="576" height="302" /></p>
<p>A product is a collective effort of a group of people. Product is output, people are input. At a startup execution of an idea is key. There are no processes in place governing quality, people are entrusted. Hence, it is important to hire the right set of people. A good hire delivers, is easier to retain and attracts more people to join.</p>
<p>From what I learnt while picking up the right ingredients for a good recipe, I could connect some of those factors to the hiring process.</p>
<p><span id="more-421"></span></p>
<h4>Freshness:</h4>
<p>Look for the most recent experience they have had. The past 6 months can play a key role. Know what they have delivered, learnt and contributed. They should show a sense of excitement with how they have spent their past 6 months professionally despite any constraints they might have had with the employer.</p>
<h4>Readiness:</h4>
<p>If you are diving into a new technology, check for the willingness and their belief in the technology you have chosen. Just the way, good aptitude always doesn&#8217;t guarantee great programmers, availability of skill doesn&#8217;t mean they are the best fit. Are they open minded, see your goals as theirs and ready to plunge on the opportunity?</p>
<h4>Quantity:</h4>
<p>I love the idea of a startup staying lean. But ask any startup and they would say they have so much to do and not enough people. It&#8217;s very important to understand for a startup (cash rich or not) growing number of people does not proportionately increase output or business. In fact, startups with large overheads and excess in people make them lose their risk appetite. Knowing how much to hire and spend time hiring is extremely important. You cannot hire for the imaginative future. Keep team size to minimum. It is easier to do better under constraints.</p>
<h4>Cost:</h4>
<p>One of the best way to keep costs low is to hire people with different experience levels. Experienced, Freshers and Interns. Avoid being on a  desperate look out for <em>Rockstars</em> that you think you cannot do without. A good team composition will give you better sustainment capabilities.</p>
<h4>Alternatives:</h4>
<p>Not all the time you would manage to find people in hirable position and at times you can do without hiring. Never miss out on thinking about the alternatives. Outsourcing, crowd-sourcing and help from friends and family. These are short term alternatives you can experiment.</p>
<h4>Source:</h4>
<p>Campus Placements, HR consultants, Job Portals, Networking, LinkedIn, References and Blog/Website are all sources that bring in new people. Not all of this works for everyone. In my experience, references and our website has attracted more quality people ready to work for us than any other source. You should be able to pick the right source for you typically depending how much and how soon.</p>
<h4>Quality</h4>
<p>This is the part where you actually want to evaluate skill-set and attitude. Quality can be brought in perspective with what you have in hand currently. Make sure they are at par or above. Every hire is a unique interview process at startup. Don&#8217;t interview a designer the way you would interview a developer. Allow people to exhibit skills and get beyond the resume.</p>
<h4>Put to use:</h4>
<p>Having people at work who are eternally waiting for something else to happen to take up their job more seriously is dangerous. Everyone at a startup has enough to do, a sales guy does not have to wait for the product to release before he could do anything valuable. If you have people not yet put to right use, you shouldn&#8217;t be hiring.</p>
<h3>Conclusion &amp; Suggested Reading</h3>
<p>Hiring is a process the founders have to be closely involved in. It is an art that grows on you as you hire and learn from it. The next time you are involved in a selection process where you put a lot of thought, you would have learnt something new. It will help you do hiring better. If you have other analogies or experience that go well with hiring please feel free to share them in comments section.</p>
<p>I liked Dharmesh Shah&#8217;s take on the <a href="http://onstartups.com/tabid/3339/bid/13808/The-Magical-Founding-Team-Mix-For-Web-Startups.aspx">first few people that you should have</a> at a startup.<br />
Another interesting post that highlights <a href="http://pmarca-archive.posterous.com/how-to-hire-the-best-people-youve-ever-worked">Hiring Criteria</a> and of course Joel Spolsky&#8217;s post on <a href="http://www.joelonsoftware.com/articles/fog0000000073.html ">The Guerrilla Guide to Interviewing</a></p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/5H6KHZM9kMY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/08/how-to-hire-better/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/08/how-to-hire-better/</feedburner:origLink></item>
		<item>
		<title>Image handling in RoR API using Paperclip</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/7GCUtqbhCJo/</link>
		<comments>http://tenmiles.com/blog/2010/08/image-handling-in-ror-api-using-paperclip/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 07:07:27 +0000</pubDate>
		<dc:creator>Nisha</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[attachment]]></category>
		<category><![CDATA[paperclip]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails api]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[upload images]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=384</guid>
		<description><![CDATA[Image handling is a common task in an application and for Ruby on Rails we have quite a few plugins like rmagick, minimagick, paperclip, attachment-fu etc available to effectively do the same. Paperclip is by far the most loved and popular plugin used to attach images to a model in a rails application. It makes [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Fimage-handling-in-ror-api-using-paperclip%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Fimage-handling-in-ror-api-using-paperclip%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Image handling is a common task in an application and for Ruby on Rails we have quite a few plugins like rmagick, minimagick, paperclip, attachment-fu etc available to effectively do the same. <a href="http://github.com/thoughtbot/paperclip"> Paperclip </a> is by far the most loved and popular plugin used to attach images to a model in a rails application. It makes life easy with good <a href="http://jimneath.org/2008/04/17/paperclip-attaching-files-in-rails/"> documentation </a> and <a href="http://railscasts.com/episodes/134-paperclip">screencasts</a> available to guide through. But at an advanced level, the challenge comes in when an api interface to upload and download images needs to be provided for the model. As paperclip does not support this by iteself, and there is not much help or guide available to help solve this problem, this post makes life easier for ROR api developers, who have to provide a way to attach images sent through xml to the model.</p>
<h4><span id="more-384"></span></h4>
<p>Lets start with a model person that has an image attachment photo. The model will require the following fields in the migration.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">add_column <span style="color:#ff3333; font-weight:bold;">:persons</span>, <span style="color:#ff3333; font-weight:bold;">:photo_file_name</span>, :<span style="color:#CC0066; font-weight:bold;">string</span><br />
add_column <span style="color:#ff3333; font-weight:bold;">:persons</span>, <span style="color:#ff3333; font-weight:bold;">:photo_content_type</span>, :<span style="color:#CC0066; font-weight:bold;">string</span><br />
add_column <span style="color:#ff3333; font-weight:bold;">:persons</span>, <span style="color:#ff3333; font-weight:bold;">:photo_file_size</span>, :<span style="color:#CC0066; font-weight:bold;">integer</span><br />
add_column <span style="color:#ff3333; font-weight:bold;">:persons</span>, <span style="color:#ff3333; font-weight:bold;">:photo_updated_at</span>, <span style="color:#ff3333; font-weight:bold;">:datetime</span></div></div>
<p>/app/models/user.rb</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><br />
has_attached_file <span style="color:#ff3333; font-weight:bold;">:photo</span><br />
validates_attachment_presence <span style="color:#ff3333; font-weight:bold;">:photo</span><br />
validates_attachment_content_type <span style="color:#ff3333; font-weight:bold;">:photo</span>, <span style="color:#ff3333; font-weight:bold;">:content_type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'image/jpeg'</span>, <span style="color:#996600;">'image/png'</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>We won&#8217;t be going through the HTML views here, as this is already well documented and available. We are more concerned with the API point of view, so here&#8217;s how the controller&#8217;s create method would have been if xml responds to is not yet introduced&#8230;</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> create<br />
<span style="color:#0066ff; font-weight:bold;">@person</span> = Person.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:person</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@person</span>.<span style="color:#9900CC;">save</span><br />
flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'Person was successfully created.'</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@person<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span> &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@person</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created</span>, <span style="color:#ff3333; font-weight:bold;">:location</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@person</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#9966CC; font-weight:bold;">else</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;new&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span> &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@person</span>.<span style="color:#9900CC;">errors</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:unprocessable_entity</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Though, we can observe the xml render statements present there, this isn&#8217;t quite going to work for us. Well to make it work first we need to decide how do we specify the images in the xml document ?</p>
<p>one way, is offer a separate URL endpoint that allowed direct uploading for just the one image. But this solution requires more than one HTTP call to create or update the model attributes and also will require as many as the number of images in the model, which is not very efficient.</p>
<p>Another way is to embed the image in the xml, where the image is encoded as the base64 encoded string. So the xml will be of this format</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Nisha Singhvi<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #808080; font-style: italic;">&lt;!-- specify photo element outside the person element, because photo is string type, while the person model --&gt;</span><br />
<span style="color: #ddbb00;">&amp;&lt;!--expects Paperclip::Attachment type;</span> hence need to do manipulations before the photo can be assigned to the model's photo attribute --&gt;<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;photo_file_name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>my_photo.jpg<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/photo_file_name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;photo</span> type = <span style="color: #ff0000;">&quot;String&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #808080; font-style: italic;">&lt;!--base-64 encoded string--&gt;</span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/photo<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>when this xml is sent to the create method we need to decode the encoded string in a temporary image file and then assign this file object to the model&#8217;s paperclip::Attachment object. The modified create method will now be</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> create<br />
respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>?<br />
<span style="color:#008000; font-style:italic;">#build other attributes of the person model</span><br />
<span style="color:#0066ff; font-weight:bold;">@person</span> = Person.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:root</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:person</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#008000; font-style:italic;">#xml file contains photo as base64 encoded string</span><br />
<span style="color:#9966CC; font-weight:bold;">unless</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:root</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:photo</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?<br />
temp = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:root</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:photo</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
<span style="color:#008000; font-style:italic;">#decode the base64 encoded string and store it in the temp file name</span><br />
<span style="color:#008000; font-style:italic;">#provided in params[:root][:photo_file_name]</span><br />
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:root</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:photo_file_name</span><span style="color:#006600; font-weight:bold;">&#93;</span>,<span style="color:#996600;">&quot;wb&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span><br />
file.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>ActiveSupport::<span style="color:#CC00FF; font-weight:bold;">Base64</span>.<span style="color:#9900CC;">decode64</span><span style="color:#006600; font-weight:bold;">&#40;</span>temp<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#008000; font-style:italic;">#open the temp file created and assign it to the paperclip::Attachment object - photo - of Person</span><br />
f = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:root</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:photo_file_name</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#0066ff; font-weight:bold;">@person</span>.<span style="color:#9900CC;">photo</span> = f<br />
<span style="color:#008000; font-style:italic;">#delete the temp file created</span><br />
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:root</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:photo_file_name</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#0066ff; font-weight:bold;">@person</span> = Person.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:person</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span>?<br />
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@person</span>.<span style="color:#9900CC;">save</span><br />
flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'Person was successfully created.'</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to person_path<span style="color:#006600; font-weight:bold;">&#40;</span>@person<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span> &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@person</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created</span>, <span style="color:#ff3333; font-weight:bold;">:location</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@person</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#9966CC; font-weight:bold;">else</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'new'</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span> &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@person</span>.<span style="color:#9900CC;">errors</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:unprocessable_entity</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Having done the create method you might be wondering how to render these photos back to the client application. Now to get the image for the api request, again just rendering the model object will just give the database columns i.e photo_file_name, photo_content_type, photo_file_size, photo_updated_at but the actual image will be missing.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> show<br />
<span style="color:#0066ff; font-weight:bold;">@person</span> = Person.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span><span style="color:#006600; font-weight:bold;">&#40;</span>render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@person</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:ok</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Here again we have two options&#8230;<br />
One is to render the path and url of the variable by building the xml using builder.<br />
/app/views/person/show.xml.builder</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">xml.<span style="color:#9900CC;">instruct</span>! <span style="color:#ff3333; font-weight:bold;">:xml</span>, <span style="color:#ff3333; font-weight:bold;">:version</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;1.0&quot;</span><br />
xml.<span style="color:#9900CC;">person</span><span style="color:#006600; font-weight:bold;">&#123;</span><br />
xml.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">path</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">photo</span>.<span style="color:#9900CC;">path</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">url</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">photo</span>.<span style="color:#9900CC;">url</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">file_name</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">photo_file_name</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div></div>
<p>But this again is not very efficient, as the url and path are relative to the server address, which in turn raises security issues.<br />
The second option is to embed the image as the base-64 string and send it in the xml file by building the xml</p>
<p>/app/controllers/persons_controller.rb</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> show<br />
<span style="color:#0066ff; font-weight:bold;">@person</span> = Person.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>?<br />
<span style="color:#0066ff; font-weight:bold;">@photo</span> = ActiveSupport::<span style="color:#CC00FF; font-weight:bold;">Base64</span>.<span style="color:#9900CC;">encode64</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">photo</span>.<span style="color:#9900CC;">path</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>io<span style="color:#006600; font-weight:bold;">|</span> io.<span style="color:#9900CC;">read</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@person</span>.<span style="color:#9900CC;">photo</span>.<span style="color:#9900CC;">url</span> == &nbsp;<span style="color:#996600;">&quot;/photos/original/missing.png&quot;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span><br />
<span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>/app/views/person/show.xml.builder</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">xml.<span style="color:#9900CC;">instruct</span>! <span style="color:#ff3333; font-weight:bold;">:xml</span>, <span style="color:#ff3333; font-weight:bold;">:version</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;1.0&quot;</span><br />
xml.<span style="color:#9900CC;">person</span><span style="color:#006600; font-weight:bold;">&#123;</span><br />
xml.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">id</span>, <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;integer&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">name</span>, <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;string&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">photo_file_name</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">photo_file_name</span>, <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;string&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">photo_content_type</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person.<span style="color:#9900CC;">photo_content_type</span>, <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;string&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
xml.<span style="color:#9900CC;">photo</span><span style="color:#006600; font-weight:bold;">&#40;</span>@photo, <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;string&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div></div>
<p>So here we have images downloaded and uploaded to a model  via xml for the purpose of API. This should also apply the same way to api using json too. Please feel free to leave your suggestions as comments.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/7GCUtqbhCJo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/08/image-handling-in-ror-api-using-paperclip/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/08/image-handling-in-ror-api-using-paperclip/</feedburner:origLink></item>
		<item>
		<title>Apache, Passenger and other server alternatives: rails</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/tgEawNuP_2k/</link>
		<comments>http://tenmiles.com/blog/2010/08/apache-passenger-and-other-server-alternatives-rails/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 13:47:08 +0000</pubDate>
		<dc:creator>abhishek</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[application server]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[mongrel]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[thin]]></category>
		<category><![CDATA[webserver]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=275</guid>
		<description><![CDATA[This post is a part of the series of articles about choices available to a rails developer. Previously we discussed about the choice of databases. This time it is about application and web servers. We can make the choice of an application and a web server separately, but as they are so closely related that [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Fapache-passenger-and-other-server-alternatives-rails%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Fapache-passenger-and-other-server-alternatives-rails%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><em>This post is a part of the series of articles about choices available to a rails developer. Previously we discussed about the choice of <a href="http://tenmiles.com/blog/2010/08/rails-database-default-alternatives">databases</a></em><em>. This time it is about application and web servers. We can make the choice of an application and a web server separately, but as they are so closely related that it is better to look at them together.</em></p>
<div><em><br />
</em></div>
<h2>Web Server</h2>
<p>It is well known what a web server does, but for starters - the web server receives the HTTP requests first, and then responds by either serving the page requested or directing the request to our rails application server. The major web servers market-share wise (survey graph below) are Apache, IIS(Microsoft), nginx, GWS(Google) and lighttpd. We as rails developers are interested in all these except IIS and GWS. Not IIS because it is closed source and proprietary and not GWS because it is used internally by Google. Apache, nginx and lighttpd are all popular among rails developers.</p>
<h3><strong>Apache</strong></h3>
<h3><a href="http://httpd.apache.org/"><img class="alignleft" style="margin-right: 10px; margin-bottom: 10px;" src="http://httpd.apache.org/images/apache_logo.gif" alt="apache logo" width="200" height="74" /></a></h3>
<p>The most popular web server  in use. It supports a wide variety of features, and is reasonably fast as well. Many of the essential features are provided as compiled modules that extend the core. These include support for server side scripting languages like perl, php, tcl, python; support for authentication; support for ssl and tls  and compression support.</p>
<p>The only issue with apache is that because it is process based, it spawns too many threads when there are too many simultaneous requests. This leads to excessive memory usage, so the performance can drop in restricted environments under heavy load.</p>
<h3><strong><span id="more-275"></span>Nginx</strong></h3>
<p><a href="http://wiki.nginx.org"><img class="alignleft" style="margin-right: 10px; margin-bottom: 10px;" src="http://wiki.nginx.org/local/nginx-logo.png" alt="nginx logo" width="200" height="51" /></a> The light-weight and high performance web server. It has most features that any good web server should have, but surely lacks a few that apache has. The major differentiator with nginx is the performance. Because of the event-based architecture, it gracefully handles tens of thousands of concurrent requests. There is limited <a href="http://wiki.nginx.org/Main">english documentation</a> (which is improving), as it was developed for <a href="http://www.rambler.ru">russian portals</a> . The adoption rate is very high &#8211; it has quickly become the third most deployed web server (after apache and IIS).</p>
<h3><strong>lighttpd</strong></h3>
<p><a href="http://www.lighttpd.net"><img class="alignleft" style="margin-right: 10px; margin-bottom: 10px;" src="http://www.lighttpd.net/light_logo_170px.png" alt="lighttpd logo" width="122" height="121" /></a></p>
<p>Lighttpd another light-weight, efficient web server with low memory footprint. It also has an event-driven architecture that is optimized for a very large number of parallel connections. Most rails applications that use it run as  lighttpd + fastcgi configuration. The concept is that lighttpd receives the HTTP requests, and it spawns our rails app instances using fastcgi. In comparison, nginx and lighttpd are almost equally good in performance (<a href="http://superjared.com/entry/benching-lighttpd-vs-nginx-static-files/">some benchmarks</a>), and some people find lighttpd easier to configure. However, there is a <a href="http://www.wikivs.com/wiki/Lighttpd_vs_nginx#Stability">perception</a> that lighttpd may not be stable because there are some very old memory leak bugs in it.</p>
<div>
<p>Here is a comparison of the market share of the major web servers -</p>
</div>
<div>
<div class="wp-caption aligncenter" style="width: 560px"><a href="http://news.netcraft.com/archives/2010/01/07/january_2010_web_server_survey.html"><img src="http://news.netcraft.com/wp-content/uploads/2010/05/wpid-2010%5E01%5Eoveralld.png" alt="web-server market share" width="550" height="300" /></a><p class="wp-caption-text">web-server market share statistics from netcraft</p></div>
</div>
<p>For more information on the comparison, the <a href="http://www.wikivs.com/wiki/Apache_vs_nginx)">wikivs wiki</a> is a good place to start. There is an interesting  <a href="http://stackoverflow.com/questions/475386/apache-vs-nginx-vs-lighttpd-which-is-simpler-to-configure-and-administer">stackoverflow discussion</a> also on this.</p>
<h2><strong>Application Server</strong></h2>
<p>Application server answers requests to the application and is mostly not meant to serve static content. In rails context, the app server runs our rails application code, on requests from a web server. The web server and the app server generally communicate via some standard communication protocols like FastCGI or HTTP.</p>
<p>The first server we come across when starting with rails is Webrick &#8211; it starts on a script/server command in development environment. It is a ruby library  for providing http web services and a server. It can be used only in very simple circumstances like development, and anything beyond that, like the production environment of the same rails app, should be run on one of more specialized servers like mongrel, thin or passenger.</p>
<div><strong> </strong></div>
<h3><strong>Mongrel</strong></h3>
<div><a href="http://github.com/fauna/mongrel"><img class="alignleft" style="margin-right: 10px; margin-bottom: 10px;" src="http://rubyonrails.org/images/pages/deploy/mongrel.jpg" alt="mongrel image" width="186" height="82" /></a></div>
<p><a href="http://github.com/fauna/mongrel">Mongrel</a> is the first contender for a production environment application server in rails. It uses plain HTTP to talk to the web server, and is reasonably fast because it uses the Ragel compiler. (More on Ragel: <a href="http://en.wikipedia.org/wiki/Rage">wikipedia page</a>,  <a href="http://www.zedshaw.com/essays/ragel_state_charts.html">mongrel creator&#8217;s essay</a>). A very popular way of running mongrel is to run it as clusters behind an apache server using mod_proxy_balancer for load-balancing. It can also be made to run as clusters behind nginx or lighttpd. The only flip-side of mongrel is that it is a little tough to administer the server, especially when operated in clusters.</p>
<div>
<h3>Thin</h3>
</div>
<p><a href="http://code.macournoyer.com/thin/"><img class="alignleft" style="margin-right: 10px; margin-bottom: 10px;" src="http://code.macournoyer.com/thin/images/logo.gif" alt="Thin logo" width="172" height="40" /></a><a href="http://code.macournoyer.com/thin">Thin</a> is <em>yet another web server</em> that has the same philosophy as mongrel (uses the mongrel  parser), but uses the <a href="http://wiki.github.com/eventmachine/eventmachine">event machine</a> to make it run faster than mongrel. Like mongrel, it is intended to be run behind apache or nginx web servers as clusters.</p>
<h3>Passenger</h3>
<p><a href="http://modrails.com/"><img class="alignleft" style="margin-right: 10px; margin-bottom: 10px;" src="http://rubyonrails.org/images/pages/deploy/passenger.png" alt="passenger logo" width="197" height="68" /></a></p>
<p><a href="http://www.modrails.com">Passenger</a> is <em>the</em> &#8216;mod rails&#8217; for the apache web server. It is fast, easy to configure, is technically sound and very stable. For example, apache with passenger doesn&#8217;t crash if our app has to crash. It is recommended <a href="http://rubyonrails.org/deploy">officially</a>, and is <a href="http://www.loudthinking.com/posts/30-myth-1-rails-is-hard-to-deploy">praised</a> by the creators of rails. It can run with nginx as well, and is supported on all unix-like operating systems &#8211; it does not work on windows! It is also easy to configure and administer.</p>
<h3>Some performance benchmarks -</h3>
<p>Various performance benchmarks are available for comparison. The summary is that Thin is faster than mongrel, and passenger is almost as fast or sometime faster than mongrel.</p>
<div>
<p style="text-align: center;">
</div>
<div>
<div class="wp-caption aligncenter" style="width: 360px"><a href="http://code.macournoyer.com/thin/"><img class="   " src="http://chart.apis.google.com/chart?cht=bvg&amp;chd=t:14.98,54.8723076923077,48.9184615384615,79.9276923076923|14.8692307692308,65.0615384615385,70.4446153846154,89.5553846153846|14.9476923076923,35.1123076923077,70.18,88.6769230769231&amp;chbh=16&amp;chs=350x150&amp;chl=WEBrick|Mongrel|Evented%20M.|Thin&amp;chco=000000,666666,cccccc&amp;chdl=1%20c%20req.|10%20c%20req.|100%20c%20req" alt="performance comparison - thin vs mongrel" width="350" height="150" /></a><p class="wp-caption-text">source: Thin website</p></div>
<div id="attachment_311" class="wp-caption aligncenter" style="width: 310px"><a href="http://modrails.com/documentation"><img class="size-medium wp-image-311  " src="http://tenmiles.com/blog/wp-content/uploads/2010/08/passenger_mongrel_thin_benchmark-300x186.png" alt="passenger_mongrel_thin_benchmark" width="300" height="186" /></a><p class="wp-caption-text">source: Passenger documentation</p></div>
</div>
<h2>Our take</h2>
<p>We run apache with passenger. <a href="http://twitter.com/ytvinay">Vinay</a> has written a series of useful articles about <a href="http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-2-apache-passenger-directives">passenger &amp; apache optimization</a>. Do have a look if the internals of the server interests you.</p>
<h2>Conclusion</h2>
<div>The most popular choice among rails developers currently is running passenger with apache.</div>
<div><a href="http://tenmiles.com/blog/wp-content/uploads/2010/08/rails_app-server_deployment_chart.jpg"></a></div>
<div id="attachment_280" class="wp-caption aligncenter" style="width: 310px"><a href="http://rails-hosting.com/Results/SurveySummary.html"><img class="size-medium wp-image-280  " src="http://tenmiles.com/blog/wp-content/uploads/2010/08/rails_app-server_deployment_chart-300x175.jpg" alt="rails app-server deployment chart" width="300" height="175" /></a><p class="wp-caption-text">Rails application deployment survey 2009  (source: http://rails-hosting.com)</p></div>
<p>Going beyond the default, if you are expecting  high concurrent load on your website, you can use nginx web server with passenger or mongrel clusters.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/tgEawNuP_2k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/08/apache-passenger-and-other-server-alternatives-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/08/apache-passenger-and-other-server-alternatives-rails/</feedburner:origLink></item>
		<item>
		<title>Rails Database Default &amp; Alternatives</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/nx-Vdwqr5sY/</link>
		<comments>http://tenmiles.com/blog/2010/08/rails-database-default-alternatives/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 12:58:39 +0000</pubDate>
		<dc:creator>abhishek</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=215</guid>
		<description><![CDATA[This post is a part of the series of articles about choices available to a rails developer. It is inspired by a blog post by Josh Susser, where he asserts that there are too many choices available for a new ruby-on-rail developer now, which can get him scared/confused. This series is not about &#8220;choice or [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Frails-database-default-alternatives%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F08%2Frails-database-default-alternatives%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><em>This post is a part of the series of articles about choices available to a rails developer. It is inspired by a </em><em><a href="http://blog.hasmanythrough.com/2009/2/7/the-tyranny-of-choice">blog post by Josh Susser</a></em><em>, where he asserts that there are too many choices available for a new ruby-on-rail developer now, which can get him scared/confused. This series is not about &#8220;choice or no choice?&#8221;, and not about &#8220;are the defaults correct?&#8221;. It just answers the newbie developer&#8217;s  curiosity of <strong>what lies beyond the defaults</strong>. Lets begin with databases.</em></p>
<h2>Database</h2>
<p><span style="font-weight: normal;">Rails is used for writing database backed web applications using the MVC design pattern. The choice of database depends on the kind of capacity you expect from the database and the budget. If you are developing a large enterprise application, you might need to research Oracle/MS-SQL and the like, along with those described here. Another choice you might have to make is whether to go for a relational DBMS. The rails framework provides adapters (programs that connect your app to the database) for three popular open source relational database management systems &#8211; sqlite, mysql and postgresql. So if you are looking for an open source RDBMS, you have have the best to choose from.<br />
</span></p>
<h4><span id="more-215"></span></h4>
<h4><a href="http://www.sqlite.org">Sqlite</a></h4>
<p><a href="http://tenmiles.com/blog/wp-content/uploads/2010/08/sqlite_banner.gif"><img class="size-full wp-image-217 alignleft" style="margin-right: 10px; margin-bottom: 10px;" src="http://tenmiles.com/blog/wp-content/uploads/2010/08/sqlite_banner.gif" alt="sqlite for rails application" width="110" height="55" /></a> Is the <a href="http://weblog.rubyonrails.org/2007/12/17/rails-2-0-2-some-new-defaults-and-a-few-fixes">rails default</a>.  As the name suggests, sqlite is light-weight sql. Unlike the other two, it doesn&#8217;t work on the client-server model. It runs as a single library, attached to the executing rails app. Due to this, it saves the overhead of client-server communication, hence <strong>lite</strong>. A common perception is that it is suitable for  development environments only and for live websites, it is a small tool (<a href="http://www.sqlite.org/whentouse.html">official perception</a>). But lot of people swear by its usability in production &#8211; they say it is fine if your site receives up to 100k hits a day. Also, as it is light, it is the best suited database for/as embedded systems.  Sqlite is used by some big names like Apple and Firefox. A more complete list can be seen on the <a href="http://www.sqlite.org/famous.htm">sqlite website</a>. More on sqlite performance -<a href="http://stackoverflow.com/questions/784173/what-are-the-performance-characteristics-of-sqlite-with-very-large-database-files">a stackoverflow question</a> , <a href="http://www.sqlite.org/speed.html">official figures</a>.  However, as sqlite is not designed to handle heavy concurrency &#8211; it might not be a good choice if your app has 100 users per second all performing database operations.</p>
<h4><a href="http://www.mysql.com">mysql</a></h4>
<p><a href="http://tenmiles.com/blog/wp-content/uploads/2010/08/mysql_logo.png"><img class="alignleft size-full wp-image-219" style="margin-right: 10px; margin-bottom: 10px;" src="http://tenmiles.com/blog/wp-content/uploads/2010/08/mysql_logo.png" alt="mysql for rails applications" width="110" height="57" /></a>Mysql is client-server based, fast, easy to use and very popular. It is available for most platforms (look at this <a href="http://en.wikipedia.org/wiki/Comparison_of_relational_database_management_systems#Operating_system_support">comparison on wikipedia</a> &#8211; mysql is all green), and adapters and tools are widely available. Quite full featured, can be configured to run well for different goals and environments through its 9 <a href="http://dev.mysql.com/doc/refman/5.1/en/storage-engines.html">storage engines</a>. And works reasonably fast by default. Do look at <a href="http://stackoverflow.com/questions/3630/sqlite-vs-mysql">this discussion</a> on stackoverlow if you are torn between mysql and sqlite.  The only catch with mysql is in the license. Its free and fine for use, but if you are planning to distribute mysql with your close-sourced product, you may have to pay license fee. Some useful information on the licensing can be found at <a href="http://stackoverflow.com/questions/225987/can-someone-explain-mysqls-license-and-what-it-means-to-closed-source-developmen">stackoverflow</a>, <a href="http://en.wikipedia.org/wiki/MySQL#Support_and_licensing">wikipedia</a> and the <a href="http://www.mysql.com/about/legal/licensing/foss-exception">official website</a></p>
<h4><a href="http://www.postgresql.org">PostgreSQL</a> <a href="http://tenmiles.com/blog/wp-content/uploads/2010/08/postgres_elephant.png"></a></h4>
<p><a href="http://tenmiles.com/blog/wp-content/uploads/2010/08/postgres_elephant.png"><img class="alignleft size-full wp-image-218" style="margin-right: 10px; margin-bottom: 10px;" src="http://tenmiles.com/blog/wp-content/uploads/2010/08/postgres_elephant.png" alt="postgresql database for rails applications" width="64" height="64" /></a> PostgresSQL is another great RDBMS (actually an <a href="http://en.wikipedia.org/wiki/Object-relational_database">O-RDBMS</a>) available for rails developers. It is almost as good as mysql, with some differences in technology, and notable difference in license. Architecture is different (this has a single engine), so is ACID compliance (full here, partial in mysql), and there are some feature differences (partial indices are supported here, not in mysql) as well. The license in postgres is a much simpler MIT style &#8216;postgres&#8217; license.  So which one to go with &#8211; mysql or postgres ? Most people who have used both are inclined (see this <a href="http://stackoverflow.com/questions/110927/do-you-recommend-postgresql-over-mysql">stackoverflow discussion</a>)<a href="http://stackoverflow.com/questions/110927/do-you-recommend-postgresql-over-mysql"> </a> towards postgres. Mysql has some limitations (like &#8211; no partial indices), which should be understood, especially if your application might need some hard-core database operations, like, say multiple level sub-querying. Plus, postgres is controlled/supported by the developer community, while mysql (now) belongs to Oracle.  A few more good comparison resources &#8211; <a href="http://blog.taragana.com/index.php/archive/postgresql-vs-mysql-comparative-review">tarangana blog</a>, <a href="http://www.wikivs.com/wiki/MySQL_vs_PostgreSQL">wikivs</a>. Some relevent stackoverlfow questions &#8211; <a href="http://stackoverflow.com/questions/1242812/pros-cons-of-mysql-vs-postgresql-for-production-ruby-on-rails-environment">pros/cons</a>,  <a href="http://stackoverflow.com/questions/772111/switching-from-mysql-to-postgresql-tips-tricks-and-gotchas">mysql-&gt; postgres switch</a>, <a href="http://stackoverflow.com/questions/404776/why-isnt-postgresql-as-widespread-as-mysql/404781#404781">reason for mysql popularity</a>.</p>
<h2>Our take</h2>
<div>We prefer to use mysql in production and development. However for quick prototyping and for testing sqlite is great, because of the time it saves running the tests.</div>
<h2>Conclusion</h2>
<div>Rails is database agnostic. If you don&#8217;t write any native sql queries in the app, it can switch from one DBMS to another effortlessly. As a best practice, the production environment should not see a DBMS change, as this may increase the risk of unexpected bugs. Although for production use, Postgres looks like a winner in the above discussion, the others also stand tall based on what the  <strong>utility</strong> is. The decision should really be taken based on the ease of use and the anticipated technical requirement.</div>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/nx-Vdwqr5sY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/08/rails-database-default-alternatives/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/08/rails-database-default-alternatives/</feedburner:origLink></item>
		<item>
		<title>What defines a Startup ?</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/vLNDnhkeBGU/</link>
		<comments>http://tenmiles.com/blog/2010/07/what-defines-a-startup/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 11:55:14 +0000</pubDate>
		<dc:creator>vinay</dc:creator>
				<category><![CDATA[Insights]]></category>
		<category><![CDATA[Opinions]]></category>
		<category><![CDATA[culture]]></category>
		<category><![CDATA[opinions]]></category>
		<category><![CDATA[startups]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=196</guid>
		<description><![CDATA[Someone asked me what I do and I had to decide whether to say &#8220;I work for a small product development company&#8221; or &#8220;I work for a web based startup company&#8221;. Invariably, the former received &#8220;ho hum&#8221; replies and the latter received &#8220;aah ooh&#8221; replies. The kick of &#8220;aah ooh&#8221; replies not withstanding, the question [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F07%2Fwhat-defines-a-startup%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F07%2Fwhat-defines-a-startup%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Someone asked me what I do and I had to decide whether to say <em>&#8220;I work for a small product development company&#8221;</em> or <em>&#8220;I work for a web based startup company&#8221;</em>. Invariably, the former received <em>&#8220;ho hum&#8221; </em>replies and the latter received <em>&#8220;aah ooh&#8221;</em> replies. The kick of <em>&#8220;aah ooh&#8221;</em> replies not withstanding, the question is still very real in my head. Are we still a startup?</p>
<p>The way I see it, there are two definitions for startups. The term <strong>startup company</strong> according to Wikipedia :</p>
<p><em>&#8220;A </em><strong><em>startup company</em></strong><em> or </em><strong><em>startup</em></strong><em> is a </em><em>company</em><em> with a limited operating history. These companies, generally newly created, are in a phase of </em><em>development</em><em> and research for </em><em>markets</em><em>.</em><em>&#8220;</em></p>
<p>This is the strict definition based on certain statistics about the company that many people consider as correct. Lets check its validity.</p>
<p>Take <strong>Google Apps</strong> for example, it was in beta (&#8216;phase of development&#8217;) <a href="http://googleblog.blogspot.com/2009/07/google-apps-is-out-of-beta-yes-really.html" target="_blank">until July 2009</a>. Does that mean it was a startup until then? The fact is that software these days is continuously under development. So that cannot be part of the criteria determining the definition of startups. Nor can age or size of the company because well, Steve Jobs described <strong>Apple</strong> as the &#8220;<a href="http://d8.allthingsd.com/20100607/steve-jobs-at-d8-the-full-uncut-interview/" target="_blank">Biggest Startup on the Planet</a>&#8221; at the D8 conference this year. Some say that once a startup becomes profitable, it becomes a company. <strong>Twitter</strong> has been &#8216;in operation&#8217; since 2006, still has not figured out a business model and has a user base thats probably second only to <strong>Facebook</strong>. Now where does that leave Twitter? Lets face it. Definitions based on turnover, size and age just don&#8217;t work anymore.</p>
<p>The expression <strong>startup company</strong> now evokes an emotion that goes beyond numbers and figures.</p>
<h4><span id="more-196"></span></h4>
<h4>Culture</h4>
<p>Startups are expected to have a clearly distinguished cool culture. Bureaucracy is definitely frowned upon and so are <a href="http://en.wikipedia.org/wiki/Cubicle_farm" target="_blank">cubicle farms</a>. Work clothes are usually t-shirts and jeans and everyone is a decision maker in the company. Work and fun are interchangeable. Millions of Kilobytes of text have been written about startup culture. For starters, take a look at Brian Halligan&#8217;s (CEO and co-founder of Hubspot) &#8220;<a href="http://onstartups.com/tabid/3339/bid/13420/Startup-Culture-Lessons-From-Mad-Men.aspx" target="_blank">Startup Culture Lessons From Mad Men</a>&#8221; and Greg Gottesman&#8217;s &#8220;<a href="http://www.techflash.com/seattle/2009/05/Thirteen_characteristics_of_a_great_startup_culture_45678557.html" target="_blank">Thirteen key characteristics of a great startup culture</a>&#8220;. The reason many people still consider Google to be a startup is because of its <a href="http://en.wikipedia.org/wiki/Google#Corporate_affairs_and_culture" target="_blank">famous work culture</a>. Not because its products are &#8216;officially in beta&#8217; forever.</p>
<h4>Funds</h4>
<p>Startups always function with restricted funds. They are always trying to cut costs by using open source tools, having fewer employees, doing more things at the same time and working longer hours. This can be true for various reasons. The key though, is that even those startups that find millions in funding through VCs and Angel investors don&#8217;t ever splurge money on 6 figure executive bonuses and private jets. Expenditure is disciplined. You will find more startups spending money on keeping a well stocked fridge and a foosball table in the office than on getting a new mahogany desk or chandelier. Again, the culture is what drives this habit. Making work fun for everyone takes precedence over luxurious spending. Its so obvious that big corporations should write it on a big hammer and bang themselves on the head with it for missing it.</p>
<h4>Nature of operations</h4>
<p>It is possible that a new product in development in an old company functions like a startup. A lot of development and research will be going into the product and business model. A handful of people will be in the team and the goal would be to make the product a business in itself. Take <a href="http://doattend.com" target="_blank">DoAttend</a>, our event organizing tool, for example. Although its a product of a 9+ year old company, the DoAttend team still functions like a startup and is itself only a few months old. So think about it. You may be working for a company thats been around for a while, but what is the nature of your work? Are you part of a newly formed, small and tight team with a specific product to make? Are you looking to make it a profitable business in itself? Are you and your team self motivated and driven toward the common cause of making the product successful?</p>
<p>Startups are no longer merely a category of companies. They reflect a whole new work culture and nature of operation that is inspiring the next generation. Startups mark the arrival of a new Renaissance in work culture. The internet and the success of startups has shown that small companies can be disruptive on a large scale. This has in turn sunk into society so much that you would rather call yourself a &#8220;startup&#8221; than a small company now. Its a lot more media and employee friendly. Think about it, a true definition endures as an emotion. So what emotion does the word &#8220;startup&#8221; evoke in you?</p>
<p>Its no surprise therefore, that although we are going to be 10 years old soon, Tenmiles is still a startup at heart. We believe in, function under, follow and promote startup culture.</p>
<p>My mind is now at rest. I will continue to say that I work for a web based startup. I can now enjoy the &#8220;aah&#8221;s and &#8220;ooh&#8221;s with a clear conscience.</p>
<p>How else do you think the definition of a startup has changed? Feel free to let us know in the comments.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/vLNDnhkeBGU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/07/what-defines-a-startup/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/07/what-defines-a-startup/</feedburner:origLink></item>
		<item>
		<title>Understanding &amp; Optimizing your Server (Part 2) – Apache &amp; Passenger Directives</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/vaJexXSkY4A/</link>
		<comments>http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-2-apache-passenger-directives/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 08:55:42 +0000</pubDate>
		<dc:creator>vinay</dc:creator>
				<category><![CDATA[Insights]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[directives]]></category>
		<category><![CDATA[maintenance]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=184</guid>
		<description><![CDATA[Prelude In the previous article, we went through the basic architecture of Apache and Passenger. Now I&#8217;ve been told that its a bit too much to digest in one shot but it&#8217;ll all make sense when all the 3 articles are read together. If not, you&#8217;re always welcome to drop a question in the comments [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F07%2Funderstanding-optimizing-your-server-part-2-apache-passenger-directives%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F07%2Funderstanding-optimizing-your-server-part-2-apache-passenger-directives%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Prelude</strong></p>
<p>In the <a title="Understanding &amp; Optimizing your server (Part 1)" href="http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-1-the-apache-passenger-dance/" target="_blank">previous article</a>, we went through the basic architecture of Apache and Passenger. Now I&#8217;ve been told that its a bit too much to digest in one shot but it&#8217;ll all make sense when all the 3 articles are read together. If not, you&#8217;re always welcome to drop a question in the comments section and I&#8217;d be happy to help.</p>
<p><strong>Assumptions</strong></p>
<p>In this article, we will be looking at the primary directives in Apache and Passenger for optimization. The rest of the series is specific to the case where a single RoR application is running on the server (say, TweakMyApp).</p>
<h4><span id="more-184"></span></h4>
<p><strong>Apache Directives</strong></p>
<p>The Apache directives that can be set for the <a title="pre-fork MPM Documentation" href="http://httpd.apache.org/docs/2.1/mod/prefork.html" target="_blank">pre-fork MPM</a> are listed here with brief descriptions and suggested values.</p>
<p><strong><a title="Start Servers" href="http://httpd.apache.org/docs/2.1/mod/mpm_common.html#startservers" target="_blank">StartServers</a></strong> &#8211; <em>The number of child processes (workers) to start on Apache startup. The default 5 is good.</em></p>
<p><em></em>Apache will spawn child workers to handle multiple incoming requests. This directive specifies how many such child processes are required by default when Apache itself starts up. When Apache starts up, a main control process spawns the workers and is responsible for delegating requests to them. You can refer the <a title="Previous post" href="http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-1-the-apache-passenger-dance/" target="_blank">previous article</a> or the <a title="MPM Module" href="http://httpd.apache.org/docs/2.1/mpm.html" target="_blank">Apache docs</a> for details about Apache&#8217;s achitecture.</p>
<p><strong><a title="MinSpareServers" href="http://httpd.apache.org/docs/2.1/mod/prefork.html#minspareservers" target="_blank">MinSpareServers</a></strong> &#8211; <em>Minimum number of idle spare children to keep ready for expected requests. A high number is rarely good. Anything from 3 to 5 is fine.</em></p>
<p>Say this number is set to 3. This will tell Apache that even if there are no requests, keep at least 3 child workers alive for expected requests at all times.</p>
<p><strong><a title="MaxSpareServers" href="http://httpd.apache.org/docs/2.1/mod/prefork.html#maxspareservers" target="_blank">MaxSpareServers</a></strong> &#8211; <em>Maximum number of idle spare children to keep ready for expected requests. Again, a high number is rarely good. Anything from 8 to 10 is fine.</em></p>
<p>Say this is set to 10. This tells Apache to keep at most 10 children alive to process expected requests. MaxSpareServers and MinSpareServers define a range of idle children to keep and Apache will kill or spawn children in order to stay within this range. These directives are important mainly to specify how much of your server&#8217;s memory is allowed to be hogged by Apache&#8217;s idle children.</p>
<p><strong><a title="MaxClients" href="http://httpd.apache.org/docs/2.1/mod/mpm_common.html#maxclients" target="_blank">MaxClients</a></strong> &#8211; <em>Maximum number of child processes that will be launched to serve requests. The default of 150 is usually good.</em></p>
<p>One thing to remember in this directive is that, say one instance of TweakMyApp consumes 90MB of RAM, it does not mean that you are allowing (90*150) MB of RAM as the maximum request setting for the server. Apache processes consume much less memory than that. We will look at that in detail in the next post. Also, if you want to set this at anything above 256, then you need to <a href="http://httpd.apache.org/docs/2.1/mod/mpm_common.html#serverlimit" target="_blank">tweak the ServerLimit</a> directive first.</p>
<p><strong><a title="MaxRequestsPerChild" href="http://httpd.apache.org/docs/2.1/mod/mpm_common.html#maxrequestsperchild" target="_blank">MaxRequestsPerChild</a></strong> &#8211; <em>Sets the limit on the number of requests each individual child process will handle. Default of 0 (infinite) is perfect.</em></p>
<p>If you change this number, you give each child a finite number of actions before it will die. In effect, you are freeing memory by reducing the number of processes that are running when the server is not busy. Freeing memory for what? Maybe there are other applications on the server that could use the memory. But its not likely that they&#8217;ll require that extra memory only when the server is not busy. So leaving this setting at 0 is best, especially based on &#8220;our assumptions&#8221;.</p>
<p><strong>Passenger Directives</strong></p>
<p>The Passenger directives that are used for optimization are listed below with brief description.</p>
<p><strong><a title="PassengerMaxPoolSize" href="http://modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxpoolsize_lt_integer_gt" target="_blank">PassengerMaxPoolSize</a></strong> &#8211; <em>The max number of RoR application instances that may run simultaneously.</em></p>
<p>This is the total number of application instances that the Passenger Application Pool will hold. Since we only have TweakMyApp running on our server, this number is essentially the number of instances of TweakMyApp we have ready in the Application Pool to server requests.</p>
<p><strong><a title="PassengerMaxInstancesPerApp" href="http://modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxinstancesperapp_lt_integer_gt" target="_blank">PassengerMaxInstancesPerApp</a></strong> &#8211; <em>The max number of instances of each RoR application that may run simultaneously.</em></p>
<p><em></em>This is not relevant to us as we have only one application, TweakMyApp, to consider.</p>
<p><strong><a title="PassengerPoolIdleTime" href="http://modrails.com/documentation/Users%20guide%20Apache.html#PassengerPoolIdleTime" target="_blank">PassengerPoolIdleTime</a></strong> &#8211; <em>The max number of seconds for which an application instance can remain idle. This can be set to 0 (infinite) for our case.</em></p>
<p>This needs to be set at a finite value only if you have multiple applications. Say there is another application, IntrudingApp, that runs on the same server and needs another instance to serve incoming requests, and say TweakMyApp instances are sitting idle, then Passenger can shut down idle TweakMyApp instances and use the memory to spawn IntrudingApp instances. Since we only have TweakMyApp running and need it to be available at all times, 0 is perfect for us.</p>
<p><strong><a title="PassengerMaxRequests" href="http://modrails.com/documentation/Users%20guide%20Apache.html#PassengerMaxRequests" target="_blank">PassengerMaxRequests</a></strong> -<em> The max number of requests a given application instance will process. Again, this can be set to 0 (infinite) for our case.</em></p>
<p>This directive is very similar to the Apache MaxRequestsPerChild directive and is best left at 0 for us.</p>
<p><strong><a title="PassengerStatThrottleRate" href="http://modrails.com/documentation/Users%20guide%20Apache.html#_passengerstatthrottlerate_lt_integer_gt" target="_blank">PassengerStatThrottleRate</a></strong> &#8211; <em>The frequency with which Passenger should perform its file system checks. I&#8217;m leaving this at the default of 0.</em></p>
<p><em></em>This setting tells Passenger how often it needs to perform its filesystem checks like checking environment.rb and restart.txt . If you have an application that you dont intend to change much or one in which changes in the code can take effect slowly, then you might want to set this value to something higher. It will help free up some memory. But I&#8217;m leaving it at 0 here under the assumption that you have a highly dynamic application.</p>
<p><strong><a title="PassengerHighPerformance" href="http://modrails.com/documentation/Users%20guide%20Apache.html#PassengerHighPerformance" target="_blank">PassengerHighPerformance</a></strong> &#8211; <em>This setting increases Passenger performance at the cost of reduced compatibility with certain other Apache modules. Im going to go with the default of &#8220;off&#8221; here.</em></p>
<p><em></em>This setting improves Passenger performance but affects compatibility with other Apache modules like mod_rewrite and mod_autoindex. Im leaving this <em>off</em> to be on the safe side.</p>
<p><strong><a title="Passenger Global Queueing" href="http://modrails.com/documentation/Users%20guide%20Apache.html#PassengerUseGlobalQueue" target="_blank">Passenger Global Queueing</a></strong> is another useful concept that could potentially speed up processing of requests further. Im leaving it <em>off</em> in my case because I have not tested it yet, but you could turn it <em>o</em>&#8221; at your own discretion. It is of special relevance if you are running multiple application on the server.</p>
<p><strong>References</strong></p>
<p>A similar, very useful blog post <a href="http://www.alfajango.com/blog/performance-tuning-for-phusion-passenger-an-introduction/" target="_blank">here</a></p>
<p>MaxClients and ServerLimit &#8211; Check the comments section <a href="http://articles.slicehost.com/2008/12/11/ubuntu-intrepid-apache-configuration-1" target="_blank">here</a></p>
<p><a href="http://groups.google.com/group/phusion-passenger/browse_thread/thread/3c27bb2ecd9dd634/f2b65114e7866bc4?lnk=gst&amp;q=understanding+apache+passenger+directives#f2b65114e7866bc4" target="_blank">The discussion</a> in Passenger&#8217;s Google group</p>
<p>Check <a href="http://stackoverflow.com/questions/853532/slow-initial-server-startup-when-using-phusion-passenger-and-rails" target="_blank">this discussion</a> for more Passenger directives, highly recommend it</p>
<p>Global queueing <a href="http://groups.google.com/group/phusion-passenger/browse_thread/thread/7c7eb8e77dca5200" target="_blank">discussion</a> in Google groups</p>
<p><strong>Multiple Apps</strong></p>
<p>Most configuration for managing multiple applications on a server will be done using Passenger directives. For example, you may want to tweak the PassengerMaxPoolSize and PassengerMaxInstancesPerApp directives. There are other directives and concepts like Global Queueing also which can help you, but I&#8217;m going to point you to the <a href="http://modrails.com/documentation/Users%20guide%20Apache.html" target="_blank">Passenger Documentation</a> for that.</p>
<p>In the next article, we will use what we have learnt so far to get to the nitty gritties &#8211; gathering metrics and tweaking configurations. Until then, ciao and feel free to drop in your comments.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/vaJexXSkY4A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-2-apache-passenger-directives/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-2-apache-passenger-directives/</feedburner:origLink></item>
		<item>
		<title>Understanding &amp; Optimizing your Server (Part 1) – The Apache &amp; Passenger Dance</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/WpI-8x8-D1c/</link>
		<comments>http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-1-the-apache-passenger-dance/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 12:13:53 +0000</pubDate>
		<dc:creator>vinay</dc:creator>
				<category><![CDATA[Insights]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=177</guid>
		<description><![CDATA[So here&#8217;s my problem. I&#8217;ve written an RoR application and I&#8217;ve managed to get a server up and running with Apache and Passenger. Im paying quite a bit for my server, but I have no idea if my application is effectively using the server&#8217;s resources. How do I gather metrics to make sure that I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F07%2Funderstanding-optimizing-your-server-part-1-the-apache-passenger-dance%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F07%2Funderstanding-optimizing-your-server-part-1-the-apache-passenger-dance%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>So here&#8217;s my problem. I&#8217;ve written an RoR application and I&#8217;ve managed to get a server up and running with <a href="http://www.apache.org/" target="_blank">Apache</a> and <a href="http://www.modrails.com/" target="_blank">Passenger</a>. Im paying quite a bit for my server, but I have no idea if my application is effectively using the server&#8217;s resources. How do I gather metrics to make sure that I can configure my web server(Apache) and application server (Passenger) optimally to serve my application?</p>
<p>I realized that there are 3 parts in the answer to this question. First, we need to understand how Apache and Passenger are designed to handle incoming HTTP requests together. Second, we need to understand what the various directives available for Apache and Passenger mean. And finally, we need to see how we can gather metrics and tweak these directives to the optimal setting.</p>
<p>Im going to address each of these 3 parts in 3 blog posts. So lets get started with the first, how Apache and Passenger are setup to work together.</p>
<p>There is <a href="http://www.modrails.com/documentation/Architectural%20overview.html" target="_blank">an explanation</a> in the Passenger docs on Passenger&#8217;s Architecture but frankly, I could not digest it in one read. So I&#8217;m going to summarize it for our purposes here.</p>
<div id="attachment_180" class="wp-caption aligncenter" style="width: 310px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/07/passenger_architecture.png"><img class="size-medium wp-image-180   " title="Passenger Architecture" src="http://tenmiles.com/blog/wp-content/uploads/2010/07/passenger_architecture-300x110.png" alt="passenger architecture mindmap" width="300" height="110" /></a><p class="wp-caption-text">mod_passenger sits in the control process and every child process of Apache&#39;s</p></div>
<h4><span id="more-177"></span></h4>
<p>Apache has an architecture wherein modules can be plugged in to add functionality to it. Passenger provides the mod_passenger module which allows Apache to act as an application server. The above diagram (taken from the Passenger docs) represents Passenger&#8217;s architecture when the default <a href="http://httpd.apache.org/docs/2.0/mod/prefork.html" target="_blank">prefork MPM</a> is used with Apache.</p>
<p>The mod_passenger module sits in the main control process and every worker process that Apache generates. It also maintains 2 other things - a spawn server and an application pool.</p>
<p>The Passenger Spawn Server further, has 3 components &#8211; Spawn Manager, Framework Spawner and Application Spawner. Now according to the Passenger documentation,</p>
<p><em>&#8220;A particularly interesting thing to note, is that a lot of the memory occupied by Ruby on Rails applications is spent on storing the program code (i.e. the </em><a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree"><em>abstract syntax tree (AST)</em></a><em>) in memory. This is observed through the use of the memory statistics function in </em><a href="http://www.rubyenterpriseedition.com/"><em>Ruby Enterprise Edition</em></a><em>. Also, a lot of the startup time of a Ruby on Rails application is spent on bootstrapping the Rails framework.&#8221;</em></p>
<p>This means that performance can be increased considerably if the Rails Framework code and your application code can be cached and reused. This is primarily what the Framework Spawner and Application Spawner do. The Framework Spawner spawns and caches an instance of every Rails version that your applications use. Similarly, the Passenger Application Spawner spawns instances of your application to serve requests. The diagram below (also taken from the Passenger docs) represents this.</p>
<div id="attachment_181" class="wp-caption aligncenter" style="width: 310px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/07/spawn_server_architecture.png"><img class="size-medium wp-image-181" title="Spawn Server Architecture" src="http://tenmiles.com/blog/wp-content/uploads/2010/07/spawn_server_architecture-300x261.png" alt="spawn server architecture mindmap" width="300" height="261" /></a><p class="wp-caption-text">Each of the top 2 layers is responsible to handle only its immediate children </p></div>
<p>The application pool is simply a pool of application instances that can be used to handle incoming requests.</p>
<p>So when an HTTP request comes in to Apache, it passes it on to mod_passenger, which checks out an application process from the pool and marks it as busy. If all app instances in the pool are busy and the pool limit has not been reached yet, then mod_passenger will place a spawn request to the spawn server/manager. The spawn manager will pass on the request to the correct Framework Spawner Server. The Framework Spawner will then forward it to the correct Application Spawner Server which will then spawn a new application instance to serve the request. The lifetime of this application instance is then maintained directly by mod_passenger.</p>
<p>So that, is typically how Apache and Passenger dance together. For a more detailed run through however, I recommend the <a href="http://www.modrails.com/documentation/Architectural%20overview.html" target="_blank">Passenger Architecture Document</a>. It is definitely an interesting read. A couple of other pages that you might like to refer :</p>
<p>Apache MPM modules &#8211; <em><a href="http://httpd.apache.org/docs/2.0/mpm.html" target="_blank">http://httpd.apache.org/docs/2.0/mpm.html</a></em></p>
<p>Ruby Enterprise Edition &#8211; <em><a href="http://www.rubyenterpriseedition.com/" target="_blank">http://www.rubyenterpriseedition.com/</a></em></p>
<p>In the <a title="Part 2 - Apache &amp; Passenger Directives" href="http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-2-apache-passenger-directives/" target="_blank">next article</a>, we&#8217;ll take a look at a few basic directives for Apache and Passenger.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/WpI-8x8-D1c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-1-the-apache-passenger-dance/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/07/understanding-optimizing-your-server-part-1-the-apache-passenger-dance/</feedburner:origLink></item>
		<item>
		<title>Pricing your SaaS Application</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/7fiuv4G7lYc/</link>
		<comments>http://tenmiles.com/blog/2010/04/pricing-your-saas-application/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 11:12:37 +0000</pubDate>
		<dc:creator>Shalin</dc:creator>
				<category><![CDATA[Insights]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[pricing]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[saas]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web2]]></category>
		<category><![CDATA[webapp]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=137</guid>
		<description><![CDATA[SaaS: Software As A Service has become widely accepted and is a popular choice among businesses. Businesses consuming SaaS applications favour the low upfront cost and zero infrastructure headaches. Also, SaaS applications being deployed online have the advantage of being available anywhere, anytime and even on any platform. Businesses developing software have embraced the SaaS [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F04%2Fpricing-your-saas-application%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F04%2Fpricing-your-saas-application%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>SaaS:</strong> Software As A Service has become widely accepted and is a popular choice among businesses. Businesses consuming SaaS applications favour the low upfront cost and zero infrastructure headaches. Also, SaaS applications being deployed online have the advantage of being available anywhere, anytime and even on any platform. Businesses developing software have embraced the SaaS model with open hands. The emergence of Cloud computing, subscription ready payment gateways and success stories of the likes of SalesForce and Google Apps makes it an easy model to follow.</p>
<p><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/cloud-pricing-graphic.png" alt="Pricing SaaS Application" title="cloud-pricing-graphic" width="600" height="320" class="size-full wp-image-138" /></p>
<p>Clearly SaaS applications have adopted a different pricing model than the traditional one-time license fee based desktop or web applications. There is a definite recurring cost per user in the hosted model that warrants the need for a different pricing approach. You not only provide an app but also manage users data.</p>
<p>Let&#8217;s dive into a few of the popular pricing strategies to understand the available models and what could fit your next SaaS application.</p>
<h4><span id="more-137"></span></h4>
<p><strong>FREE</strong></p>
<p>There is actually no free model when it comes to SaaS applications, unlike desktop or deployable web based apps. The Free model is actually an Ad-Supported model or something that helps a business leverage/popularize another brand or product. YouTube is a good example that falls into this model. No user ever pays to upload or consume the videos. The revenue generated for the business is using Ads. Other services that follow similar models are popular Networking Sites like <a href="http://facebook.com">Facebook</a>, <a href="http://twitter.com">Twitter</a> &#038; <a href="http://orkut.com">Orkut</a>.</p>
<div id="attachment_144" class="wp-caption alignnone" style="width: 610px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/04/free-facebook-signup.png"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/free-facebook-signup.png" alt="Free Web App" title="free-facebook-signup" width="600" height="265" class="size-full wp-image-144" /></a><p class="wp-caption-text">Facebook - Free Social Networking Service</p></div>
<p>The free model can scale quickly and you need to achieve critical mass to make sense of running on an Ad driven model. You would need to have a lot of cash in your pocket to scale up the infrastructure to support a large user base before ad-revenue starts pouring in. The free model works well for business-to-consumer (B2C) rather than business-to-business (B2B). While businesses do leverage these applications quite well they have no control, support &#038; one-to-one relationships with the service providers.</p>
<div id="attachment_146" class="wp-caption alignnone" style="width: 610px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/04/free-ad-youtube.png"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/free-ad-youtube.png" alt="YouTube showing Ad" title="free-ad-youtube" width="600" height="365" class="size-full wp-image-146" /></a><p class="wp-caption-text">Ads shown on youtube.com homepage</p></div>
<p>The most successful Free SaaS applications have their own Ad Networks. Think Facebook, Twitter &#038; YouTube (Google). Other apps that don&#8217;t have their own ad networks end up sharing their profits with their advertising network partner (such as google adsense) making it even more difficult for the business to survive purely on ads. Recently, <a href="http://ning.com">Ning</a> the popular Social Network provider <a href="http://www.dailyfinance.com/story/the-free-internet-loses-another-one-ning/19444179/">decided to close their Free offering</a> and price their service instead. </p>
<p>There are startups that use the Free model while offering their service in beta. They are likely to move to other pricing models.</p>
<p><strong>Freemium</strong></p>
<p>This is probably the most popular pricing model for SaaS applications. There are plenty of B2C and B2B apps that use this model effectively. The idea of Freemium is to offer a Free plan along with paid plans. Paid plans usually offer some benefits over the free plans. Free plans become a great starting point for users. </p>
<div id="attachment_152" class="wp-caption alignnone" style="width: 610px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-codebasehq.png"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-codebasehq.png" alt="" title="freemium-codebasehq" width="600" height="70" class="size-full wp-image-152" /></a><p class="wp-caption-text">CodeBaseHQ's Free Plan - With the limits clearly stated </p></div>
<p><a href="http://flickr.com">Flickr</a> is a great and the simplest of example that follow this model. You can upload pictures and share with a free plan but with a limit of 200MB uploads per month ,unlimited viewing of your images but would have ads on the page. If your usage is going to go above that limit you can consider upgrading to their PRO plan (for an annual fee you can upload up to as much as 100 times more content).</p>
<div id="attachment_148" class="wp-caption alignnone" style="width: 610px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/04/fremium-flickr.png"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/fremium-flickr.png" alt="Flickr Pro Plan" title="fremium-flickr" width="600" height="354" class="size-full wp-image-148" /></a><p class="wp-caption-text">FlickR offers PRO plan at $24.95/year </p></div>
<p>Premium plans are usually selling more usage, features, priority support or sometimes even additional data security and back up. To arrive at what could be premium in your SaaS application could depend on the market segment you are addressing to and/or the costs to enable you to provide the additional services. Free plans help the business generate more word of mouth and attract small businesses early on.</p>
<p><strong>Free Trial, Paid Only</strong></p>
<p>Try before you buy. A more serious, built-for-business pricing model. Applications are usually available for anywhere between 7-60 day trial but are full featured. Apple&#8217;s <a href="http://me.com">MobileMe</a> and <a href="http://hubspot.com">Hubspot</a> are good examples that use this model effectively. </p>
<div id="attachment_149" class="wp-caption alignnone" style="width: 610px"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/paidonly-mobileme.png" alt="" title="paidonly-mobileme" width="600" height="300" class="size-full wp-image-149" /><p class="wp-caption-text">Apple's Mobile Me Service at $99.95 per year with 60-days trial. No Free Plans.</p></div>
<p>You probably need to have a product that stands out, has limited competition or is perceived as an extremely useful app. Many services indeed require you to submit your credit card information when you sign up for the trial period and start charging you as soon as the trial is complete. While this could prove an entry barrier for users it surely helps you minimize non-serious trial users.</p>
<p><strong>Arriving at your pricing model</strong></p>
<p>Having discovered and determined various segmentation that can help you price your service (what to charge for) the next big question is how much to ask and how often. How much quite often determines the entry barrier while how often determines retention ability. IMHO, How much is of course the bigger challenge. The real number could be arrived by studying competition, market size, target audience, perceived value of your service and many other factors. However, there is a clear choice you can make, between having a Single Plan or  Multiple Plan.</p>
<p><strong>Single Plan</strong></p>
<p>Evernote, Flickr, MobileMe use a single plan strategy; Premium/Pro plan. </p>
<div id="attachment_150" class="wp-caption alignnone" style="width: 610px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-evernote-saas-pricing.png"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-evernote-saas-pricing.png" alt="" title="freemium-evernote-saas-pricing" width="600" height="390" class="size-full wp-image-150" /></a><p class="wp-caption-text">Single Plan offered by Evernote</p></div>
<p>They are essentially selling more storage space and bandwidth, targeted towards individuals rather than businesses. Their product does not involve multiple users within a single account and can be categorized in to B2C. Hence, the rationale behind a single price point.</p>
<p><strong>Multiple Plans</strong></p>
<p>It is important to evaluate if your market could be segmented. For instance &#8211; Small, Medium and Large Enterprises, Open Source and Proprietary software vendors, Freelancers starting out and well established freelancers. The goal of multiple pricing plans is to charge more to customers who use your service more and vice-versa. For instance, if you are selling a project management solution, you can easily segment your target audience on either the company size or number of projects. Businesses often may experiment with the most low end plan before they think the solution is fit for the entire company.</p>
<div id="attachment_151" class="wp-caption alignnone" style="width: 610px"><a href="http://www.deskaway.com/pricing/index.php"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-deskaway-monthly.png" target="_blank" alt="DeskAway Project Management Software" title="freemium-deskaway-monthly" width="600" height="414" class="size-full wp-image-151" /></a><p class="wp-caption-text">From Free Plans to $99/mo plan. Key segmenting factor is number of projects and storage space.</p></div>
<p><a href="http://linkedin.com">LinkedIn</a> offers separate pricing for Job Posters (Companies) and Job Seekers. </p>
<div id="attachment_155" class="wp-caption alignnone" style="width: 610px"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-linkedin-jobposter.png" alt="" title="freemium-linkedin-jobposter" width="600" height="118" class="size-full wp-image-155" /><p class="wp-caption-text">LinkedIn - Pricing for Job Posters (Companies) </p></div>
<div id="attachment_156" class="wp-caption alignnone" style="width: 610px"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-linkedin-jobseeker.png" alt="" title="freemium-linkedin-jobseeker" width="600" height="424" class="size-full wp-image-156" /><p class="wp-caption-text">LinkedIn - Pricing for Job Seekers</p></div>
<p>Another excellent example of segmenting is GitHub. It segments different business sizes and offers free plan to only open source projects. Making it a popular choice among the large opensource development community. </p>
<div id="attachment_168" class="wp-caption alignnone" style="width: 610px"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/fremium-opensource.png" alt="" title="fremium-opensource" width="600" height="384" class="size-full wp-image-168" /><p class="wp-caption-text">GITHUB - Keeping it FREE for Open Source Projects</p></div>
<p><strong>No Plans &#8211; Pay as you go</strong></p>
<p>If your end users don&#8217;t have a definite usage pattern and are unlikely to commit for a specific time period it might be a good idea to have a pay as you go plan. <a href="http://doattend.com" title="Online Event Registration Service">DoAttend</a> and <a href="http://campaignmonitor.com">Campaign Monitor</a> are good examples of pay-as-you-go pricing models. </p>
<p>DoAttend works on a transaction model charging customers a very small fee when transactions happen. The customers are invoiced monthly based on their actual usage. Ideally, an Event Organizer who does one event a year will never want to pay monthly or yearly when he/she only uses the system for a maximum of 3-4 months.</p>
<div id="attachment_158" class="wp-caption alignnone" style="width: 610px"><a href="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-doattend.png"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/freemium-doattend.png" alt="" title="freemium-doattend" width="600" height="359" class="size-full wp-image-158" /></a><p class="wp-caption-text">DoAttend - Transaction based pricing - Pay As You Go</p></div>
<p>In a similar way, Campaign Monitor charges 1 cent per email sent out along with a fixed fee of $5 per campaign. Customers are charged 100% in advance everytime they choose to send out a mail campaign. Their pay-as-you-go pricing model appeals to customers who send out mailers once in a while with a varied number of subscription lists, which makes monthly plans a lot more expensive. </p>
<p><a href="http://slideshare.net">SlideShare</a> uses Pay As You Go model for lead generation. Their latest LeadShare Program basically charges their customers only when a lead is generated from the presentation hosted on slideshare. </p>
<div id="attachment_169" class="wp-caption alignnone" style="width: 610px"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/slideshare-leadshare-payasyougo.png" alt="" title="slideshare-leadshare-payasyougo" width="600" height="373" class="size-full wp-image-169" /><p class="wp-caption-text">Leadshare by Slideshare - Pay per lead program</p></div>
<p><strong>How often to charge</strong></p>
<p>Monthly, Yearly and Pay-As-You-Go pricing models are what most applications adopt. Applications billing on Quarterly or Half-Yearly basis are quite rare. It is not uncommon to use more than one of these payment intervals. Evernote uses both Monthly and Yearly option. Mail Chimp uses both Pay-As-You-Go and Monthly plans. </p>
<div id="attachment_160" class="wp-caption alignnone" style="width: 610px"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/combination-mailchimp.png" alt="" title="combination-mailchimp" width="600" height="432" class="size-full wp-image-160" /><p class="wp-caption-text">MailChimp has both Monthly &#038; Pay As You Go plans</p></div>
<p>Canceling subscriptions and upgrading/downgrading plans are assumed available by most consumers and you should be very clear about it to ensure better conversions. The best way to judge if your payment interval is ideal for your app is by keeping a track on customer retention ratio. Another handy number to have is average value and retention period of your customer. If you are offering a service for $5/mo and realize that average retention period is only 7 months it might be a good idea to offer a discounted yearly plan (besides improving your application to increase your numbers) and see how your new customers choose. If you are offering a yearly plan that is priced high, it would be a good idea to introduce a monthly plan to see if that reduces the barrier to entry. </p>
<p>Setup fees are very rare too, Hubspot charges a fee during sign up referred to as Mandatory Quick Start Program Fee. If every account on the system has a fixed cost to get started or if you think the value provided in your service is the maximum during the first few months rather than an long on-going usage, you can consider a setup fee. </p>
<div id="attachment_161" class="wp-caption alignnone" style="width: 610px"><img src="http://tenmiles.com/blog/wp-content/uploads/2010/04/paidonly-hubspot.png" alt="" title="paidonly-hubspot" width="600" height="323" class="size-full wp-image-161" /><p class="wp-caption-text">Hubspot Charges a Compulsory Fee on Joining - referred to as Quick Start Program</p></div>
<p><strong>Popular infrastructure</strong></p>
<p>The SaaS ecosystem has grown really quickly, solidly and cost effectively. Cloud hosting, modern billing systems and availability of excellent frameworks have made this possible.</p>
<p><strong>Cloud Hosting</strong></p>
<p><a href="http://aws.amazon.com/">Amazon Web Services</a>: Amazon offers a large variety of cloud solutions. The most popular being Amazon Elastic Compute Cloud (EC2) and Amazon Simple Storage Service (S3). There are no major upfront costs and their pricing is hourly or by space consumed (in GB). It&#8217;s fairly easy to setup and a highly scalable solution.</p>
<p><a href="http://rackspacecloud.com">Rackspace Cloud</a>: Rackspace the leader in Dedicated hosting bought a cloud hosting service called Mosso and are aggressively marketing their cloud service as Rackspace Cloud. They offer cloud Servers (self-managed, starts at $10.95/mo), Cloud Sites ($149/mo) and Cloud files ($0.15/GB/month).</p>
<p><a href="http://Slicehost.com">Slicehost</a> and <a href="http://www.linode.com/">Linode</a> are popular VPS hosting companies. These services are popular among ruby on rails (ror) and Python django developers. Pricing starts at $20/month.</p>
<p><a href="http://engineyard.com">EngineYard</a> focuses on Rails hosting. One-click code deploys, application cloning, data automation and gem management.</p>
<p><a href="http://Heroku.com">Heroku</a> is another ruby-rails hosting company. They have a free plan (great playing field for your 1 week old app on the cloud) along with paid plans starting at $15/mo.</p>
<p>Other hosting companies worth a mention are <a href="http://MediaTemple.net">MediaTemple</a>, <a href="http://Joyent.com">Joyent</a> and <a href="http://www.aptana.com/cloud">Aptana</a>. </p>
<p><strong>Billing Systems</strong></p>
<p><a href="http://Authorize.net">Authorize.net</a> (US only), <a href="http://Paypal.com">Paypal</a>, <a href="http://aws.amazon.com/fps/">Amazon Flexible Payments Service</a>, <a href="http://www.braintreepaymentsolutions.com/">BrainTree</a> (US only), <a href="http://www.beanstream.com">Beansteam</a> (US &#038; Canada only) and <a href="http://2checkout.com">2checkout</a> are some of the popular payment gateway that offer subscription services. You don&#8217;t have to store any credit card information on your servers and in most cases don&#8217;t even require PCI compliance. <a href="http://Spreedly.com">Spreedly</a> and <a href="http://Chargify.com">Chargify</a> offer services on-top of the payment gateways to make upgrade/drowngrade/renewals available without you having to code anything to enable these features (for rails developers you have <a href="http://railskits.com/saas">Rails Kit</a>, ready-made code to plug into your rails application).  </p>
<p><strong>Frameworks</strong></p>
<p>If you are building apps you might already be well aware of the popular frameworks available. These frameworks significantly reduce development time and make maintaining code easy. Server Code: Python <a href="http://www.djangoproject.com/">Django</a>, <a href="http://rubyonrails.org/">Ruby On Rails</a> and <a href="http://codeigniter.com/">CodeIgniter</a> for PHP. For Client End Javascript &#8211; <a href="http://www.prototypejs.org/">Prototype</a> and <a href="http://jquery.com/">jQuery</a> are the most popular choices with many other awesome Javascript libaries around. <a href="http://www.blueprintcss.org/">Blueprint</a> for CSS is very handy too. It is a good idea to compress your Javascripts and CSS for better performance. You can even consider using <a href="http://code.google.com/">Google APIs</a> to off load the JS load from your server.</p>
<p><strong>The bottom line</strong></p>
<p>Pricing is no rocket science if you rationally arrive at it. Experimenting early on, staying flexible and listening to your customers can really help you nail down the ideal pricing model that works for your business. Allow customers to upgrade/downgrade and even exit without any penalties. Don&#8217;t simply underprice for the sake of looking more affordable than your competitor. Keep your conversion and retention ratio in check to back your pricing decision.</p>
<p>Have more ideas/resources to share? Add them in the comments.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/7fiuv4G7lYc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/04/pricing-your-saas-application/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/04/pricing-your-saas-application/</feedburner:origLink></item>
		<item>
		<title>Rails Developer, Chennai</title>
		<link>http://feedproxy.google.com/~r/Tenmiles/~3/HDDOQTum6tQ/</link>
		<comments>http://tenmiles.com/blog/2010/04/rails-developer-chennai/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 11:10:00 +0000</pubDate>
		<dc:creator>Shalin</dc:creator>
				<category><![CDATA[Jobs]]></category>
		<category><![CDATA[chennai]]></category>
		<category><![CDATA[fresher]]></category>
		<category><![CDATA[intern]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[tenmiles]]></category>

		<guid isPermaLink="false">http://tenmiles.com/blog/?p=106</guid>
		<description><![CDATA[Are you turned on by great ideas and beautiful code? If yes, we want you. Here at Tenmiles, we are driven purely by the excitement of building our own products and making them simply awesome for our customers. And beautiful code is the next obvious step to getting there. We have rolled out 3 Rails products so [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F04%2Frails-developer-chennai%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftenmiles.com%2Fblog%2F2010%2F04%2Frails-developer-chennai%2F&amp;source=tenmilescorp&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Are you turned on by great ideas and beautiful code? If yes, we want you. Here at <a href="http://tenmiles.com">Tenmiles</a>, we are driven purely by the excitement of building our own products and making them simply awesome for our customers. And beautiful code is the next obvious step to getting there. We have rolled out 3 Rails products so far and are best known for <a href="http://doattend.com">DoAttend</a>. We are hiring <strong>experienced developers</strong>, <strong>freshers</strong> with some personal programming experience (any language) and <strong>interns</strong>.</p>
<p><img class="alignnone size-full wp-image-107" title="work-at-tenmiles-tag" src="http://tenmiles.com/blog/wp-content/uploads/2010/04/work-at-tenmiles-tag.jpg" alt="" width="600" height="397" /></p>
<p><strong>What are we looking for? </strong></p>
<p>You must be a daring programmer who can get things done. You should be able to pick up new approaches and learn new techniques quickly.</p>
<p>You must be self-driven and self-motivated. We want to see you come up with ideas for products and features, want to hear you talk about them passionately and want to be convinced that they&#8217;re simply rad!</p>
<p>You must have a startup mindset &#8211; taking responsibility for the product, and working as a team to do what it takes and make it a success.</p>
<p><strong><img class="alignleft size-medium wp-image-109" title="Ruby_on_Rails_logo" src="http://tenmiles.com/blog/wp-content/uploads/2010/04/Ruby_on_Rails_logo-252x300.jpg" alt="" width="136" height="162" />Experienced Developers:</strong> You must be exceptionally good in programming and have a very good domain knowledge in Rails. Experience no bar. Show us some code or links to projects you have completed.</p>
<p><strong>Freshers &amp; Interns:</strong> Hunger to code, excellent aptitude and logical skills. Experience in Rails/Ruby not required but exposure to some programming language with personal programming experience would be required.</p>
<p><strong>What do you get to do?</strong></p>
<p>You will officially be in charge of development and upkeep of one of our Rails products.</p>
<p>You will also be a part of the Rails team as a whole and will be contributing to its evolution &#8211; building the domain knowledge in the company, establishing best practices, coming up with more product ideas and delivering Rails apps to customers. We still function like a startup and so your involvement will help form the culture and practices in areas that you work on. We encourage you to take responsibility and initiative and get things done. Oh, and of course, you&#8217;ll be working on a Mac <img src='http://tenmiles.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Now if you read the above and feel more adrenalin pumping through your body, it most likely means that you think you&#8217;re perfect for this role. And that most likely means that WE will think you&#8217;re perfect for the role.</p>
<p><strong>How can you apply? </strong></p>
<p>Email us your resume to <a href="mailto:jobs@tenmiles.com">jobs@tenmiles.com</a>. Please send your resumes in PDF format only. Do not send cover letters, instead, please list your experience (professional or personal) with Rails, JavaScript and HTML+CSS. Link projects that show your experience. The more great code you show us, faster the interview process  and the easier it will be to floor us.</p>
<p><strong>Got questions?</strong> Leave us a comment or get in touch with us by <a href="mailto:jobs@tenmiles.com">email</a> or <a href="http://twitter.com/tenmilescorp">twitter</a>.</p>
<img src="http://feeds.feedburner.com/~r/Tenmiles/~4/HDDOQTum6tQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tenmiles.com/blog/2010/04/rails-developer-chennai/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://tenmiles.com/blog/2010/04/rails-developer-chennai/</feedburner:origLink></item>
	</channel>
</rss>
