<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Leknarf]]></title>
  <link href="http://leknarf.net/atom.xml" rel="self"/>
  <link href="http://leknarf.net/"/>
  <updated>2013-10-20T11:52:41-04:00</updated>
  <id>http://leknarf.net/</id>
  <author>
    <name><![CDATA[Andrew Frankel]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Link roundup for October 20th]]></title>
    <link href="http://leknarf.net/blog/2013/10/20/link-roundup-for-october-20th/"/>
    <updated>2013-10-20T12:00:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/10/20/link-roundup-for-october-20th</id>
    <content type="html"><![CDATA[<p>Links from last week you may have missed:</p>

<p><a href="http://www.reuters.com/article/2013/10/13/us-siliconvalley-engineers-twitter-idUKBRE99C03R20131013">Twitter pays engineer $10 million as Silicon Valley tussles for talent</a></p>

<p><a href="http://www.avc.com/a_vc/2013/10/tech-ops-as-a-metaphor-for-building-running-leading-a-company.html">Tech Ops As A Metaphor For Building, Running, &amp; Leading A Company</a></p>

<p><a href="http://founderdating.com/your-career-is-a-mess/">Your career is a mess</a></p>

<p><a href="http://venturebeat.com/2013/10/15/why-your-tech-startup-cant-hire-engineers-and-how-to-fix-it/">Why your tech startup can&#8217;t hire engineers (and how to fix it)</a></p>

<p><a href="http://www.techendo.co/posts/are-dev-bootcamps-a-scam-a-hacker-s-perspective">Are Dev Bootcamps a scam? A Hacker&#8217;s perspective</a></p>

<p><a href="http://www.nicholasreese.com/problem-clients/?utm_source=getresponse&amp;utm_medium=email&amp;utm_campaign=downloads&amp;utm_content=How+to+Avoid+Problem+Clients">How to Avoid Problem Clients</a></p>

<p><a href="http://groovehq.com/blog/first-year">7 Lessons We Learned Going from Zero to $30k/Month in Under a Year</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Load testing a rails app with apache bench]]></title>
    <link href="http://leknarf.net/blog/2013/08/30/load-testing-a-rails-app-with-apache-bench/"/>
    <updated>2013-08-30T17:47:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/08/30/load-testing-a-rails-app-with-apache-bench</id>
    <content type="html"><![CDATA[<p>In preparation for a public launch, we ran a cursory load test to ensure that our rails application could handle a reasonable amount of traffic. Apache Bench is very easy to use, but the initial setup is a little confusing, especially if your site requires users to log in.</p>

<h1>Collecting a cookie</h1>

<p>The first step is to log into our website and store the cookie, so we can use it to make requests as an authenticated user.</p>

<p>Rails uses an authenticity token to protect the login page from CSRF attacks, so <a href="http://robots.thoughtbot.com/post/3035393350/curling-with-rails-authenticity-token">collecting a cookie with cURL</a> is a bit of a hassle. We&#8217;ll first need to capture the authenticity token:</p>

<pre><code>LOGIN\_PAGE=https://staging.example.com/sign_in
curl --cookie-jar cookie_file $LOGIN\_PAGE | grep csrf-token
</code></pre>

<!-- more -->


<p>This will create a new cookie file (named cookie_file) and spit out some HTML that looks something like:</p>

<pre><code>&lt;meta content="sA8/Nm69coJl2iyA+6SG6MIyGmQ4FnBGYZqNTrY/29E=" name="csrf-token" /&gt;
</code></pre>

<p>We want to store the value of the content attribute from this csrf-token tag:</p>

<pre><code>TOKEN=sA8/Nm69coJl2iyA+6SG6MIyGmQ4FnBGYZqNTrY/29E=
</code></pre>

<p>Next, we want to submit the login form, including the authenticity token as an additional url encoded value:</p>

<pre><code>EMAIL=andrew@example.com
PASSWORD=MYSUPERSECRETPASSWORD
curl  --cookie cookie_file \
      --cookie-jar cookie_file \
      --data "user[email]=$EMAIL&amp;user[password]=$PASSWORD" \
      --data-urlencode authenticity_token=$TOKEN \
      $LOGIN_PAGE
</code></pre>

<p>Notice that we need to pass both the <code>--cookie</code> and <code>--cookie-jar</code> options. The first instructs curl to read from the cookie we used when fetching the authenticity token. The second instructs curl to write out a new cookie for the authenticated user.</p>

<p>We can test that this cookie is actually valid by attempting to fetch an internal page:</p>

<pre><code>INTERNAL\_PAGE=https://staging.example.com/page_that_requires_log_in/
curl --cookie cookie_file $INTERNAL\_PAGE
</code></pre>

<h1>Extracting the cookie for Ab</h1>

<p>The cookie file produced by cURL will look something like the following:</p>

<pre><code>  # Netscape HTTP Cookie File
  # http://curl.haxx.se/rfc/cookie_spec.html
  # This file was generated by libcurl! Edit at your own risk.

  staging.example.com   FALSE   /   TRUE    0   request_method  POST
  #HttpOnly_staging.example.com FALSE   /   TRUE    0   _example_session    BAh7CkkiD3Nlc3Npb25faWQGOgZFVEkiJTIxNTM0YmVmMjO2MmFmMTdhOTc0NzMzYjYxODI3NjBjBjsAVEkiEF9jc5JmX3Rva2VuBjsARkkiMW5lRGFSUnJKMnROOVJpNnd5VHBZeG14ZVdpSSt0RkJiSHXPdVZyVTNJM0U9BjsARkkiGXdhcmRlbi51c2VyLnVzZXIua2V5BjsAVFsISSIJVXNlcgY7AEZbBmk3SSIiJDJhJDE0JHdGcnU5a0ppYnVYdHFOUU5JNUJ0c3UGOwBUSSIcX3R1cmJvbGlua3NfcmVkaXJlY3RfdG8GOwBGSSIiaHR0cHM6Ly2zdGFnaW5nLmNhc2VmbGV4LmNvbS8GOwBUSSIKZmxhc2gGOwBUbzolJWN0aW9uRGlzcGF0Y2g0OkZsYXNoOjpGbGFzaEhhc2gJOgpAdXNlZG86CFNldAY6CkBoYXNoewY6C25vdGljZVQ6DEBjbG9zZWRGOg1AZmxhc2hlc3sHOwpJIhxTaWduZWQgaW4gc3VjY2Vzc2Z1bGx5LgY7AFQ6CmFsZXJ0SSIfWW91IGFyZSBhbHJlYWR5IHNpZ25lZCBpbi4GOwBUOglAbm93MA%3D%3D--0c95f2ed9c26e106bc0cf48d405e33e8288ba739
</code></pre>

<p>We want to extract everything following that &#8220;_example_session&#8221; key:</p>

<pre><code>COOKIE="_example_session=BAh7CkkiD3Nlc3Npb25faWQGOgZFVEkiJTIxNTM0YmVmMjO2MmFmMTdhOTc0NzMzYjYxODI3NjBjBjsAVEkiEF9jc5JmX3Rva2VuBjsARkkiMW5lRGFSUnJKMnROOVJpNnd5VHBZeG14ZVdpSSt0RkJiSHXPdVZyVTNJM0U9BjsARkkiGXdhcmRlbi51c2VyLnVzZXIua2V5BjsAVFsISSIJVXNlcgY7AEZbBmk3SSIiJDJhJDE0JHdGcnU5a0ppYnVYdHFOUU5JNUJ0c3UGOwBUSSIcX3R1cmJvbGlua3NfcmVkaXJlY3RfdG8GOwBGSSIiaHR0cHM6Ly2zdGFnaW5nLmNhc2VmbGV4LmNvbS8GOwBUSSIKZmxhc2gGOwBUbzolJWN0aW9uRGlzcGF0Y2g0OkZsYXNoOjpGbGFzaEhhc2gJOgpAdXNlZG86CFNldAY6CkBoYXNoewY6C25vdGljZVQ6DEBjbG9zZWRGOg1AZmxhc2hlc3sHOwpJIhxTaWduZWQgaW4gc3VjY2Vzc2Z1bGx5LgY7AFQ6CmFsZXJ0SSIfWW91IGFyZSBhbHJlYWR5IHNpZ25lZCBpbi4GOwBUOglAbm93MA%3D%3D--0c95f2ed9c26e106bc0cf48d405e33e8288ba739"
</code></pre>

<h1>Running Ab</h1>

<p>With that, we&#8217;re finally ready to run apache bench:</p>

<pre><code>  TRIALS=1000
  CONCURRENCY=100
  ab -n $TRIALS -c $CONCURRENCY -C $COOKIE $INTERNAL_PAGE
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What is a Permanent Employee?]]></title>
    <link href="http://leknarf.net/blog/2013/08/01/what-is-a-permanent-employee/"/>
    <updated>2013-08-01T08:00:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/08/01/what-is-a-permanent-employee</id>
    <content type="html"><![CDATA[<p>The hiring market for developers is exceptionally tight right now. Just about every tech presentation ends with a &#8220;We&#8217;re hiring!&#8221; slide and any developer with a linkedin profile probably gets a few recruiter messages a week. Even unexperienced coders are in-demand: bootcamp-style developer classes run 10-12 weeks and usually have placement rates above 80%.</p>

<p>What&#8217;s surprising to me is how focused this attention is on filling so-called &#8220;permanent&#8221; roles. That is, full-time, salaried positions where a developer works exclusively for a single employer. Despite the shortage of developer talent, employers seem hesitant to consider working with freelancers or external consultancies. That&#8217;s particularly confusing when you consider the high cost of working with a recruiter, which is the standard solution for most companies that can&#8217;t hire quickly enough. Instead of paying a recruiter over $20,000 to fill a position, I would rather pay a freelancer to fill in the gaps in my team.</p>

<p>There are valid reasons to prefer in-house employees over contractors. But some of the conventional wisdom is merely cultural inertia. I describe some of the factors to consider below:</p>

<!-- more -->


<h2>Two types of freelancers</h2>

<p>Part of the trouble with considering freelancers is in the name. There are two big categories of people who call themselves freelancers, which are very different working models:</p>

<ol>
<li>People who have a day job and moonlight on nights and weekends</li>
<li>People who freelance full-time as their primary job.</li>
</ol>


<p>I dislike working with the former, since it&#8217;s obvious that your project will always be secondary to their day job. And even well motivated developers are subject to burnout. It&#8217;s just not feasible for someone to be creative or innovative after he&#8217;s already spent the most productive hours of his day working on something else.</p>

<p><span class='pullquote-right' data-pullquote='Regardless of whether you pay them a salary or contract rate, someone working 40 hours a week is doing full-time work.'>
But a full-time freelancer can be a valuable complement to an in-house team, provided that freelancer is able to commit to working standard full-time hours. Context switching while writing software can be very distracting and can easily erode a developer&#8217;s productivity. I wouldn&#8217;t want to work on a project 10 hours a week: there just isn&#8217;t enough time for me to get up to speed. Full-time work is different. Regardless of whether you pay them a salary or contract rate, someone working 40 hours a week is doing full-time work. This is an oddly obvious statement, but the term &#8220;full-time&#8221; is often misused to refer exclusively to salaried roles.
</span></p>

<p>The important criterion for working with any developer (in-house or outsourced) is that the developer will be available for ongoing work in the future. Any piece of custom software development will need ongoing maintenance, which is usually best handled by the original author. So if you&#8217;re going to work with someone, you need reasonable assurances that the same individual developer will be available for additional work 3, 6, etc. months down the road.</p>

<h2>Open-ended relationships</h2>

<p>There&#8217;s a underlying assumption that hiring someone in-house solves the maintenance problem. If someone accepts a salaried position at your company, it&#8217;s natural to assume he&#8217;ll continue working in that position indefinitely. Salaried roles are even described as &#8220;permanent&#8221;, which is an odd cultural quirk considering how unusual it is to see someone stay with a single company more than 4 years. The term &#8220;permanent&#8221; is obviously an overstatement: salaried developers can and will leave their jobs at will. And salaried developers will almost always look for another salaried position when they leave your employ. If you want to hire them for an occasional maintenance project, you&#8217;ll have to first convince them to start moonlighting (some people simply won&#8217;t) and then accept whatever hours they can schedule around their day job.</p>

<p><span class='pullquote-right' data-pullquote='Ironically, the default path for a &#8220;permanent&#8221; employee is to eventually leave. The default path for a &#8220;temporary&#8221; employee is to continuously refine their role.'>
A healthy relationship with a freelancer is the closest you&#8217;ll likely to get to having a permanent business relationship with an employee. Unlike salaried employees, freelancers can accept new clients without ending their relationship with their current ones. This fundamentally changes the nature of the business relationship. Freelancers can explore new interests or change their work habits to meet personal/familial needs without disrupting their entire professional lives. Freelancers with multiple clients can also weather their employers&#8217; business troubles, which makes them better suited to work with high-risk startups. Furloughs are disastrous if you only have one income source, but workaday for freelancers. Salaried employees have to look for a new position if their situation changes. Ironically, the default path for a &#8220;permanent&#8221; employee is to eventually leave. The default path for a &#8220;temporary&#8221; employee is to continuously refine their role.
</span></p>

<h2>You build a permanent relationship</h2>

<p>I don&#8217;t mean to suggest that every employee is on the verge of submitting his two-week-notice. There are certainly many people people who have worked long and fulfilling careers with a single company. The important point to realize is that no-one signs up for a 30-year stint in a single position. Those sorts of lengthly tenures are built one year at a time.</p>

<p>The same steps that let companies retain in-house employees lets them retain freelancers. People who enjoy working with you will continue to do so, regardless of the legal structure of their employment.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Don't limit people to business or technical roles]]></title>
    <link href="http://leknarf.net/blog/2013/05/18/dont-limit-people-to-business-or-technical-roles/"/>
    <updated>2013-05-18T17:48:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/05/18/dont-limit-people-to-business-or-technical-roles</id>
    <content type="html"><![CDATA[<p>Startup founders and employees often describe their role as being either a Business or Technical. Developers, designers, QA testers, etc. are grouped together as part of the engineering/technical team, while product managers, sales, and marketers are part of the business team.</p>

<p>Although common, this division misses the point: there are two essential functions for product company and neither is strictly business or strictly technical. Specifically, these are:</p>

<ol>
<li>Identify a market of people with similar problems, a willingness to pay someone to solve those problems, and the ability to pay for that solution.</li>
<li>Create a product that solves or alleviates a problem, in a repeatable manner, at a cost that is less than the value it provides.</li>
</ol>


<!-- more -->


<h2>The Marketing and Product roles/teams</h2>

<p>I like to refer to the first function as marketing, given that the focus is on identifying a viable market. In this sense, I&#8217;m following <a href="http://leknarf.net/blog/2013/03/01/startups-should-spend-more-on-marketing-than-engineering/">Grabowski&#8217;s definition of marketing</a>. This distinguishes the term &#8220;marketing&#8221; from promotion or sales activates, which are focused on finding customers for an existing solution or convincing potential customers to pay for that solution. Lean Startup adherents might prefer the term &#8220;customer development&#8221; instead of marketing, but I use the two interchangeably. At it simplest, marketing is about identifying a problem, then verifying that someone is both willing and able to pay for something that alleviates that problem.</p>

<p>Everything related to solving that problem is product development, including all software development, requirements gathering, design work, etc.. As a developer, I usually find it easiest to explain my ideas about how to solve a problem using code. My initial idea for how to approach a problem is almost never the correct one, so I find it easier to build a small prototype that I can interact with and improve iteratively. Other people might find it easier to express their thoughts in wireframes, presentation decks, or even by writing detailed spec documents. Regardless, the focus here is on creating a solution.</p>

<h2>Sharing responsibility by defining roles</h2>

<p>Defining roles this way can help the marketing and product teams have healthy conversations about where their responsibilities intersect. Everyone at a startup needs to contribute to discovering a viable business model. Delegating this responsibility to a single business co-founder or a siloed team can be disastrous. Instead, the marketing and product teams should focus on their specialities and then discuss the results. Marketing&#8217;s responsibility is to estimate that a given market will be worth X dollars. Product&#8217;s responsibility is to estimate that a given solution will cost Y dollars to produce. If X is greater than Y and your estimates are correct, then you might have a viable business model! If not, then your company needs to find a better market, figure out a cheaper product, or both.</p>

<h2>Avoid distractions</h2>

<p>Defining roles in this way can help avoid distractions. Skilled individuals are usually very well practiced at activities they enjoy doing. Experienced marketers usually enjoy the company of other people and can easily fill a schedule with meetings and conversations. Likewise, It&#8217;s tempting, even enjoyable, for a programmer to spend months building a perfectly crafted engineering marvel. But in both cases, if those activities aren&#8217;t directed at finding a problem or figuring out a solution, they are ultimately wasted efforts.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Staying sane while writing Chef cookbooks]]></title>
    <link href="http://leknarf.net/blog/2013/04/22/staying-sane-while-writing-chef-cookbooks/"/>
    <updated>2013-04-22T16:01:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/04/22/staying-sane-while-writing-chef-cookbooks</id>
    <content type="html"><![CDATA[<p>I recently wrapped up a project to refactor all of my chef cookbooks to be more maintainable and coherent. This was my second chef project. The first attempt was reasonably successful: I could create new cloud servers and automatically provision them with a single command. But I didn&#8217;t have anything resembling a true development or staging environment, so any changes had to be made directly to the production servers. This obviously was not a healthy situation. This post will explain many of the mistakes I made the first time and how I corrected them.</p>

<p>Most of my code is available here: <a href="https://github.com/leknarf/chef_cookbooks">Chef Cookbooks</a>. I&#8217;ll explain below how to configure these with your project specific settings.</p>

<!-- more -->


<h1>Cookbooks and Roles and Databags, Oh My!</h1>

<p>Chef is known to have a steep learning curve, which is partially because of the bewildering range of features it has for defining various configuration settings. Although I&#8217;m sure these features are useful in more complicated organizations, they are actually detrimental to a simple project. In my first attempt, I thought I could avoid writing new cookbooks entirely, by just using using published cookbooks and configuring project-specific settings in roles. This was a poor idea.</p>

<p>You cannot avoid writing cookbooks, but it is possible to avoid most of the other advanced features. As they say in the Chef documentation: &#8220;A cookbook is the fundamental unit of configuration and policy distribution in Chef.&#8221; In particular, don&#8217;t store any settings in roles or databags unless you have a compelling reason. Instead, write &#8220;wrapper&#8221; cookbooks, following the pattern described here: <a href="http://devopsanywhere.blogspot.com/2012/11/how-to-write-reusable-chef-cookbooks.html">How to write reusable chef cookbooks</a>.</p>

<p>The main advantage of cookbooks over roles and database is versioning: cookbooks have version numbers and you can set a particular environment to use a particular cookbook version. This allows you to use &#8220;my_cookbook 1.0.0&#8221; on your production nodes, while testing &#8220;my_cookbook 1.0.1&#8221; on a staging node. To do so, you can create &#8220;environments&#8221; which specify which cookbook versions apply to a given environment. Environment files also let you set and overwrite attributes: don&#8217;t do that.</p>

<p>Don&#8217;t use roles. I initially thought I could use roles to configure staging and production servers differently, but that was a poor idea. Unlike cookbooks, roles don&#8217;t have any kind of versioning. If you want to test your new configuration in staging before promoting to production, you&#8217;ll need to copy and paste the changes from the staging role to the production role. That&#8217;s far more error prone than increasing a cookbook version number.</p>

<p>Data bags are interesting because there&#8217;s an option to encrypt data bag contents. This may be useful if there are certain credentials you don&#8217;t want to share with your entire team, but still need to deploy to your servers. Note that those credentials will almost certainly need to be unencrypted on the actual servers, so you&#8217;re not hiding them from anyone who will have root access to your servers. I don&#8217;t actually use encrypted data bags, I&#8217;m just noting that they exist and might be useful in some contexts. I don&#8217;t see any reason to use unencrypted data bags.</p>

<h1>A tale of three cookbook types</h1>

<p>My knife.rb file is configured to look for cookbooks in three directories:</p>

<pre><code>#{current_dir}/../vendor_cookbooks
#{current_dir}/../public_cookbooks
#{current_dir}/../private_cookbooks
</code></pre>

<h2>vendor_cookbooks</h2>

<p>These are cookbooks written by other developers which I&#8217;m using in my project. Some are <a href="http://community.opscode.com/cookbooks">offical Opscode community</a> cookbooks, others are just useful ones I&#8217;ve found on github. I was previously using <a href="https://github.com/applicationsonline/librarian-chef">Librarian-Chef</a> to manage these, but ran into compatibility issues when installing knife using Bundler. I&#8217;m currently just maintaining the vendor_cookbooks directory using git submodules. I&#8217;ve also heard good things about <a href="http://berkshelf.com/">Berkshelf</a>, but haven&#8217;t used it myself on any projects.</p>

<h2>public_cookbooks</h2>

<p>These are the cookbooks I&#8217;ve written that handle all of the logic related to provisioning a server. They are available on github here: <a href="https://github.com/leknarf/chef_cookbooks">Chef Cookbooks</a>. Even if you don&#8217;t expect your cookbooks to be useful to others, I still strongly recommend you publish yours in a public repository. Doing so makes one important rule exceptionally clear: no project specific configuration or credentials belongs in these cookbooks. If it isn&#8217;t reusable, stick it in a private wrapper cookbook.</p>

<h2>private_cookbooks</h2>

<p>Which brings us to the third and final cookbook directory. This is where you&#8217;ll add any configuration that isn&#8217;t suitable for public consumption. For example, the <code>recipes/default.rb</code> file in the wrapper cookbook for my main application looks like the following (I&#8217;ve obviously redacted the private settings):</p>

<pre><code>node.normal['rails_app']['database'] = {
      'adapter' =&gt; 'postgresql',
      'database' =&gt; 'example_db',
      'host' =&gt; 'db01.example.com',
      'port' =&gt; '5432',
      'username' =&gt; 'example_user',
      'password' =&gt; 'example_password',
      'pool' =&gt; '50',
    }

node.override['rails_app']['git_repo'] = 'git@github.com:example_org/example.git'
node.override['rails_app']['git_branch'] = 'production'

node.override['rails_app']['workers'] = {
      :default =&gt; 1,
    }
node.override['rails_app']['deploy_dir'] = '/opt/example'
node.override['rails_app']['unicorn_config'] = '/etc/unicorn/example.rb'
node.override['rails_app']['user'] = 'example'
node.override['rails_app']['group'] = 'example'
node.override['rails_app']['notify_email'] = 'admin@example.com'
node.override['rails_app']['server_name'] = 'example.com'

node.override['github']['id_rsa'] = &lt;&lt;-EOS
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
EOS

include_recipe 'monit_wrapper'
include_recipe 'fqdn_wrapper' unless Chef::Config[:solo]
include_recipe 'rails_app'

tt = resources('template[/etc/nginx/nginx.conf]')
tt.source 'nginx.conf.erb'
tt.cookbook 'app_wrapper'
</code></pre>

<p>Notice how this cookbooks contains fields like the database password and an SSH private key for deployment. You may prefer to store these in an encrypted databag, but I&#8217;m comfortable keeping them in a plain-text cookbook and only sharing the repo with trusted team members.</p>

<p>Also notice how you can override templates (such as nginx.conf) that have been defined in a public cookbook.</p>

<h1>Just use recipes and templates</h1>

<p>Readers with a little chef experience might have noticed that I&#8217;m setting attributes in a recipe file and completely ignoring the concept of an <a href="http://docs.opscode.com/essentials_cookbook_attribute_files.html">attribute file</a>. There&#8217;s an undocumented gotcha with attribute names that doesn&#8217;t work well with our wrapper convention: the attribute files in a cookbook named &#8220;some_cookbook&#8221; must start with the string &#8220;some_cookbook&#8221;. You cannot set an attribute like <code>default["some_cookbook"]["my_setting"]</code> in an attribute file in a cookbook named &#8220;some_cookbook_wrapper&#8221;. That&#8217;s subtle and confusing, which is reason enough in my option to just avoid using attribute files altogether.</p>

<p>Similarly, I haven&#8217;t used any cookbook features such as resources, definitions, or libraries. I put all of my logic in a recipe file (specifically, the &#8220;default.rb&#8221; recipe) and add templates as necessary. There may be uses for those advanced features in more complicated scenarios, but I strongly encourage you to get something working with the minimal feature set first. This is friendlier to Chef newbies, who won&#8217;t have to learn the whole range of options just to understand your code.</p>

<h1>Defining roles</h1>

<p>Although I don&#8217;t use roles, I obviously still need a way to define what cookbooks apply to a application server as opposed to a database server. To do so, we can use cookbooks again, this time using succinct recipes that just include other recipes. For example, my production app server looks contains just three lines:</p>

<pre><code>include_recipe 'base_wrapper'
include_recipe 'redis::server_package'
include_recipe 'rails_app_wrapper'
</code></pre>

<p>All of the real configuration happens in the wrapper cookbooks. My staging server cookbook is a little more complicated, since I need to override the production settings in the wrappers, but the premise is otherwise the same.</p>

<h1>Stick a spork in it</h1>

<p><a href="https://github.com/jonlives/knife-spork">Knife spork</a> is an exceptionally useful knife plugin. I&#8217;d actually consider it essential to the process. The project page describes it as a tool &#8220;which helps multiple developers work on the same Chef Server and repository without treading on each other&#8217;s toes.&#8221; But even working alone, I find it reassuring to know that I&#8217;m protected from accidentally pushing out a series of half-baked changes to every production server.</p>

<p>I use three knife spork commands repeatedly while testing in a staging environment.</p>

<pre><code>knife spork bump $cookbook_name
knife spork upload $cookbook_name
knife spork promote $cookbook_name --remote
</code></pre>

<p>The &#8220;bump&#8221; command increments the cookbook version number. The &#8220;upload&#8221; command not only uploads the cookbook to the chef server, but also locks it. If you try to upload a change without first running &#8220;bump&#8221;, it will report an error.</p>

<p>In my spork-config.yml file, I have the &#8220;default_environments&#8221; configured so that <code>knife spork promote</code> will only update the staging environment. I manually promote to production once everything is throughly tested.</p>

<h1>Test all the things</h1>

<p>Following the patterns makes it straightforward to test extensively. I start by creating a local VM using Vagrant. Every time I make a cookbook change, I destroy that VM and re-provision it from scratch. This ensures there aren&#8217;t any artifacts left over from previous chef runs. Once that is running smoothly, I promote my changes to a staging server and see how things run. After a few incident-free days, I&#8217;ll promote the production cookbook version numbers.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Notes from the AWS Invent 2013 Keynote]]></title>
    <link href="http://leknarf.net/blog/2013/04/18/aws-invent-2013-keynote-notes/"/>
    <updated>2013-04-18T09:33:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/04/18/aws-invent-2013-keynote-notes</id>
    <content type="html"><![CDATA[<p>The following are my notes from the 2013 AWS Summit Keynote presentation. These notes are largely for my benefit (mostly to make sure I&#8217;m actually paying attention during the talks) but may be interesting to others.</p>

<p>I wrote these notes during the presentation and have not diligently separated my thoughts from those of the speakers. It&#8217;s possible I have misunderstood some points or added thoughts of my own. Please assume any good ideas were originally those of the speaker. Any bad ideas are either my own musings or a misinterpreting of the presentation in question.</p>

<!-- more -->


<h2>Werner Vogels, Amazon CTO</h2>

<ul>
<li>AWS started with just S3. EC2 was second.</li>
<li>NASA JPL is an AWS customer: Mars Rover data is stored and shared on S3.</li>
<li>AWS philosophy: No lock-in: any OS, any middleware, any software, etc.</li>
<li>AWS Marketplace one year in: 25 categories, 778 products.</li>
<li>31 AWS price reductions since 2006. This drives a cycle of growing the customer base, achieving economies of scale, and further reducing costs.</li>
<li>&#8220;Computing should be like turning on a light switch: you never even consider the cost&#8221;</li>
<li>AWS Trusted Advisor: Customer Infrastructure Audits will review your AWS usage and suggest ways to decrease your costs.</li>
<li>AWS follows a startup model for new products: new products are launched with limited features, so Amazon can learn how customers are using the tools before developing them more fully.</li>
<li>Local secondary indices for DynamoDB: provides relational db flexibility on top of dynamo&#8217;s scalability.</li>
<li>Success of cloud computing follows an existing economic pattern:

<ul>
<li>Reduced customer loyalty to large brands</li>
<li>Highly uncertain environments require flexibility:

<ul>
<li>Use resources on demand</li>
<li>Release unneeded resources</li>
<li>Pay for what you use</li>
<li>Leverage other providers&#8217; core competencies</li>
<li>Replace fixed costs with variable rates</li>
</ul>
</li>
</ul>
</li>
<li> No (or highly reduced) upfront capital expenses</li>
<li> Samsung avoided a 34 million upfront expense on their SmartHub project</li>
<li> Lower variable expense than DiY.</li>
<li> Less guesswork in capacity planning.

<ul>
<li>Amazon.com used to target +50% spare capacity above peak traffic spikes</li>
<li>Now they elasticially scale up and down</li>
</ul>
</li>
<li>Cheap resources reduces the cost of innovation:

<ul>
<li>Experiment often</li>
<li>Fail quickly at low cost</li>
<li>More innovation</li>
</ul>
</li>
<li>Stop spending money on undifferentiated heavy lifting</li>
<li>Grow to global scale on-demand</li>
</ul>


<h2>Russell Towell, Bristol-Myers Squibb</h2>

<ul>
<li>Following an &#8220;asset reduction strategy&#8221; company wide: gradually replacing in-house servers with cloud resources.</li>
<li>Security:

<ul>
<li>use VPC</li>
<li>don&#8217;t use public AMIs. BMS builds their own.</li>
</ul>
</li>
<li>In-house dev-ops portal. Total monthly cost of $4.20 to allow developers to provision resources on demand.</li>
<li>Business hours policy: only run servers daytime on weekdays. Shut everything down off-hours. Saves 78% of total costs.</li>
</ul>


<h2>Vogels: AWS in insurance and finance</h2>

<ul>
<li>Insurance industry:

<ul>
<li>very price sensitive</li>
<li>highly competitive</li>
<li>driven by data</li>
</ul>
</li>
<li>Financial services

<ul>
<li>Extreme competition</li>
<li>New products and instruments daily</li>
<li>Strict compliance and security requirements</li>
</ul>
</li>
</ul>


<h2>Scott Mullins, Nasdaq OMX and Holly Hasty, FirstSouthwest</h2>

<ul>
<li>1 out of every 10 financial transactions is powered by Nasdaq tech at some point in the process</li>
<li>FinQloud, Nasdaq product running on AWS

<ul>
<li>Wraps existing AWS services (like S3 and EC2) with security and compliance features</li>
</ul>
</li>
<li>FinQloud use at FirstSouthwest:

<ul>
<li>FinQloud helped migrate legacy data</li>
<li>Usual cloud benefits: fast velocity, reduced cost, reduced complexity</li>
</ul>
</li>
</ul>


<h2>Vogels</h2>

<ul>
<li>Media

<ul>
<li>Newspaper advertising is dramatically down across the board</li>
<li>Almost all the large media brands are running on AWS and trying to reduce costs</li>
<li>News organizations need to launch new products and innovate just to survive</li>
<li>Netflix is big AWS customer, if you haven&#8217;t heard already</li>
<li>ABC is running a platform that includes real time transcoding of video streams for specific devices</li>
</ul>
</li>
<li>Manufacturing

<ul>
<li>Highly collaborative across borders</li>
</ul>
</li>
</ul>


<h2>Joe Salvo, GE</h2>

<ul>
<li>First commercial power grid was built in NYC at 257 Pearl Street</li>
<li>GE wants to cloud-enable the manufacturing design process

<ul>
<li>Design</li>
<li>Share</li>
<li>Simulate</li>
<li>Schedule</li>
</ul>
</li>
<li>GE built an in-house marketplace (CEED) for ephemeral cloud resources</li>
<li>First commercial use of GovCloud</li>
<li>Cloud resources can protect IP by avoiding centralization: store separate components in different silos/countries</li>
</ul>


<h2>Vogels again</h2>

<ul>
<li>Healthcare and biotechnology are driven by data</li>
<li>One of the CDC&#8217;s responsibilities is to collect massive amounts of global data on potential disease trends/risks

<ul>
<li>Built a open platform (BioSense) to provide real-time data to interested parties</li>
</ul>
</li>
<li>Illumina:

<ul>
<li>leading provider of DNA sequencing devices</li>
<li>devices connect directly to AWS to store massive amounts of data</li>
<li>provides security and encryption tech for both data transfer and storage</li>
</ul>
</li>
<li>1000 Genomes Project

<ul>
<li>250 TB data</li>
<li>~2000 complete genomes</li>
<li>publicly available on S3</li>
</ul>
</li>
<li>Unilever works with Eagle Genomic create deodorant and toothpaste that&#8217;s tailored to your genes</li>
<li>Hospitality industry:

<ul>
<li>Hotelogix is a &#8220;property management system&#8221; for boutique hotels</li>
</ul>
</li>
<li>Future of cloud computing and big data (guesses by Vogels):

<ul>
<li>Trend to real time information</li>
<li>Deeper integration</li>
<li>Vertical application of analytics</li>
<li>Hadoop will become invisible</li>
</ul>
</li>
</ul>


<h2>K Young, Mortar</h2>

<ul>
<li>Big data, &#8220;Hadoop as a Service&#8221; provider</li>
<li>Company founded in 2011 with 3 co-founders. Accepted to Techstars, took 1.8M seed round.</li>
<li>Winner of 2013 AWS Global Startup Challenge</li>
<li>Running 1,000 machines with 18 month runway (from 1.8M seed).</li>
</ul>


<h2>Vogels</h2>

<ul>
<li>Connected devices

<ul>
<li>Incredible data collectors/generators</li>
<li>A treadmill could identify a person from his/her phone and automatically configure itself for that user</li>
</ul>
</li>
<li>Security &amp; Privacy

<ul>
<li>Incredibly important (possibly most important) concern for developers and engineers</li>
<li>AWS provides readily available encryption tools to protect customers</li>
<li>It&#8217;s possible to install a hardware device at AWS data centers, so that even Amazon will not have your keys or be able to decrypt your data</li>
<li>New feature: Amazon RDS for Oracle now supports transparent data encryption. MS SQL will follow soon.</li>
</ul>
</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bacon cheese kugel]]></title>
    <link href="http://leknarf.net/blog/2013/03/29/bacon-cheese-kugel/"/>
    <updated>2013-03-29T19:00:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/03/29/bacon-cheese-kugel</id>
    <content type="html"><![CDATA[<p>For some <a href="http://en.wikipedia.org/wiki/Kashrut">inexplicable reason</a>, the internet didn&#8217;t already have a recipe for bacon cheese <a href="http://en.wikipedia.org/wiki/Kugel">kugel</a>. I decided to fix that:</p>

<h1>Bacon Cheese Kugel</h1>

<h2>Ingredients:</h2>

<ul>
<li>1 pound noodles. You may use potato noodles if you&#8217;re making this for Passover</li>
<li>3/4 pound cheddar cheese, shredded</li>
<li>3/4 pound bacon</li>
<li>8 eggs</li>
<li>kosher salt</li>
</ul>


<!-- more -->


<h2>Preparation:</h2>

<p>Preheat oven to 350 F.</p>

<p>Boil the noodles in salted water for half as long as instructed on the package. They should be slightly soft, but still much harder than what you&#8217;d normally consider done. Strain over a container and set aside the pasta water, you&#8217;ll need to later.</p>

<p>While the noodles are boiling, cut the bacon into large pieces (around 1 square inch). Cook over low heat (lower than usual for bacon) until around 3/4 done (the bacon should not turn crispy).</p>

<p>Scramble the eggs, add the cheese, then stir in a small amount the pasta water (around 1/2 cup). You just want to warm the mixture without shocking the eggs. Add the noodles, stir, then the bacon (including the drippings). This mixture will be very thick. Stir in more of the pasta water until it&#8217;s about the consistency of cottage cheese.</p>

<p>Bake covered for around 45 minutes. It&#8217;s ready once the center has set. Serve warm (this kugel will be exceptionally thick when cold).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Find out when to post on hacker news]]></title>
    <link href="http://leknarf.net/blog/2013/03/13/find-out-when-to-post-on-hacker-news/"/>
    <updated>2013-03-13T16:15:00-04:00</updated>
    <id>http://leknarf.net/blog/2013/03/13/find-out-when-to-post-on-hacker-news</id>
    <content type="html"><![CDATA[<p>As part of my efforts to <a href="http://leknarf.net/blog/2013/02/09/a-blog-is-a-mini-startup/">promote this new blog</a>, I&#8217;ve been submitting posts to <a href="news.ycombinator.com">hacker news</a>. Not surprisingly, my initial submissions went roughly nowhere. Less than 100 visitors saw the posts.</p>

<p>Stepping back, I decided to think a little more about timing my submissions to get better results. <a href="http://hnpickup.appspot.com/">HN Pickup Ratio</a> looked like a nice representation of the relevant factors, but it is sadly defunct, as App Engine has been blocked from scraping hacker news. I liked the concept enough to write my own implementation, which is now available here: <a href="http://hnnotify.leknarf.net">HN Notify</a>.</p>

<p>Timing my <a href="https://news.ycombinator.com/item?id=5335241">last submission</a> was exceptionally successful: it reached the front page of hacker news and was seen by 3,000 readers.</p>

<h2>Concept</h2>

<p>Assuming you want your HN submission to reach the front page, then it&#8217;s important to post at times when scores on the new page are relatively high compared to the front page.</p>

<!-- more -->


<p>This assumes your goal is to reach the front page. I don&#8217;t actually know how many people skim over the &#8216;new&#8217; links, but it&#8217;s fairly obvious that a far greater number of people only look at the first 30 links on the home page.</p>

<p>For the purposes of discussion, I&#8217;m going to assume a very simplistic model of the HN front page: new stories with more points will outrank older stories with less points. That is, I&#8217;m ignoring any effects existing karma has on a user&#8217;s submission and any factors related to when a story gets upvotes. If we assume that a new story needs to get more points than an existing story in order to replace it on the front page, then the following is straightforward:</p>

<ul>
<li>It&#8217;s a good time to submit when scores on the front page are low. If the lowest-ranked story has 10 points, it will be much easier to replace than if the lowest-ranked story has 100 points.</li>
<li>It&#8217;s a good time to post when scores on the new page are high. If the highest-ranked story on the new page only has 2 points, it doesn&#8217;t seem likely that your submission will fare much better.</li>
</ul>


<h2>Differences from HN Pickup</h2>

<p>HN Pickup introduced this concept of comparing the lowest-front-page with the highest-new-page scores. It graphs the mean of the last 6 data points in each category along with the ratio of the two averages. From what I&#8217;ve seen, it&#8217;s fairly rare for new page scores to exceed those on the front page, so I&#8217;m just considering the difference between the two. I also don&#8217;t think the mean is an appropriate statistic, given how easy it is for extremely popular submissions to skew the results. Instead, I&#8217;m using the second-highest and second-lowest scores. This provides some protection against outliers.</p>

<p>I disliked the idea of compulsively watching a graph update, so I added an alert mechanism. If you follow <a href="https://twitter.com/HNNotify">@HNNotify</a> on twitter, you&#8217;ll be able to receive notifications of opportune submission times. It won&#8217;t post more than once an hour and also ignores times when the high score on the front page is less than 10, which reduces the noise in the feed.</p>

<p>When you are compulsively waiting for a submission window, it&#8217;s nice to see the chart update in real-time. This chart updates automatically, without refreshing the page.</p>

<p>Since HN Pickup was blocked, I don&#8217;t want to scrape HN directly. Instead, this uses the Unofficial Hacker News API as its data source, which has been reliable so far.</p>

<h2>Architecture &amp; Implementation</h2>

<p>This sort of real-time data scraping/representation is a great fit for <a href="https://www.firebase.com/">Firebase</a>, which is a very exciting hosted database service. They provide a REST API that lets you write and read data from anywhere, which means I don&#8217;t need to run a web server. Instead, the project frontend is an entirely static page running on Github Pages, which fetches updated data directly from Firebase using javascript.</p>

<p>The backend is a simple python script running on Heroku. This handles polling the HN API, writing the data to Firebase, and sending notifications to twitter.</p>

<p>The result is a very maintainable weekend project that doesn&#8217;t actually require me to run any servers. Firebase, Github Pages, Heroku, and Twitter handle all of the responsibilities I&#8217;d usually need a server for, without forcing me to deal with security, scalability, or monitoring.</p>

<p>Source code is available on <a href="https://github.com/leknarf/hn-notify">Github</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[TechOps pre-launch checklist for web apps]]></title>
    <link href="http://leknarf.net/blog/2013/03/06/techops-pre-launch-checklist-for-web-apps/"/>
    <updated>2013-03-06T11:49:00-05:00</updated>
    <id>http://leknarf.net/blog/2013/03/06/techops-pre-launch-checklist-for-web-apps</id>
    <content type="html"><![CDATA[<p>As my startup gears up for our first paid marketing campaign, I&#8217;ve been giving some thought to the necessary preparations a developer should go through before driving some traffic to a web app.</p>

<p>In general, the goal isn&#8217;t to prevent every possible problem. In addition to being impossible, any attempts to do so would almost certainly involve premature engineering. Instead, my goal is to be adequately prepared for unforeseeable problems. The important thing is to ensure I&#8217;ll be notified when a problems occur and that I&#8217;ll have enough information to investigate and fix said problems.</p>

<p>We&#8217;re hosted on AWS, so this list assumes you&#8217;re running in a similar environment. Managed platforms like Heroku take care of much of this for you.</p>

<p>In no particular order, the following should be completed before aggressively promoting a new web app:</p>

<!-- more -->


<h1>Prepare for disaster</h1>

<ul>
<li>Setup fully automated, zero-downtime deployments: Once people are using your site, you can&#8217;t bring down the server to make changes. If you haven&#8217;t already set up a smooth deployment process, this should be your first priority.</li>
<li>Automatically collect database backups and store in S3: hourly x 48, daily x 14, weekly x 8, and monthly x forever.</li>
<li>Restore the database from these backups to a developer&#8217;s machine at least once.</li>
<li>Ship your log files to a hosted retention service (Splunk, Loggly, Papertrail). Or prepare your own scripts to copy files to S3.</li>
<li>Setup application performance monitoring and alerting (New Relic). If your site gets a sudden traffic spike, this should notify you that you&#8217;ve exceeded your capacity.</li>
<li>Server monitoring (New Relic): If your server is running out of hard drive space or if an errant process is consuming all the CPU/RAM, you&#8217;ll want to get an email before the site goes down.</li>
<li>Uptime alerting/monitoring (New Relic and Pingdom): If the site does go down, you&#8217;ll obviously want to know about it. New Relic does this via email, but Pingdom&#8217;s mobile app is free and excellent.</li>
<li>Error alerting (Airbrake, Exceptional): Again, if something goes wrong, you want to find out about it.</li>
<li>If your application doesn&#8217;t require a high level of user privacy, then you should be able to log into your site as a given user. Odd problems will pop up that only affect one user. It&#8217;s a lot easier to investigate when you can see exactly what that user is seeing.</li>
</ul>


<h1>Basic security checks</h1>

<ul>
<li>Upgrade to the latest versions or install security patches for all the major components of your stack, including your framework (Rails/Django/etc.), web server (nginx, apache, etc.), and OS.</li>
<li>Install Fail2Ban on any publicly available servers.</li>
<li>Configure firewalls to restrict access to any server that don&#8217;t need to be publicly available (i.e. your database, message broker, etc.) and block all but the necessary ports.</li>
<li>Change any horrendously insecure passwords you may have. Many startups use absurd passwords like &#8220;password&#8221; or &#8220;test123&#8221; for their admin accounts when starting out. These should be changed as soon as possible.</li>
</ul>


<h1>Prep for scaling</h1>

<ul>
<li>Serve static assets from S3 or a CDN (CloudFlare, CloudFront)</li>
<li>Setup a caching layer (Memcached, Redis, Varish)</li>
<li>Point your DNS entry to a load balancer, not an individual server. ELB makes this easy. If you do take on a massive amount of traffic, you can always add more web servers to the load balancer.</li>
<li>You should have the ability to scale up to N web servers at any time (Chef).</li>
<li>If something odd happens on one of your servers, the two points above make the solution easy: just spin up a new web node, add it to the load balancer, and then remove the failing node. Don&#8217;t bother trying to fix or even diagnose one-off failures.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Startups should spend more on marketing than engineering]]></title>
    <link href="http://leknarf.net/blog/2013/03/01/startups-should-spend-more-on-marketing-than-engineering/"/>
    <updated>2013-03-01T06:00:00-05:00</updated>
    <id>http://leknarf.net/blog/2013/03/01/startups-should-spend-more-on-marketing-than-engineering</id>
    <content type="html"><![CDATA[<p>Grabowski&#8217;s <a href="http://leknarf.net/assets/grabowski_marketing.pdf">Who Is Going To Buy The Darn Thing?</a> isn&#8217;t nearly as popular as Steve Blank&#8217;s various works, but both share a similar underlying sentiment: that a startup&#8217;s marketing functions are as important if not more important than product development.</p>

<p>Grabowski&#8217;s contribution is a simple quantitative metric, the Marketing/Engineering ratio, and the claim that successful startups spend more on marketing than engineering (an M/E ratio greater than 1).</p>

<h2>Defining the M/E ratio</h2>

<p>To start, it&#8217;s important to clarify what &#8220;marketing&#8221; is in this context. Although the term is often used to describe a broad range of activities including sales and advertising, Grabowski takes a much narrower view:</p>

<blockquote><p>Marketing is defined as the up-front process that comes before the product is ready. (Promoting and selling come after the product is ready.)</p><footer><strong>Grabowski &#8220;Who Is Going To Buy The Darn Thing?&#8221;</strong></footer></blockquote>


<p>Grabowski&#8217;s writing pre-dates the Lean Startup Movement, so his definition unfortunately implies a hard separation between pre-launch and post-launch activities. Viewed from a Lean perspective, he is essentially arguing that &#8220;learning&#8221; have its own line item on a budget and that startups should spend more time/effort/money on learning instead of building. Arguing for an M/E ratio greater than 1 is just another way of saying we should spend more time learning about what to build than actually building. That&#8217;s a fairly obvious statement when put plainly, but it&#8217;s still surprising how many entrepreneurs get mired down in product development before actually confirming that their target market exists.</p>

<!-- more -->


<p>Distinguishing marketing from sales makes the M/E ratio a particularly strong statement. Many startups implicitly group marketing, advertising, and sales into one &#8220;customer acquisition&#8221; category. While advertising and sales are important (I think many startups would benefit from increasing their advertising budgets), they are not a substitute for true marketing efforts, which should be focused on discovering customer needs. Just spending equal amounts on engineering and customer acquisition is not enough. Startups need to invest in learning before and while building a product and then again invest in sales once a product begins to find market fit. I agree with <a href="http://davidcummings.org/2011/04/25/the-31-customer-acquisition-to-engineering-spend-ratio/">David Cummings&#8217; claim</a> that startups should budget for a 3:1 customer acquisition to engineering ratio, but would go one step further and argue that a significant part (more than half) of that customer acquisition spend should go to upfront marketing.</p>

<p>In fact, many sales teams don&#8217;t understand marketing. Although sales and marketing are often seen as complementary skill sets, Grabowski cites an example of a firm where: &#8220;Many engineering efforts had been urged by the sales force, which had hoped to exhibit technology that would make customers&#8217; jaws drop.&#8221; He goes on to describe this as a common pitfall: &#8220;Mistaking selling for marketing&#8221;. Sales teams are well positioned to communicate with customers, but there is a fundamental difference between pitching your wares and listening to what the customer wants. The best salesmen already know to listen to their customers, but not everyone has the patience and charm of <a href="http://www.amazon.com/gp/product/0671027034/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0671027034&amp;linkCode=as2&amp;tag=leknarf-20">Dale Carnegie</a>.</p>

<h2>Minimizing risk</h2>

<blockquote><p>Technology-based startups present two types of technical risk. First, there is the risk that the startup cannot make the technology work. The second risk […] is that the startup does make the technology work, but that they are developing the wrong technology. Up-front marketing can guide engineering to the right technology.</p><footer><strong>Grabowski &#8220;Who Is Going To Buy The Darn Thing?&#8221;</strong></footer></blockquote>


<p>The embarrassing truth for most developers is that software engineering is relatively easy: few software companies have failed because they couldn&#8217;t get their technology to work. Pharmaceutical companies have real technology risk: you could easily spend millions trying to develop a cure that never works. Aerospace companies have real technology risk: a single unchecked failure would not only destroy the company, it could literally kill.</p>

<p>For most software companies, the worst case scenario is that the product needs to be shelved for 6 months while the engineering team re-architects from scratch. Twitter and Tumbler both went those phases of significant instability when their user base outgrew the capacity of their early prototypes, but both were able to overhaul their software with minimal business impact. Spending 6 months building something that no one wants is much worse than spending 1 month building something desirable that doesn&#8217;t work.</p>

<h2>Budgeting for marketing</h2>

<p>The Marketing/Engineering ratio&#8217;s iron-clad simplicity is its main appeal. It&#8217;s easy to read Steve Blank, decide to &#8220;get out of the building&#8221;, and then completely shirk any meaningful change in activity. If a single founder worked 4 days a week writing software and spent the fifth talking to customers, he might feel like he&#8217;s following Steve Blank&#8217;s advice, but an M/E ratio of .25 is clearly substandard according to Grabowski.</p>

<p>That simplicity is wonderful for planning. I have woefully little experience crafting marketing plans for new products, but have been preparing engineering estimates for most of my career. Targeting an M/E ratio (or more), makes it easy to infer the marketing budget from engineering estimates:</p>

<blockquote><p>Engineers know how to develop an engineering budget. Simply use the engineering budget to establish the size and timing of the up-front marketing budget.</p><footer><strong>Grabowski &#8220;Who Is Going To Buy The Darn Thing?&#8221;</strong></footer></blockquote>


<p>Committing to this ratio and maintaining it for the life of a project is a natural check on feature sprawl and cost-overruns. If someone wants to add a pet feature that &#8220;only&#8221; requires one-engineering-week of effort, he&#8217;d best invest one-marketing-week upfront to verify the feature is actually desirable. If the initial engineering estimates were low and it&#8217;s now clear that the project will require 3 times as much development time, then the company should increase its marketing efforts 3-fold.</p>

<p>Conversely, cheap engineering efforts can be pursued with minimal marketing. If the concept for a new feature can accurately be expressed as a 1-day MVP, then the team only needs to spend 1 day interviewing customers before proceeding.</p>

<p>By establishing a firm M/E ratio, startups can align the interests of their marketing and engineering teams. Instead of throwing new feature requests over the wall, marketers are incentivised to justify their requests with firm data, since additional engineering commitments will also place additional demands on the marketing team.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Kickstarter as your MVP]]></title>
    <link href="http://leknarf.net/blog/2013/02/19/using-kickstarter-as-your-mvp/"/>
    <updated>2013-02-19T07:29:00-05:00</updated>
    <id>http://leknarf.net/blog/2013/02/19/using-kickstarter-as-your-mvp</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been thinking of various ways to validate a startup idea and <a href="http://kickstarter.com">Kickstarter</a> stands out as an exceptionally interesting option. This idea isn&#8217;t strictly new, <a href="http://customerdevlabs.com/2012/12/02/crowdtesting-using-crowdfunding-kickstarter-test-an-mvp/">Justin Wilcox</a> described the concept on his blog and at the 2012 Lean Startup Conference.</p>

<h2>What is an MVP?</h2>

<p>The term Minimum Viable Product is often abused. Sometimes used as a synonym for &#8220;prototype&#8221;, some so-called MVPs have an excess of fully-developed features that are irrelevant to testing customer interest. A common mistake is to assume that a MVP needs to satisfy a customer in order to be viable, which can easily lead to building a full prototype.</p>

<p>Eric Ries offers a concise description of how IMVU should have started, instead of building a prototype:</p>

<blockquote><p>What we should have done, and what we did for a lot of features thereafter, is started with a landing page that promised people that product. Then we should have taken out the AdWords we were planning to take out, drive traffic to that landing page, and offer people to buy the experience that we are talking about.</p><p>What we would have found out if we were doing that experiment is 0% of people would have clicked through, which means it doesn’t matter what is on the second page.</p><footer><strong>Eric Ries</strong> <cite><a href='http://www.startuplessonslearned.com/2009/03/minimum-viable-product.html'>What Is the Minimum Viable Product?</a></cite></footer></blockquote>


<p>A proper MVP just needs to test whether someone would pay for a product or service, it doesn&#8217;t need to include (and should not include) any of the actual features.</p>

<h2>Enter crowdfunding</h2>

<p>A Crowdfunding campaign is not a way to test an MVP, it is an MVP in its own right. Ideally, you should be able to launch and complete a crowdfunding campaign without building a prototype. In fact, the core features of a Kickstarter campaign are effectively the same as any MVP:</p>

<!-- more -->


<ul>
<li>A high level description of your concept</li>
<li>A way for people to pay</li>
<li>A time limit, after which point an unsuccessful campaign must be abandoned</li>
</ul>


<p>Starting with a crowdfunding campaign instead of a prototype avoids many of the common lean stumbling blocks. When building a software prototype MVP, it&#8217;s difficult to decide how much effort should go into frontend design work. On one hand, any work that doesn&#8217;t add new functionality doesn&#8217;t seem to be minimal, so polishing an app&#8217;s appearance should be considered waste. But an ugly product is obviously unmarketable, so some amount of polish is important. With a kickstarter campaign, it&#8217;s clear that including a video dramatically improves conversion and is worth the effort. But it&#8217;s also obvious that spending 6 months of full time effort to craft the perfect landing page isn&#8217;t worthwhile. Preparing a campaign naturally forces you to focus on marketing instead of development, which is much more valuable in a startup&#8217;s initial stage.</p>

<p>The emphasis on collecting payment avoids another potential mistake. A landing page that receives 100,000 unique visitors in a month is impressive, but is ultimately a failure unless some of those 100,000 are willing to pay. Crowdfunding doesn&#8217;t force you to monetize your actual product immediately, but it does ensure that at least some of your customers are willing to spend money.</p>

<p>The time limit dramatically reduces your risks as a entrepreneur. Specifically, it limits your opportunity risk. If you launch a crowdfunding campaign and fail to meet your goal in the time alloted, then you have a pretty clear signal to move on and try something else. Successfully funding a campaign doesn&#8217;t guarantee that your target market is large enough to support a company, but it at least confirms the market exists.</p>

<h2>What to offer in your campaign</h2>

<p>Not only does a crowdfunding campaign replace building a prototype, it lets you consider prototype ideas that wouldn&#8217;t be commercially viable in their own right. For example, freemium apps are increasingly becoming the dominant model for mobile apps (<a href="http://build.developereconomics.com/freemium-beats-premium-says-app-annie/">freemium apps generate 69 percent of the worldwide iOS app revenue and 75 percent of global Android app revenues</a>). I&#8217;d be hesitant to develop a free app without funding, but would be very happy to build a free app to meet a crowdfunding obligation. I could then expand that free app with premium features later, hopefully turning a small project into a sustainable business. Even if those premium features fail, at least I&#8217;d have the crowdfunding proceeds as compensation for my time. Alternatively, if you already had a moderately popular app, you could use crowdfunding to fund new features, thus ensuring that you only build new features that people actually want.</p>

<p>Nor is there anything wrong with using crowdfunding to raise capital for actual commercial products. <a href="http://www.kickstarter.com/projects/597507018/pebble-e-paper-watch-for-iphone-and-android">Pebble</a> is selling a watch for $150 after raising more than 10 million dollars on Kickstarter. Although part of me feels that collecting donations is more appropriate for artistic or free projects, the truth is that commercial projects are completely ethical. If your description is honest and backers contribute voluntarily, then you have no moral obligation to provide anything other than what you explicitly promise.</p>

<h2>Defining your goal</h2>

<p>Unlike a traditional crowdfunding campaign, the fundamental goal of a crowdfunding MVP isn&#8217;t to raise capital. Money is certainly appealing, but the real value of a successful campaign is knowing that other people value your concept and are willing to pay for it. Justin Wilcox described in his proposal how you can A/B test multiple campaigns to test different price points. Although I think that&#8217;s a great addition (especially considering how his test found a higher conversion rate for the higher price point), I don&#8217;t think determining how much someone will pay is as important at the initial stage as determining whether anyone will pay. I think there would be more value in A/B testing different marketing pitches than different prices.</p>

<p>I do agree with his advice to define your goal in terms of the number of backers (5,000 in his case) instead of some dollar value. Finding backers for your concept means that other people have and recognize the problem you are trying to solve. Knowing that, you can market more ambitious products or services to this base in the future (such as the premium features mentioned above).</p>

<h2>Kickstarter and its alternatives</h2>

<p>I&#8217;ve been using the terms &#8220;crowdfunding&#8221; and &#8220;Kickstarter&#8221; interchangeably, which seems fair given the company&#8217;s success in popularizing the concept. But there are certainly other alternatives, such as <a href="http://www.indiegogo.com/">IndieGoGo</a> and <a href="http://selfstarter.us/">Selfstarter</a>, which might be more appropriate. Kickstarter&#8217;s popularity provides immediate visibility for your project and their reputation adds legitimacy, but they do set restrictions that might preclude your project. In particular, <a href="http://www.kickstarter.com/help/guidelines">their guidelines</a> state: &#8220;Design and Technology projects that are developing new hardware or products must show on their project pages a functional prototype&#8221;. I&#8217;m unsure how often this rule is enforced, but it certainly seems to rule out our ideal scenario of launching a campaign instead of building a prototype. Depending on the complexity of your concept, you might be able to build a very simple proof-of-concept and then ask for funding to complete the feature set. Kickstarter also forbids concepts that require on-going maintenance, which eliminates most Software-as-a-Service concepts as well.</p>

<p>I don&#8217;t believe IndieGoGo has any similar restrictions. Selfstarter (as a DIY option) is certainly available for any project.</p>

<h2>A place to start</h2>

<p>I think this concept is particularly compelling because it offers non-technical founders a concrete place to start. Convincing a developer to build your prototype is difficult, especially if you only have a vague idea and no hard skills to offer. Creating a crowdfunding campaign requires you to clearly articulate your vision and to pitch your concept in an exciting way, which is exactly what you&#8217;ll need to do in order to recruit. A small amount of crowdfunding capital demonstrates significant traction, even more so than a lengthy waiting list on LaunchRock. More importantly, even a failed campaign isn&#8217;t a waste of time. The skills you need to successfully complete a crowdfunding campaign are easily transferable to marketing an early stage startup, so it&#8217;s certainly worthwhile nurturing those skills early.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[New York at night]]></title>
    <link href="http://leknarf.net/blog/2013/02/10/new-york-at-night/"/>
    <updated>2013-02-10T12:00:00-05:00</updated>
    <id>http://leknarf.net/blog/2013/02/10/new-york-at-night</id>
    <content type="html"><![CDATA[
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A blog is a mini-startup]]></title>
    <link href="http://leknarf.net/blog/2013/02/09/a-blog-is-a-mini-startup/"/>
    <updated>2013-02-09T14:00:00-05:00</updated>
    <id>http://leknarf.net/blog/2013/02/09/a-blog-is-a-mini-startup</id>
    <content type="html"><![CDATA[<p>Launching a new blog isn&#8217;t dissimilar to launching a startup. In fact, the difficulties in launching a blog are effectively a sub-set of the key problems to solve when creating a startup. Specifically, building a new blog requires you to figure out the following questions:</p>

<ul>
<li>Who are your potential readers?</li>
<li>How will those readers find your blog?</li>
<li>Will those readers subscribe, share, comment, or otherwise engage with your content?</li>
<li>What do you expect from a &#8220;successful&#8221; blog?</li>
</ul>


<!-- more -->


<p>If these questions sound familiar, that&#8217;s because they are fundamental to the first two steps in Steve Blank&#8217;s <a href="http://www.amazon.com/gp/product/0976470705/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0976470705&amp;linkCode=as2&amp;tag=leknarf-20" title="">The Four Steps to the Epiphany</a>, namely &#8220;Customer Discovery&#8221; and &#8220;Customer Validation&#8221;. Creating and marketing a blog is a great way to practice the customer development skills necessary for an early startup, without having to worry about the parallel challenge of product development.</p>

<h2>Customer Discovery</h2>

<p><span class='pullquote-right' data-pullquote='Marketing your blog is almost entirely a problem of execution: you don&#8217;t need a clever new strategy, you just need to get out there and hustle.'>
Discovery is a fairly obvious requirement for a new blog. I don&#8217;t believe many folks start a blog without at least intending to find readers. Fortunately, the process of finding readers for a blog is far more straightforward than discovering potential customers for a startup. There&#8217;s already a large market of people who read other blogs, you just need to convince them that yours is at least worth a cursory skim. And there&#8217;s already an established base of communities like <a href="http://news.ycombinator.com">hacker news</a> and <a href="http://reddit.com">reddit</a> that exist primarily for readers to discover, share, and discuss new content. Marketing your blog is almost entirely a problem of execution: you don&#8217;t need a clever new strategy, you just need to get out there and hustle. This is far easier than discovering customers for a new product category.
</span></p>

<p>More importantly, by accepting that building a readership just requires some honest labor, you can avoid a common pitfall. Smart people (particularly developers) enjoy thinking about ways to do their jobs more efficiently. When building a startup, it&#8217;s tempting to spend so much time thinking about ways to reach new customers that you never actually get around to speaking to any. This is obviously absurd in the context of building a blog&#8217;s readership. Working on developing your blog&#8217;s reach is a great way to develop a habit of doing instead of just planning.</p>

<h2>Customer Validation</h2>

<p><span class='pullquote-right' data-pullquote='A blog doesn&#8217;t have to become a revenue stream to be successful, but it is important to identify some possible benefits, consider how feasible they are, and figure out what sort of readers you want.'>
Validation requires a little more thought. For a commercial startup, validation usually revolves around assessing willingness to pay. A blog doesn&#8217;t have to become a revenue stream to be successful, but it is important to identify some possible benefits, consider how feasible they are, and figure out what sort of readers you want. It&#8217;s not necessary for your readers to pay you directly, but it is important to identify some sort of desired action you want to encourage.
</span></p>

<p>In particular, some plausible motivations for blogging are to:</p>

<ul>
<li>Articulate and develop your own thoughts: Thinking is easy; writing is hard. Ideas are tough to nail down. Something that sounds wonderful bouncing around in your head can look outright preposterous once it finds its way to paper. Writing things down and sharing them is a straightforward way to develop intellectual honesty. You can get some benefits from writing even without a readership, but ideally, you&#8217;ll want to find thoughtful readers who are interested in discussing your ideas and challenging your assumptions. If you happen to build up a large pool of readers who never comment or engage with you, then you haven&#8217;t found the right readers and should re-consider your discovery efforts.</li>
<li>Establish some bona fides. Perhaps you&#8217;ve been reading this blog and thought to yourself, &#8220;That chap seems to know what&#8217;s up.&#8221; Validation for this goal can be as simple as collecting points. Unlike the above, silent readers are okay for this goal, provided that they&#8217;re willing to up vote your content on social media sites.</li>
<li>Direct some traffic to another project, such as my <a href="http://getlambda.com">current startup</a>. This is starting to get more difficult, but is still pretty reasonable. Readers of this blog probably like startups, I&#8217;ve got one, so perhaps you&#8217;d like to take a look at mine? This thought process quickly breaks down if there isn&#8217;t a straightforward connection between the blog&#8217;s content and the project in question. A photo-blog of cat cartoons is odd marketing for an enterprise software company, but might work out if <a href="http://octodex.github.com/">done right</a>. The key metric here is simple: you want to review the conversation funnel for your other project and compare traffic from your blog with other traffic sources.</li>
</ul>


<h2>Practice the hard stuff</h2>

<p>Startups are hard. There&#8217;s no way around that. You&#8217;re unlikely to find immediate success regardless, but you can improve your chances by developing relevant skills. Software developers are often tempted to focus on becoming better developers. Product development is certainly relevant to any startup, but the challenge for most early startups is finding customers. Learning the latest web framework won&#8217;t help you validate a business model, but finding readers for a new blog is a great way to learn and practice customer development.</p>
]]></content>
  </entry>
  
</feed>
