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

  <title><![CDATA[Craig Kerstiens]]></title>
  <link href="http://www.craigkerstiens.com/atom.xml" rel="self"/>
  <link href="http://www.craigkerstiens.com/"/>
  <updated>2012-01-28T16:14:45-08:00</updated>
  <id>http://www.craigkerstiens.com/</id>
  <author>
    <name><![CDATA[Craig Kerstiens]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Sphinx Build Pack on Heroku]]></title>
    <link href="http://www.craigkerstiens.com/2012/01/25/sphinx-buildpack/"/>
    <updated>2012-01-25T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2012/01/25/sphinx-buildpack</id>
    <content type="html"><![CDATA[<p>Heroku&#8217;s latest Cedar stack supports running anything. Heroku&#8217;s officially supported languages actually have their buildpacks public via <a href="http://github.com/heroku/">Heroku&#8217;s github</a>, you can view several of them at:</p>

<ul>
<li><a href="https://github.com/heroku/heroku-buildpack-python">Python Build Pack</a></li>
<li><a href="https://github.com/heroku/heroku-buildpack-ruby">Ruby Build Pack</a></li>
<li><a href="https://github.com/heroku/heroku-buildpack-scala">Scala Build Pack</a></li>
</ul>


<p><em>There have even been some created as fun weekend hacks such as the <a href="http://github.com/hone/heroku-buildpack-jsnes">NES Rom Buildpack</a>.</em></p>

<!-- more -->


<p>Recently at Heroku my teams have started exploring new forms of collaborating and documenting. In particular editing a wiki for communication is contrary to our regular workflow. Much of our day is spent in code and git. To edit a wiki within a web browser and using some markup we&#8217;re less familiar with is an overhead we were aiming to reduce. As a result we&#8217;ve tried a few things, the first was simply using a github repo to edit markdown.</p>

<p>Personally I have always been a fan of Sphinx documentation. However, Sphinx has no means to secure a site out of the box. Generating the static site then running it being a Rack app to secure it seemed like a few extra steps that would hinder workflow. As a result I set out to build the Sphinx buildpack which would let you push a Sphinx project to Heroku and automatically run your documentation. The buildpack itself supports two modes, public documentation and a private documentation. To have your documentation secured in private mode you simple need to add your google apps domain as a config var <code>heroku config:add DOMAIN=mydomain.com</code>.</p>

<p><em>If you need more information about setting up OpenID check out my recent post <a href="http://www.craigkerstiens.com/2012/01/23/securing-your-organization/">Securing your organization with OpenID </a></em></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sphinx-quickstart
</span><span class='line'><span class="nv">$ </span>git init .
</span><span class='line'><span class="nv">$ </span>git add .
</span><span class='line'><span class="nv">$ </span>git commit -m initial
</span><span class='line'><span class="nv">$ </span>heroku create -s cedar -b http://github.com/craigkerstiens/heroku-buildpack-sphinx.git
</span><span class='line'><span class="nv">$ </span>git push heroku master
</span><span class='line'><span class="nv">$ </span>heroku open
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Securing your Internal Organization with OpenID]]></title>
    <link href="http://www.craigkerstiens.com/2012/01/23/securing-your-organization/"/>
    <updated>2012-01-23T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2012/01/23/securing-your-organization</id>
    <content type="html"><![CDATA[<p>I&#8217;ve recently been amazed at the number of companies that are still using a VPN or other means to manage their apps/network. Not just large enterprisey companies, but small agile startups. I fully understand that it works, but 95% of these places are also using another key tool for access inside their company&#8230; <em>Google Apps</em>. I fully expect companies to use google apps, its more of the former that surprises me most. For a long time OpenID wasn&#8217;t at a usable point, even today it still isn&#8217;t without its faults. However, it does make for a much cleaner workflow once in place than having your users login to something with they&#8217;re used to using elsewhere.</p>

<p>In our personal lives we use email as our keys to the kingdom. In fact I now almost refuse to sign up for any service that doesn&#8217;t let me use oauth, so why should a work place be much different. So I inquired with a few companies to see if they were fine with securing things like documentation or wiki&#8217;s being google auth, they indeed were. Yet they still seem to have users keep one more username and password for their VPN to be able to login to access internal docs/tools.</p>

<!-- more -->


<p>Most tech centric companies grow their own apps for many things they do within a company. Even the heavier adopters of SaaS still end up building a lot of internal systems. So why not secure them with your email domain just as you commonly would if it were a public service?</p>

<p>The problem comes in that OpenId with google has an initial setup overhead, but after that works unbelievably well.</p>

<h2>The catch</h2>

<p>In some cases you currently have to identify your domain as an OpenId provider. This means that @yourname.com is an OpenId provider. This simply means creating a url route for openid in your base site similar to the below:</p>

<figure class='code'><figcaption><span>http://heroku.com/openid</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;xrds:XRDS</span> <span class="na">xmlns:xrds=</span><span class="s">&quot;xri://$xrds&quot;</span> <span class="na">xmlns=</span><span class="s">&quot;xri://$xrd*($v*2.0)&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;XRD&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Service</span> <span class="na">priority=</span><span class="s">&quot;0&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;Type&gt;</span>http://specs.openid.net/auth/2.0/signon<span class="nt">&lt;/Type&gt;</span>
</span><span class='line'>      <span class="nt">&lt;URI&gt;</span>https://www.google.com/a/craigkerstiens.com/o8/ud?be=o8<span class="nt">&lt;/URI&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/Service&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/XRD&gt;</span>
</span><span class='line'><span class="nt">&lt;/xrds:XRDS&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p><em>This is due to an issue of OpenID discovery which you can read more on at: https://groups.google.com/group/google-federated-login-api/browse_thread/thread/4a7dd2312a47a082/9285cec18a30b9d3?lnk=gst&amp;q=apps+discovery&amp;pli=1#9285cec18a30b9d3. In short, setting up the above can save you a lot of time</em></p>

<h2>Setting up in apps</h2>

<p>Most web frameworks have libraries that make it easy to secure your apps with openid/oauth. In particular Django and Rails both make this pretty easy. To make this even simpler for you below is code to actually secure an internal app for both Django and Rails. You can do similar with Flask or Sinatra as well.</p>

<h3>Rails</h3>

<div><script src='https://gist.github.com/1555489.js?file='></script>
<noscript><pre><code>class ApplicationController
  def admin?
    session[:admin_user] &amp;&amp; (ENV['ADMINS'] || &quot;&quot;).split(',').include?(session[:admin_user])
  end
  helper_method :admin?

  def admin_required
    redirect_to '/auth/admin' unless admin?
  end
end</code></pre></noscript></div>


<p>In case your admin controller isn&#8217;t already generated:</p>

<figure class='code'><figcaption><span>http://heroku.com/openid</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>rails g controller admin/users
</span></code></pre></td></tr></table></div></figure>


<p>Then anything you want to secure:</p>

<figure class='code'><figcaption><span>http://heroku.com/openid</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>module Admin
</span><span class='line'>  class UsersController <span class="nt">&lt; ApplicationController</span>
</span><span class='line'>    <span class="err">before_filter</span> <span class="err">:admin_required</span>
</span><span class='line'>
</span><span class='line'>    <span class="err">def</span> <span class="err">index</span>
</span><span class='line'>      <span class="err">render</span> <span class="na">:text =</span><span class="err">&gt;</span> <span class="s">&#39;Hello from the admin panel!&#39;</span>
</span><span class='line'>    <span class="err">end</span>
</span><span class='line'>  <span class="err">end</span>
</span><span class='line'><span class="err">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Django</h3>

<div><script src='https://gist.github.com/1555612.js?file='></script>
<noscript><pre><code>django-openid-auth==0.3
python-openid==2.2.5
</code></pre></noscript></div>


<p>Finally sync your database:</p>

<figure class='code'><figcaption><span>http://heroku.com/openid</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>python yourapp/manage.py syncdb
</span></code></pre></td></tr></table></div></figure>


<p>Secure any view with the <code>login_required</code> decorator as your typically would with Django.</p>

<h2>Summary</h2>

<p>In short with some very basic app setup you can have an internal workflow thats just as good as what you use in your day to day outside the office.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How Heroku Works - Hiring]]></title>
    <link href="http://www.craigkerstiens.com/2011/12/02/how-heroku-works-hiring/"/>
    <updated>2011-12-02T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/12/02/how-heroku-works-hiring</id>
    <content type="html"><![CDATA[<p>I alluded in earlier posts of <a href="http://www.craigkerstiens.com/2011/11/02/how-heroku-works-teams-tools/">How Heroku Works</a> that we have talented engineers. In fact I would venture to say that there is not a weak link when it comes to our engineers at Heroku. Ensuring we have talented engineers makes it easier for us to find other talented engineers and maintains a level of quality in our product. This means we must be very careful about not diluting our pool of engineering talent, which is where our hiring process becomes especially key. By the time we hire a new employee, we know without a doubt they&#8217;re a fit within our organization.</p>

<p><em>Our goal in hiring is seldom to fill a role, but more commonly to find more talented people share our goal (changing the world for developers).</em></p>

<!--more-->


<p>So what&#8217;s our hiring process look like&#8230;.</p>

<ol>
<li><del>Review Resume/Github Profile</del></li>
<li><del>Initial Screen</del></li>
<li><del>Second Screen</del></li>
<li><del>Starter Project</del></li>
</ol>


<p>While there&#8217;s definitely a process that we follow that&#8217;s not what&#8217;s interesting. We way too often get worried about the steps 1, 2, 3&#8230; Instead you should focus on what&#8217;s important: are they a fit? Can they get shit done? Who cares about how many phone screens someone goes through?! Five phone screens instead of two doesn&#8217;t make them a better fit for your company. The short of it is they go through enough screens that you feel comfortable and you progress them through the process. For us at any point in the process if someone is determined to not be a fit the process ends there. If the process does end the hiring manager will relay this in the appropriate form, though always in writing via email as well.</p>

<p>The hiring manager could debatably be the biggest difference between our process and others. When a candidate applies to a position it goes to the hiring manager (<em>not an HR person</em>). The hiring manager will be your manager once at Heroku it&#8217;s one in the same and this ensures from the start of the process the candidate and the manager mesh well. Yes, having the manager of a group review github profiles and resumes is extra effort, but who better to judge from a quick glance than engineers. In general as a manager you&#8217;re evaluated on the success of those you manage, as such you should be invested heavily in those you hire. In addition to this we find a big difference in the on boarding process and how quickly someone can succeed. We have used many approaches, but the success of someone at Heroku based on having their hiring manager and manager be the same individual is best highlighted below:</p>

<p><img src="http://f.cl.ly/items/462y1J3G0L3q1f3v1o1U/hiring-1.png" alt="Hiring Manager = Manager" /></p>

<p>While every step in the hiring process is valuable starter projects may be the most valuable to ensuring quality. The final step with nearly everyone we hire is to invite them to come hack with us. Instead of parading someone around for a day long interview we get down to business and write some code. It could be something internal to Heroku, it could be an open source project we use, it could be something interesting that the candidate feels would add value to Heroku. Starter Projects vary slightly between each hiring manager.</p>

<p>Several of our managers prefer to lay out several potential interesting projects, talk through them with the candidate, and then let the candidate decide what they&#8217;d like to work on. Sometimes there&#8217;s a pressing need that the candidate can jump right in and add some value. It&#8217;s <strong>always</strong> important that the starter project is achievable, if it&#8217;s too broad of difficult for a 1-2 day period then the manager has failed in the hiring process. Regardless of the project it&#8217;s far more than an exercise on a white board, it&#8217;s actually what life is like at Heroku. We have lunch at the <a href="http://www.flickr.com/photos/teich/4928103311/">same table</a> that we eat at every other day, we interact just as we normally would, and after work there may or may not <a href="http://drunken-samurai-42.tumblr.com/">be drinks</a> just like any other day.</p>

<p><em>As a slight aside, we even conduct starter projects when current Herokai move from one team to another</em></p>

<p>Starter projects usually last anywhere from a day to several days. At the end of a starter project the candidate presents what they did, in a similar fashion to weekly demos that occur at workshop (more on that some other time). In earlier days it was nearly the entire company that would sit in, ask questions and give feedback. Now it&#8217;s a bit harder for all us to fit into one conference room, though there&#8217;s an open invite and anyone that wishes can sit in (often 10-20 Herokai). At the end of the starter project there&#8217;s no question that the candidate fits or doesn&#8217;t, often from both sides. Of course if it&#8217;s a fit we make an offer and welcome them into the family.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How Heroku Works - Maker's Day]]></title>
    <link href="http://www.craigkerstiens.com/2011/11/07/how-heroku-works-maker-day/"/>
    <updated>2011-11-07T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/11/07/how-heroku-works-maker-day</id>
    <content type="html"><![CDATA[<p>In my earlier post on <a href="http://www.craigkerstiens.com/2011/11/02/how-heroku-works-teams-tools/">Teams and Tools at Heroku</a>, I mentioned how we value engineers&#8217; time; their work has enabled us to build a great platform. As a result of what we&#8217;ve built, we&#8217;ve had great growth both of our platform and of our teams internally. With that growth inevitably comes different distractions on engineers&#8217; time. Despite how a manager may plan things, engineering work needs long periods of uninterrupted time. To ensure that no matter what, an engineer has plenty of opportunity to do the work he or she was hired to do, Heroku has Maker&#8217;s Day.</p>

<!--more-->


<p><em>Maker&#8217;s Day ensures that engineers get a full day of uninterrupted time to focus on making things.</em></p>

<p><img src="http://www.craigkerstiens.com/images/makerday.png" alt="Maker's Day" /></p>

<p>The more consistent interruptions are throughout an engineer&#8217;s day, the more time will be lost due to context switching in addition to the time spent on those other activities. These interruptions may include a quick question from a manager, a question on a code problem someone else is working through, or an email or IM from a coworker. Regardless of the type of interruption, it causes an engineer to lose focus. According to <a href="http://www.amazon.com/Peopleware-Productive-Projects-Teams-Second/dp/0932633439">Peopleware: Productive Projects and Teams</a>, in a study regarding productivity among engineers, the top performers when surveyed said they were interrupted regularly 38% of the time versus the bottom performers, who were interrupted 76%. Context switching should be counted as fully wasted time for an engineer, and all too often as the number of meetings increases, the time involved with context switching is increased similarly to the following:</p>

<p><img src="http://www.craigkerstiens.com/images/contextswitch.png" alt="Cost of context switching" /></p>

<p>For more on how interruptions or context switching decreases productivity, Jeff Atwood has a great post about <a href="http://www.codinghorror.com/blog/2006/09/the-multi-tasking-myth.html">The Multi-Tasking Myth</a>, which demonstrates &#8230;</p>

<p>Most people understand that context switching is bad, but another team may still have valid demands on your time. Pushing back against another team or manager isn&#8217;t always feasible; after all, we do work together, and each team at times may need something from another team. This is where Maker&#8217;s Day starts to come in. Every Thursday at Heroku is Maker&#8217;s Day.</p>

<p><strong>Maker&#8217;s day is meant for making shit. Meetings don&#8217;t happen on Maker&#8217;s Day</strong>. If someone asks if that time on your calendar works for a meeting, the simple response is no&#8211;it&#8217;s Maker&#8217;s Day. Because Maker&#8217;s Day has been ingrained into our culture, engineers have no problem giving that response when there&#8217;s a request on their time on Maker&#8217;s Day. If someone in marketing, sales, or another non-engineering role wants to book meetings, they’re welcome to do so, but they&#8217;re going to be without engineers. However, even for non-engineers, Maker&#8217;s Day is equally invaluable; uninterrupted hours of focus at a time are amazing for productivity in any role.</p>

<p>Maker&#8217;s Day varies in how it is executed from person to person. Often the office is slightly less busy due to some engineers working from home or coffee shops to maximize their productivity. To an outsider, the office may appear business as usual: engineers sit at their desks, working. At lunch, everyone is sitting around the lunch table eating together. To the unobservant eye it may appear to be just any other day, but the engineers notice the difference. There will be significantly less interruptions by someone walking over to your desk, you won&#8217;t be pulled into meetings that distract you from features, and you know it&#8217;s an opportunity to accomplish a bulk of work laid out from your weekly planning meeting.</p>

<p>As Heroku has grown, meetings have increased, and the value of Maker Day&#8217;s has increased exponentially.</p>

<p>Whether you&#8217;re in the early stages of bootstrapping a company or at a large company of thousands of engineers, one of the best practices anyone can put into place is dedicated quality time for engineers to produce code. Maker&#8217;s Day is a fantastic way to ensure this happens on a weekly basis.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[More Advanced Dependencies]]></title>
    <link href="http://www.craigkerstiens.com/2011/11/03/moreadvanceddependencies/"/>
    <updated>2011-11-03T00:00:00-07:00</updated>
    <id>http://www.craigkerstiens.com/2011/11/03/moreadvanceddependencies</id>
    <content type="html"><![CDATA[<p>So we walked through setting up your <a href="http://www.craigkerstiens.com/2011/11/01/installingpythonpackages/">virtualenv and installing some packages</a>. The basic workflow for installing packages will work 95% of the time, however part of the time you will need a little more. Below are several cases that may require extra effort. Its likely worthwhile to skim these and only reference them when needed as they likely wont be part of your everyday workflow (with the exception of using mirrors).</p>

<p>Most packages you install should be on pip and an actual released version of a package. There are times however when you may need to test out a package that is still being worked on. For these cases there&#8217;s what developers commonly do and what you should do.</p>

<!--more-->


<p>If you must install a package from git then you might use something similar to the following:</p>

<figure class='code'><figcaption><span>requirements.txt</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>git+https://github.com/kennethreitz/requests.git#egg<span class="o">=</span>requests
</span></code></pre></td></tr></table></div></figure>


<p>Even more ideal is specifying the version:</p>

<figure class='code'><figcaption><span>requirements.txt</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>git+https://github.com/kennethreitz/requests.git<span class="o">==</span>0.6.0#egg<span class="o">=</span>requests
</span></code></pre></td></tr></table></div></figure>


<p><em>The above should never be done when deploying to production, it reduces predictable behavior and requires that github is available for you to deploy. You should never be dependent on more than PyPi and your own system to deploy.</em></p>

<p>Instead when you deploy to production you should point to an internal link. This looks something similar to:</p>

<figure class='code'><figcaption><span>requirements.txt</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>--find-links http://path/to/package/
</span></code></pre></td></tr></table></div></figure>


<p>The other item thats not currently (though will be soon) a default behavior is mirrors. For those not familiar, a mirror is essentially a copy of a site (in this case <a href="http://pypi.python.org/">PyPi</a>). At some point in the future the site may be down preventing you from installing packages or deploying code. If this is the case you&#8217;re able to use a flag to use these mirrors. If you simple add the flag below it will automatically use the mirrors, allowing you to continue:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>pip --use-mirrors install Django
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How Heroku Works - Teams and Tools]]></title>
    <link href="http://www.craigkerstiens.com/2011/11/02/how-heroku-works-teams-tools/"/>
    <updated>2011-11-02T00:00:00-07:00</updated>
    <id>http://www.craigkerstiens.com/2011/11/02/how-heroku-works-teams-tools</id>
    <content type="html"><![CDATA[<p>Heroku is a largely agile company, we work in primarily small teams that talk via api and data contracts. Its also a company comprised primarily of engineers, even product managers often write code. Heroku as a platform drives many of the features not from top down, but from bottom up based on engineers desires or skunkworks projects. There&#8217;s many valuable insights into how Heroku runs efficiently for engineering.</p>

<p>I&#8217;ll be diving into many various practices that enable Heroku to put quality engineering above all else, but first let me highlight the team structure and tools that enable this.</p>

<!--more-->


<p>Heroku is comprised of many small teams internally, each team operates much like an individual entity. The team chooses its own tools and best method for communication, though as a whole some form of Scrum is run throughout teams.</p>

<p>For most teams this involves a weekly planning meeting earlier in the week. In such a meeting teams may conduct a retrospective, opportunities to improve the process the coming week, and of course plan tasks for the coming week. Its <b>very</b> important to note that planning tasks for the week doesn&#8217;t necessarily involve planning the deadline for them, but rather simply laying out what people are working on (more on this in a future post). Each team will record and track this in a tool of their own choosing. Several use <a href="http://www.pivotaltracker.com">pivotal tracker</a>, one uses <a href="http://www.scrumy.com">scrumy</a>, some use email to distribute and track against personal to do lists. The method for tracking issues is again entirely up to the individual team. A one person team may choose to use a simple to do list, larger teams commonly use <a href="http://www.github.com">github</a> issues and pull requests. Given the team is the one responsible for their own productivity the team is the one to choose what tools they use.</p>

<p>Meeting loads vary from person to person depending on what is the demands are on their time, though everyone at Heroku participates in some form of standup. Most teams do these daily as quick status stand-ups of what was worked on the day before and whats to be worked on the next day. In addition to the planning meeting and stand-ups, there is often collaborative engineering, and company wide gatherings.</p>

<p>Collaborative engineering once again varies depending on which engineers are working together. Engineers may get in front of a white board or in front of machines and simple collaborate. For engineers together in the office this is often the most productive way. These practices work the same for remote employees, though slightly modified for the high touch interaction. For remote employees this often works as pair programming via Skype. Skype is indispensable for allowing remote workers to feel far less remote. Skype alongside <a href="http://typewith.me/">typewith.me</a> and you have an unbelievable easy to collaborate not just with 1 other, but with multiple parties to work through a document on a given topic. For smaller activities of communication asynchronous is key. This ranges from <a href="http://campfirenow.com/">campfire</a> most commonly during common working hours when someone is likely to be at a machine, to email when the return on a request may take slightly longer.</p>

<p>Finally there is the all common company wide meeting, which occurs weekly. The structure of this varies from status updates to broader ongoings. Its often the perfect time for engineers to hear about what sales is doing or get updates on teams you don&#8217;t commonly interact with. Along with common status updates there will be broader company updates.</p>

<p>Consistently across all teams you&#8217;ll find these principles which allow us to ensure the quality of engineering as we continue to grow:</p>

<ul>
<li>Small teams that talk across defined API&#8217;s and data contracts</li>
<li>Teams using the tool that they believe is best for the job</li>
<li>Frequent asynchronous communication</li>
<li>Collaboration (including for remote employees)</li>
</ul>


<p>The key in Heroku running efficiently is primarily allowing each team to run as it chooses. Heroku works because we have talented engineers, the best thing we can do for those engineers is allow them to work productively. Often only they know the best way to accomplish this, so who better to let them accomplish it than themselves.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Installing Python Packages]]></title>
    <link href="http://www.craigkerstiens.com/2011/11/01/installingpythonpackages/"/>
    <updated>2011-11-01T00:00:00-07:00</updated>
    <id>http://www.craigkerstiens.com/2011/11/01/installingpythonpackages</id>
    <content type="html"><![CDATA[<p>Now that you have you system and project environment all setup you probably want to start developing. But you likely don&#8217;t want to start writing an entire project fully from scratch, as you dive in you&#8217;ll quickly realize theres many tools helping you build projects and sites faster. For example making a request to a website there&#8217;s <a href="http://docs.python-requests.org/en/latest/index.html">Requests</a>, for handling processing images there&#8217;s <a href="http://www.pythonware.com/products/pil/">Python Imaging   Library</a>, or for a full framework to help you in building a site there&#8217;s <a href="http://www.djangoproject.com">Django</a>. With all of these there&#8217;s one simple and common way to install them. But first a little more on how it all works.</p>

<!--more-->


<p>All major Python packages are hosted on <a href="http://pypi.python.org/">PyPi</a> (Pronounced Pi-P or Cheeseshop). When you use a common python installer it will:</p>

<ol>
<li>Search for the package you specify</li>
<li>If you specify a version will use it, otherwise will use the latest</li>
<li>Will download the source for that package</li>
<li>Install it into your Python environment</li>
</ol>


<p>Now for actually installing&#8230; Lets get started with installing the three packages below. At this point you should at least have a fresh Python environment, however you don&#8217;t have an immediate way to install packages. The defacto Python package installer is <a href="http://pip-installer.org">pip</a>.</p>

<p>Earlier we setup virtualenv to help isolate our python packages we were working with. First lets go ahead and create a folder for our project then setup a new environment for the project we&#8217;ll work on:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mkdir myapp
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>myapp
</span><span class='line'><span class="nv">$ </span>virtualenv --no-site-packages venv
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>If we list the contents of the directory you&#8217;ll now see a folder venv. Within this folder you&#8217;ll find all the parts of the environment that virtualenv just created:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>ls
</span><span class='line'>venv
</span><span class='line'><span class="nv">$ </span>ls venv
</span><span class='line'>bin   include lib
</span></code></pre></td></tr></table></div></figure>


<p>Now you&#8217;ve got a sandboxed environment that exists but you haven&#8217;t loaded it. You can now activate and deactivate this any time you like. Once you do this it customizes your path to use the packages you&#8217;ve installed for this environment. To load your environment when in the myapp directory:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="nb">source </span>venv/bin/activate
</span></code></pre></td></tr></table></div></figure>


<p>To deactivate this simple:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>deactivate
</span></code></pre></td></tr></table></div></figure>


<p>Now that we&#8217;ve got your environment loaded installing your packages should be pretty simple. Ensure that you have your virtualenv loaded and then run:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>pip install requests
</span><span class='line'><span class="nv">$ </span>pip install PIL
</span><span class='line'><span class="nv">$ </span>pip install Django
</span></code></pre></td></tr></table></div></figure>


<p>Now that you&#8217;ve installed your packages you want to be able to share this with others to make it easy to get setup. You could provide a list of everything your application needs to run manually, or because its Python you can expect it to make it easy for you. Pip has a wonderful command freeze that will show all of your packages and their versions that are installed. Simply run:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>pip freeze
</span></code></pre></td></tr></table></div></figure>


<p>However, this only outputs the information. Along with this pip has a canonical form for listing requirements and installing them from a file. The filename is commonly a requirements.txt. To create this we simply pipe the results of pip freeze to this file.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>pip freeze &gt; requirements.txt
</span></code></pre></td></tr></table></div></figure>


<p>Next we&#8217;ll talk about a few more advanced items in dependency management, then finally we&#8217;ll get started on building an application.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting Setup with Python]]></title>
    <link href="http://www.craigkerstiens.com/2011/10/27/gettingsetupwithpython/"/>
    <updated>2011-10-27T00:00:00-07:00</updated>
    <id>http://www.craigkerstiens.com/2011/10/27/gettingsetupwithpython</id>
    <content type="html"><![CDATA[<p>This is the first of a multipart series to getting started with Python. Throughout this guide we&#8217;ll walk you through a full setup. For starters if you&#8217;re a mac or linux user you already have <a href="http://python.org">Python</a> on your system. You should be able to confirm you have python my opening up a terminal window and running:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>python --version
</span><span class='line'>Python 2.7.2
</span></code></pre></td></tr></table></div></figure>


<!--more-->


<p>As long as you see a Python version 2.5.x-2.7.x you should be fine to continue. From here we&#8217;re going to work through setting up your Python project environment. For this we&#8217;re going to use <a href="http://virtualenv.org">virtualenv</a>. For those of you not familiar <a href="http://virtualenv.org">virtualenv</a> is a self-contained python environment. It holds its own copy of python and any libraries you install. This allows you to work on multiple projects with different versions of libraries.</p>

<p>While we&#8217;re installing virtualenv we&#8217;re also going to go ahead and setup PostgreSQL as we&#8217;ll be using it later. If you&#8217;re on a mac you&#8217;ll first need to setup homebrew. Homebrew is used for installing various system packages. If you&#8217;re on linux, in particular Ubuntu you can skip down to the steps for setting up your environment.</p>

<p>First for Mac users lets setup homebrew which will allow us to install various system packages:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>/usr/bin/ruby -e <span class="s2">&quot;$(curl -fsSL https://raw.github.com/gist/323731)&quot;</span>
</span></code></pre></td></tr></table></div></figure>




<h2>OSX with Brew:</h2>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl -O http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg | sh setuptools-0.6c11-py2.7.egg
</span><span class='line'><span class="nv">$ </span>easy_install virtualenv
</span><span class='line'><span class="nv">$ </span>brew install postgresql
</span></code></pre></td></tr></table></div></figure>




<h2>Ubuntu:</h2>


<p>Now for setting up your project:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sudo apt-get install virtualenv
</span><span class='line'><span class="nv">$ </span>sudo apt-get install postgresql
</span></code></pre></td></tr></table></div></figure>


<p>Now you have Python, virtualenv, and postgresql all installed. We can now focus on setting up the initial start to a project.</p>

<p>In the next part we can start with installing some Python packages.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Environment Structure for Django Apps]]></title>
    <link href="http://www.craigkerstiens.com/2011/05/16/environment-structure-django-apps/"/>
    <updated>2011-05-16T00:00:00-07:00</updated>
    <id>http://www.craigkerstiens.com/2011/05/16/environment-structure-django-apps</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been writing applications off and on for nearly 4 years now, since before Django 1.0 was even released. I must say the framework could not be better described than by its own tagline &#8220;The Web framework for perfectionists with deadlines&#8221;. Among the things I love about it are:</p>

<ul>
    <li>Amazing documentation, there&#8217;s not 30 different blog posts with different ways to do things, either read the django project documentation or the app documentation</li>
    <li>They don&#8217;t consistently break backwards compatibility. While at times they do this, it is not the norm or standard, which isn&#8217;t the case for some other unnamed frameworks</li>
    <li>DRY, Don&#8217;t Repeat Yourself. If there&#8217;s an app that exists people don&#8217;t have a burning need to recreate the same functionality, resulting in lower number but higher quality pluggable apps.</li>
</ul>


<!--more-->


<p>However, after using the framework for nearly 4 years I&#8217;m just now discovering my preferred way of managing environments. I know there&#8217;s still a bit of back and forth on development environment/IDE, but as far as configuring actual project environment I&#8217;ve become very comfortable with what I&#8217;ve now been using for many months. It also allows for someone else bootstrapping their environment incredible quickly as well. Below is a quick cookbook of how to do this on OSX and Ubuntu.</p>

<h2>OSX with Macports:</h2>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sudo port install python27
</span><span class='line'><span class="nv">$ </span>sudo port install py27-virtualenv
</span><span class='line'><span class="nv">$ </span>sudo port install postgresql90
</span></code></pre></td></tr></table></div></figure>


<p>Now for setting up your project:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mkdir example
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>example
</span><span class='line'><span class="nv">$ </span>virtualenv-2.7 --no-site-packages .
</span><span class='line'><span class="nv">$ </span><span class="nb">source </span>bin/activate
</span></code></pre></td></tr></table></div></figure>




<h2>OSX with Brew:</h2>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sudo brew install python
</span><span class='line'><span class="nv">$ </span>sudo brew install virtualenv
</span><span class='line'><span class="nv">$ </span>sudo brew install postgresql
</span></code></pre></td></tr></table></div></figure>


<p>Now for setting up your project:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mkdir example
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>example
</span><span class='line'><span class="nv">$ </span>virtualenv --no-site-packages .
</span><span class='line'><span class="nv">$ </span><span class="nb">source </span>bin/activate
</span></code></pre></td></tr></table></div></figure>




<h2>Ubuntu:</h2>


<p>Now for setting up your project:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>sudo aptitude install python
</span><span class='line'>sudo aptitude install virtualenv
</span><span class='line'>sudo aptitude install postgresql
</span></code></pre></td></tr></table></div></figure>


<p>Now for setting up your project:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mkdir example
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>example
</span><span class='line'><span class="nv">$ </span>virtualenv --no-site-packages .
</span><span class='line'><span class="nv">$ </span><span class="nb">source </span>bin/activate
</span></code></pre></td></tr></table></div></figure>


<p>For those of you not familiar virtualenv is a self-contained python environment. It holds its own copy of python and any libraries you install. Now that you&#8217;ve setup your virtualenv we can go through the process of installing django and setting up your repository. This is the same across all of the above platforms:</p>

<p>Add to a .gitignore file:</p>

<figure class='code'><figcaption><span>.gitignore </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>bin
</span><span class='line'>build
</span><span class='line'>include
</span><span class='line'>lib
</span><span class='line'>.Python
</span><span class='line'>*.pyc
</span></code></pre></td></tr></table></div></figure>


<p>Add to a requirements.txt file:</p>

<figure class='code'><figcaption><span>requirements.txt</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">Django</span><span class="o">==</span>1.3.1
</span><span class='line'><span class="nv">psycopg2</span><span class="o">==</span>2.4.1
</span></code></pre></td></tr></table></div></figure>


<p>Then run:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>bin/pip install -r requirements.txt
</span></code></pre></td></tr></table></div></figure>


<p>This should fully installed any of your required apps and makes it easy for others to do the same to begin contributing to a larger app. Finally if you like you can create your git repo from this an make your first commit:</p>

<pre><code>$ git init
$ git add .
$ git commit -m 'my first django virtualenv'
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Attribution 101]]></title>
    <link href="http://www.craigkerstiens.com/2011/03/18/attribution-101/"/>
    <updated>2011-03-18T00:00:00-07:00</updated>
    <id>http://www.craigkerstiens.com/2011/03/18/attribution-101</id>
    <content type="html"><![CDATA[<p>Continuing with the recent posts on metrics and marketing. I want to give a quick primer on attribution. To any marketing or analytics people out there, simply skip this it would aim to be a primer recap at best for you.</p>

<p>The very general meaning behind attribution is to give credit. When it comes to web products this can be giving credit for lots of things:</p>

<ul>
    <li>A visit to your site</li>
    <li>A purchase to your site</li>
    <li>Other events, such as sign up, referring friends, etc.</li>
</ul>


<!--more-->


<p>Its really wonderful when there&#8217;s a direct mapping in correlation. Take for example the case where:</p>

<ol>
    <li>User sees your ad on facebook</li>
    <li>User clicks on ad</li>
    <li>User signs up for an account</li>
    <li>User pays you money</li>
</ol>


<p>In this case it&#8217;s clear that its worthwhile to advertise on facebook. The hard part becomes when there&#8217;s a non-linear path in some form (which is almost always the case). Now take the case:</p>

<ol>
    <li>User sees your ad on facebook</li>
    <li>User clicks on ad, then leaves</li>
    <li>User comes back a day later directly, and spends 10 minutes on the site reading</li>
    <li>User comes back a day later after searching via google, and creates an account</li>
    <li>User sees a re targeting ad 1 month later and visits</li>
    <li>User pays for account</li>
</ol>


<p>In a perfect world you have case 1 and can give the full credit or attribution of the purchase to your facebook ad. However, in a real world you have case 2 and it becomes more complicated. Perhaps its something like this though:</p>

<ul>
    <li>Account creation - 100% to facebook ad</li>
    <li>Paying for account - 50% to facebook ad, 50% to retargetting?</li>
</ul>


<p>This is where there is not an exact science to attribution, as it could be justified to give 100% of the credit for paying for an account to the re targeting. So if this has you pondering on attribution here&#8217;s the downer part&#8230;. The tools that allow you to attribute a goal or action to multiple sources:</p>

<ul>
    <li>Omniture</li>
    <li>Web Trends</li>
</ul>


<p>Most other tools are the last place the user ever came from, some occasionally are the first place a user came from, but without pony-ing up for a high end product your options on actually getting data don&#8217;t really exist.</p>

<p>&nbsp;</p>

<p><em>Disclaimer: I have little to no formal training in stats or analytics, have simply learned through launching products so take this for what its worth, someone that has been there and done it.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Startup/Bootstrapped Marketing Recap]]></title>
    <link href="http://www.craigkerstiens.com/2011/03/07/startupbootstrapped-marketing-recap/"/>
    <updated>2011-03-07T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/03/07/startupbootstrapped-marketing-recap</id>
    <content type="html"><![CDATA[<p>If you have an hour to spare its well worth it to look back and look back at my series on startup/bootstrapped marketing. But if you&#8217;re short on time and want the high level summary here&#8217;s the quick recap:</p>

<p><a href="http://www.craigkerstiens.com/2011/02/14/bootstrappedstartup-marketing-part-1/">Part 1 - Focus on SEO</a></p>

<ul>
    <li>Ensure you have a sitemap; <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=183668">http://www.google.com/support/webmasters/bin/answer.py?answer=183668</a>
<ul>
    <li>Submit it to google</li>
    <li>Submit it to yahoo</li>
    <li>Submit it to bing</li>
</ul>
<!--more-->
</li>
    <li>Use meta tags and ensure they&#8217;re unique</li>
    <li>Use unique titles and h1/h2 tags in your pages</li>
</ul>


<p><a href="http://www.craigkerstiens.com/2011/02/16/bootstrappedstartup-marketing-part-2/">Part 2 - Find Influencers</a></p>

<ul>
    <li>Find the key bloggers</li>
    <li>Be brief and to the point</li>
    <li>Provide value to them, often by an exclusive</li>
</ul>


<p><a href="http://www.craigkerstiens.com/2011/02/18/bootstrappedstartup-marketing-part-3/">Part 3 - Traditional Advertising</a></p>

<ul>
    <li>Contextual - AdSense, target for competitors</li>
    <li>Demographic - Cast wide net for demographic info, narrow on interests/hobbies</li>
    <li>Vertical - Ensure to filter out noise and focus on brand</li>
</ul>


<p><a href="http://www.craigkerstiens.com/2011/02/22/bootstrappedstartup-marketing-part-4/">Part 4 - Retargetting</a></p>

<ul>
    <li>No matter what do this step, it make&#8217;s you appear to have a larger presence than you do to users</li>
    <li>Most recommended service: <a href="http://www.adroll.com">AdRoll</a></li>
</ul>


<p>Again this is just a very high level recap. If any of these items strikes a chord with you please dive deeper. The amount of time it takes to learn about how to market and target your users is a fraction of the return you get from doing it effectively. Finally, if anyone out there needs direction on how to target and measure more effectively always feel free to reach out to me, i&#8217;m easily found on <a href="http://www.twitter.com/craigkerstiens">twitter</a> among many other services.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Reading Metrics to Evaluate Marketing]]></title>
    <link href="http://www.craigkerstiens.com/2011/03/02/understanding-metrics/"/>
    <updated>2011-03-02T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/03/02/understanding-metrics</id>
    <content type="html"><![CDATA[<p>A short while backed I talked about <a href="http://www.craigekerstiens.com/2011/02/03/tactical-steps-for-startup-metrics/">tactically measuring metrics</a> for your site/company. Recently I talked a bit about <a href="http://www.craigekerstiens.com/2011/02/14/bootstrappedstartup-marketing-part-1/">methods of marketing</a>. A large key to getting the most out of your time and money is to properly report against the intersection of these two items. First I&#8217;m going to make the assumption you&#8217;ve read those posts, if you haven&#8217;t go back and do that. Next this is heavily on the assumption that you&#8217;re using Google Analytics as your primary tool for measuring metrics and have setup goals appropriately.</p>

<!--more-->


<p>Within measuring you&#8217;re metrics you&#8217;ll have abandonment at each level. You may have some visitors that never register, and many that register but never purchase anything. It&#8217;s wonderful if you&#8217;re able to immediately have full insight of the best means of marketing to drive revenue, however realistically it occurs in a more phased approach. The first step is to drive visitors and almost immediate second is to convert those users as registered.</p>

<p><em><strong>Acquisition -&gt; Activation</strong></em></p>

<p>This at a high level makes sense, as does at a high level knowing you should be targeting users in your target market. However, even slightly drilling into this you realize that all traffic is not equal. It&#8217;s often known that CPC and CPA advertising does not convert well for users, though can drive traffic. This may not always be the case. For Registry Stop to make this analysis easier we&#8217;ve created a custom report in google.</p>

<p>To create your own custom report simply click Manage Custom Reports under the Custom Reports area then &#8220;Create new custom report&#8221;. The custom report ability in google gives you much more ability to drill into the data that you already have at a higher level. To track effectiveness of converting visitors to registered users and which sources are effective at this you&#8217;d create something that looks like:</p>

<p><a href="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz024.png"><img class="alignnone size-medium wp-image-366" title="Creating Custom Report" src="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz024-300x205.png" alt="Creating Custom Report" width="300" height="205" /></a></p>

<p>Here while very simple we&#8217;re able to see some very key information quickly. Here&#8217;s an example of how it would appear over a few day period:</p>

<p><a href="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz0231.png"><img class="alignnone size-medium wp-image-368" title="Google Analytics - Goals Custom Report" src="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz0231-300x205.png" alt="Google Analytics - Goals Custom Report" width="300" height="205" /></a></p>

<p>&nbsp;</p>

<p>As you progress in your stage of bootstrapping or growing your startup you&#8217;ll want to grow custom reports that allow you to report against as many <a href="http://www.craigekerstiens.com/2011/02/03/tactical-steps-for-startup-metrics/">metrics</a> as possible. The first and last part of my day is spent pouring over these reports. Having this data readily available allows us to drive our business based on data. Perhaps the hardest part of all of this is admitting when the data is counter to what we expect and following its advice.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setting up Goals and Funnels - Google Analytics]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/28/setting-goals-funnels/"/>
    <updated>2011-02-28T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/28/setting-goals-funnels</id>
    <content type="html"><![CDATA[<p>I had a recent request on how to setup a funnel in Google Analytics. If you&#8217;ve missed by first post on some tips for <a href="http://www.craigekerstiens.com/2011/02/02/events-with-google-analytics-and-tricking-pageviews/">Google Analytics</a> first check that out. With most websites today there is some portion of the site that is event and not page based, meaning you have some workflow on the page based on Javascript. If this is the case you&#8217;ll want to <a href="http://www.craigekerstiens.com/2011/02/02/events-with-google-analytics-and-tricking-pageviews/">fake a page view</a> instead of an event in order to entirely use it in funnels and goals.</p>

<p>A personal recommendation is actually to use both, goals and funnels. The key a funnel is that you need to have successive steps that occur in some order. With regards to metrics tracking this is absolutely needed, but typically you may have 1-2 total funnels with many steps in your site versus goals where you could have 10-15 single goals. For <a href="http://www.registrystop.com">Registry Stop</a> we&#8217;ve structured our site so that our earlier stage goals become the same as steps in later stage funnels. For us in almost all cases the first part of the funnel is the visit, the second is registering for an account. We do have independent goals for visits and registrations as well, but we do not have funnels on those goals.</p>

<!--more-->


<p>A key to getting the most use out of your funnels is to know that there is a <strong>workflow to follow</strong> to getting to that end goal. To highlight this slightly more visually let me walk through an example:</p>

<ol>
    <li><em><strong>User visits your site.</strong></em></li>
Here you&#8217;ll want to create a goal. Likely this is tracking a page view of the homepage.
    <li><em><strong>User registers for an account.</strong></em></li>
Here again, you&#8217;ll create a goal and nothing more. If there is a confirmation page that will be your goal, if there is not, then you&#8217;ll want to <a href="http://www.craigekerstiens.com/2011/02/02/events-with-google-analytics-and-tricking-pageviews/">fake a page view</a> in order to track that goal.
    <li><em><strong>User adds a product</strong></em></li>
This is the first place you want to create both a goal and a funnel.</ol>


<p>With regards to the goal, it should be pretty simple, tracking some page view. For the funnel though you will likely have 4 parts.</p>

<p>The parts of your funnel will be:</p>

<ol>
    <li>User visits your site.</li>
    <li>User registers for an account.</li>
    <li>User begins process of adding a product</li>
    <li>User completes product add</li>
</ol>


<p>For Registry Stop we have a similar funnel for users which includes:</p>

<ol>
    <li>Registering for an account</li>
    <li>Visiting the sync page</li>
    <li>Adding a synced registry</li>
</ol>


<p>Now as for actually setting up a goal or funnel. This is slightly unintuitive as it&#8217;s not from inside a specific site on Google Analytics. At the home level of google analytics you&#8217;ll have all of your sites setup. For each site to the right you&#8217;ll have actions, click the Edit to go to the goal area.</p>

<p><a href="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz011.png"><img class="alignnone size-full wp-image-348" title="Google Analytics Settings - Goals and Funnels" src="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz011.png" alt="Google Analytics Settings - Goals and Funnels" width="125" height="64" /></a></p>

<p>Once here it becomes a bit more intuitive. You can begin by simply adding a goal. Your goal types should seem mostly intuitive, as mentioned in an earlier post you cannot use an Event in a goal. For this reason you can fake a pageview as if it actually occurred and then create your goal against that non-existent page view. If you want a few more details of how to do this check out the previous post . So for an example, we have a goal on <a href="http://www.registrystop.com">Registry Stop</a> that detects when a page view occurs as a result of a registry being synced. Because this workflow is heavily javascript and flow based we fake the page view and track it as if the page was actually visited. The goal itself looks like:</p>

<p><a href="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz012.png"><img class="alignnone size-medium wp-image-350" title="Google Analytics Example Goal" src="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz012.png" alt="Google Analytics Example Goal" width="300" height="75" /></a></p>

<p>For setting up your funnel as we mentioned above its generally a set of page views. A very key item is the check box next to the first item in your funnel. If you check this is means any other steps in the funnel are not counted unless you the first step is completed. If you have a very structured 1, 2, 3 workflow this makes sense. However, if there are various ways for the goal to complete then be very careful about selecting this.</p>

<p>For this same goal above we have a corresponding funnel to track in detail how our conversion flows. The funnel itself looks like this once setup:</p>

<p><a href="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz022.png"><img class="alignnone size-medium wp-image-344" title="Google Analytics Funnel Setup" src="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz022.png" alt="Google Analytics Funnel Setup" width="300" height="127" /></a></p>

<p>This results in a funnel report that looks like:</p>

<p><a href="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz011.png"><img class="alignnone size-medium wp-image-342" title="Synced Registry Funnel" src="http://www.craigkerstiens.com/images/Snapz-Pro-XScreenSnapz011.png" alt="Synced Registry Funnel" width="300" height="250" /></a></p>

<p>&nbsp;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JQuery and Django Autocomplete]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/25/jquery-django-autocomplete/"/>
    <updated>2011-02-25T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/25/jquery-django-autocomplete</id>
    <content type="html"><![CDATA[<p>In a couple of various places I&#8217;ve seen light requests of how to put autocomplete in for a Django web application. Here&#8217;s a really light weight version with a view and autocomplete functionality using:</p>

<ul>
    <li><a href="http://www.djangoproject.com">Django</a></li>
    <li><a href="http://www.jquery.com">JQuery</a></li>
    <li><a href="http://www.jqueryui.com">JQuery UI</a></li>
</ul>


<p>For a view to search within your django model it would look something like:</p>

<figure class='code'><figcaption><span>models.py </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">simplejson</span>
</span><span class='line'><span class="k">def</span> <span class="nf">autocompleteModel</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
</span><span class='line'>    <span class="n">search_qs</span> <span class="o">=</span> <span class="n">ModelName</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name__startswith</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">REQUEST</span><span class="p">[</span><span class="s">&#39;search&#39;</span><span class="p">])</span>
</span><span class='line'>    <span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
</span><span class='line'>    <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">search_qs</span><span class="p">:</span>
</span><span class='line'>        <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span><span class='line'>    <span class="n">resp</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">REQUEST</span><span class="p">[</span><span class="s">&#39;callback&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="s">&#39;(&#39;</span> <span class="o">+</span> <span class="n">simplejson</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">+</span> <span class="s">&#39;);&#39;</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">resp</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s">&#39;application/json&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>For the jQuery autocomplete and call:</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Evaluating Paying for a Blog Post]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/25/evaluating-paying-blog-post/"/>
    <updated>2011-02-25T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/25/evaluating-paying-blog-post</id>
    <content type="html"><![CDATA[<p>At a recent meetup I talked a bit about how I&#8217;d been using blog posts on other blogs, both free and paid for as a primary user acquisition tool. I was very shocked, when several were surprised and curious on the method for this. In tech startups coverage is common, but its usually just that press, not paid for press. I must say I love how the tech community doesn&#8217;t force people to pay to get the word out, but it is very much a competition; that might be just as much work as paying.</p>

<p>In contrast the wedding industry is very much a pay to play space. If you give some money you can get some attention.</p>

<!--more-->


<p>First things first, contact the blog you&#8217;re interested in being written up in and ask for their media kit. If they welcome sponsored posts, then it is likely called out in their media kit. However, this isn&#8217;t always the case, if you&#8217;ve noticed posts on their blog that have been sponsored posts but pricing isn&#8217;t called out in their blog then email them explicitly and inquire.</p>

<p>Once you&#8217;ve got their media kit its time to do some digging. My process has first been to validate their numbers. Most blogs include their unique visitors and page views in their media kits. I immediately jump over to compete to check if their numbers are even in the ballpark. To clarify in the ballpark can be somewhere around 1.5x of compete. There are a surprising number of blogs that may be 20x off in the numbers they are stating. This could mean you&#8217;re outright lying on your stats, or that you&#8217;re not running a solid enough business that you know how to effectively track your numbers. It could be, because your blog exists on 5 different domains, while compete I&#8217;m checking only the primary. Regardless, if you&#8217;re numbers aren&#8217;t close, it often means you&#8217;re not as together as we&#8217;d like.</p>

<p>If they pass the first smoke screen of the stats being in the ballpark, then we can move on to evaluating sponsoring a post. Traffic&#8217;s a big factor, unique visitors are important as well as page views. Next we&#8217;ll typically look for how active your users are. Do users actively engage in comments, where there are active commenters there&#8217;s usually opportunity to get a bit more out of your post.</p>

<p>Next would be, how frequent are posts. Are you looking at 1-2 posts that go up per day, or 10. If 10, it simply means your content will be pushed to the bottom of the page pretty quickly, in this case if page views are exceptionally high, it may mean that users only view 1-2 posts per day and miss the others. I&#8217;ve historically done this on a subjective basis, but it could easily be a number that is calculated and factored in.</p>

<p>So you start with this basic methodology for one blog, then do it for a few more. Its pretty simple to compare 3-4 blogs on their potential value, but when you really start expanding this you could be looking at 100 blogs. If that&#8217;s the case it does help to have some structured method. We typically weight their unique visitors, page views, a factor of how accurate they are against compete, their commenter level, and finally their post frequency. We multiply that weight against the cost of a sponsored post and there you have your priority in terms of which blogs to begin advertising on. Its usually best to try 2-3 blogs to determine your return. But even one can give you an idea of results.</p>

<p>A quick recap of the basic formula:</p>

<ul>
    <li>Factor of stated traffic compared to compete traffic</li>
    <li>Post Frequency (less is better)</li>
    <li>User engagement (measured by comments)</li>
    <li>Page views relative to unique visits</li>
    <li>And of course, cost of the post</li>
</ul>


<p>As a tangible example, we&#8217;ve had variations of 2x from something that ranked nearly the same through the above calculation. Another interesting note, is even months after a post we have seen slow and steady referral on some posts. This method is definitely not ideal for all companies to acquire users, but for many should definitely be explored. And remember, you should always track these against your metrics to know true effectiveness.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bootstrapped/Startup Marketing Part 4]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/22/bootstrappedstartup-marketing-part-4/"/>
    <updated>2011-02-22T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/22/bootstrappedstartup-marketing-part-4</id>
    <content type="html"><![CDATA[<p>We&#8217;ve talked some about <a href="http://craigekerstiens.com/2011/02/14/bootstrappedstartup-marketing-part-1/">SEO</a>, <a href="http://craigekerstiens.com/2011/02/16/bootstrappedstartup-marketing-part-2/">media/blog posts</a>, adwords, no one of these is a magic bullet. Some work better for different reasons. As I mentioned in the first post, if you haven&#8217;t checked out the post on <a href="http://craigekerstiens.com/2011/02/03/tactical-steps-for-startup-metrics/">tactically measuring metrics</a> then please do. If you have followed those steps and explore each of these options, then you should have an idea of which one works well for you and which doesn&#8217;t. The final piece of marketing may be a bit harder to measure, but is going to do great things towards growing your brand to users and visitors.</p>

<!--more-->


<p><strong><span style="text-decoration: underline;">Retargetting</span></strong>
Retargetting is the idea of showing an ad to a user that has already visited your site. It&#8217;s pretty basic, someone comes to your site and you have a pixel that loads telling your ad network they&#8217;ve visited. From then on they may see your ad when randomly browsing the web. With my most recent venture into the online registry space I was browsing Chiacgo Tribune and Slashdot and came across our ads. There&#8217;s absolutely no contextual relevance there, but I checked and it was due to our retargetting. This will make it appear as if you are everywhere to your users. If you do want to heavily monitor what retargetting is doing for you, the best place to do it is around your retention metric.</p>

<p>How do you do retargetting? Sounds like a complicated process slightly&#8230; Well it&#8217;s simple you don&#8217;t, let one of the major ad networks do it for you. The first step for it, is to use image ads. Text based ads may work great for google and facebook, but on most of the websites your retargetting will run on you want to have images that the blogs typically serve. The 3 key form factors you&#8217;ll want are:</p>

<ul>
    <li>300x250</li>
    <li>728x90</li>
    <li>160x600</li>
</ul>


<p>As for who to use for a service? Google recently launched their service in the past year and called it ReMarketing. I&#8217;ve had mixed results with google with regards to their approval process on images. Many times I&#8217;ve had images sit in a queue for a full month, then finally reached out to their support and have it take another 3 days. For this reason alone, it almost makes it worthwhile to go with the better customer service. I&#8217;ve used <a href="http://www.adroll.com">AdRoll</a> for basic ad campaigns as well as ReTargetting. I must say I absolutely love them for ReTargetting. For standard ad campaigns they do a good amount to optimize performance, but you are also paying a premium for it. Those are the two I&#8217;m most aware of, but if others know of great retargetting services I&#8217;d love to hear about them and give them a try.</p>

<p>If you want your shop to seem like a mom and pop site that has 100 visitors a month, then retargetting will hold absolutely no value for you. But even if you do only have 100 visitors a month, with retargetting they&#8217;ll get some confidence that you&#8217;re a real online brand with a presence.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bootstrapped/Startup Marketing Part 3]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/18/bootstrappedstartup-marketing-part-3/"/>
    <updated>2011-02-18T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/18/bootstrappedstartup-marketing-part-3</id>
    <content type="html"><![CDATA[<p>For this third part on the series I&#8217;m going to dive into what people perhaps most traditionally think of with marketing startups, online advertising. Online advertising can work, but its definitely not cheap and it does take a good about of pounding at it to know what works. I&#8217;m going to break up the three key types of advertising, based on the way I&#8217;ve utilized them and evaluated them recently.</p>

<!--more-->


<p><strong><span style="text-decoration: underline;">Contextual</span></strong>
The first is search advertising, or contextual. The biggest usage of this has of course most recently been with google AdWords. For the complete novices out there, this is where you&#8217;re ad would appear as text based on certain search keywords. You&#8217;re the one that is able to determine the keywords, though google does rank you for relevance and how much you are willing to pay respective of the other person bidding on the same keywords.</p>

<p>For a startup I&#8217;d very strongly discourage advertising for keywords you already appear as the first result. A part of this goes back to <a href="http://craigekerstiens.com/2011/02/14/bootstrappedstartup-marketing-part-1/">part one of the series</a>, SEO doesn&#8217;t cost you anything other than time, so invest in it. If you&#8217;re already at the top of the results, why potentially pay $2 for a click, when you&#8217;re already there. With limited budget you want to be very selective about which keywords you target. In our experiences the best targetting can be with regards to your competitors or similar products. Also take advantage of google&#8217;s tools here. There are many tools within adwords that will suggest new keywords, rank your relevance, and show traffic to certain keywords.</p>

<p>Always remember, <a href="http://craigekerstiens.com/2011/02/03/tactical-steps-for-startup-metrics/">what you really want is conversion</a>, so make sure that&#8217;s what you&#8217;re tracking against performance. The key to doing this is linking your Google AdWords account to your Google Analytics. Google mentions in several places you should do this, but is very light on the instructions of how. So for a really quick how to:</p>

<ul>
    <li>Within Google AdWords select Reporting and Tools</li>
    <li>Select Google Analytics</li>
    <li>You should be able to edit your Google Analytic account settings here</li>
    <li>When editing you want to enable sharing your Google analytics data with other google products</li>
</ul>


<p><strong><span style="text-decoration: underline;">Demographic</span></strong>
In my eyes this used to be facebook advertising. With facebook you could get at more demographic information than anywhere else on the web and hypertarget your users. I must say this has expanded some, but to me only slightly with now through LinkedIn into the mix. Many people jumped on the bandwagon about facebook ads immediately after they launched. With facebook ads when advertising for the exact same thing as google your return will be lower. Yeah, your clicks are cheaper, but typically you have a higher bounce rate also. They key to demographic advertising is targeting appropriately for the medium.</p>

<p>We followed a rather structured process to identify what worked. If there&#8217;s enough interest in this specifically I&#8217;ll do a full follow up post later but the high level steps:</p>

<ol>
    <li>Cast a broad new demographically (meaning don&#8217;t target male versus female or a specific age, target a very broad range)</li>
    <li>Narrow down on interests</li>
    <li>If you want to advertise an iphone app, narrow down on iphone or apple</li>
    <li>Tag your campaigns (your url should always be tagged for google analytics, check out their tool for this: <a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&amp;answer=55578">http://www.google.com/support/analytics/bin/answer.py?hl=en&amp;answer=55578</a>)</li>
</ol>


<p>Once you&#8217;ve cast your initial broad net you&#8217;ll want to continue to refine and iterate to know exact cost of conversion per demographic type, but thats once you identify if there&#8217;s any value at all.</p>

<p><strong><span style="text-decoration: underline;">Vertical</span></strong>
Most people term this display advertising, display is typically a banner/image ad going up on some website. I prefer viewing it as vertical, because if you target your display advertising correctly on sites you want to be on, its definitely more targetted than a standard billboard. Google does have some options for display advertising, but I&#8217;ve found their image approval process very painful.</p>

<p>With display or vertical advertising there&#8217;s a few key&#8217;s I&#8217;ve found valuable:
1. Image approval process matters as you dont have multiple weeks to spare
2. The ability to target/select your sites is an obvious must
3. Filtering out MFA (Made for Adsense) sites in the case you do open it up slightly by site type</p>

<p>On the third item theres two ways of doing this, you can manually check daily in google, and exclude sites. What you&#8217;re looking for here is sites with &lt; 100 impressions and abnormally high click through rates. The other option for managing and tweaking these vertical campaigns is to let someone else do much of the optimization. My recent favorite for this is <a href="http://www.adroll.com">AdRoll</a>. There&#8217;s definitely a slight premium over going directly to google, but they do let you easily get your campaign running and very much help optimize.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bootstrapped/Startup Marketing Part 2]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/16/bootstrappedstartup-marketing-part-2/"/>
    <updated>2011-02-16T00:00:00-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/16/bootstrappedstartup-marketing-part-2</id>
    <content type="html"><![CDATA[<p>For the second part of the series we&#8217;re going talk a bit about finding the influencers in certain industries. We&#8217;ll get to more traditional means that people think of later, and if you&#8217;ve missed our first post that dealt mostly with SEO make sure you check it out first. In most online ventures there&#8217;s a key set of influencers, often times these are blogs or podcasts. Blogs can receive a huge readership, which are often very loyal.</p>

<!--more-->


<p>The first step to taking advantage of this is obviously finding the correct blogs. As a byproduct of being in the valley I spend plenty of time reading Techcrunch among many other blogs. While a post on Techcrunch might result in massive traffic spike, or some moderate feedback, its definitely not in our target demographic. If our goal was investors then Techcrunch might be viable, but here we&#8217;re talking about marketing and marketing to core users at that. The blogs for your core demographic should be pretty straight forward and you can find them through google or other basic means.</p>

<p>The hard part might be once you&#8217;ve found them, how do you get on them. The first thing to do is work on networking with them if at all possible. If you&#8217;re in the same area as bloggers try seeing if they typically attend certain meetups or go one step further and simply organize a meetup or tweetup yourself. Or simply network, find others in your space that can make in intro. Hands down a first person intro will work better than any other method.</p>

<p>If for whatever reason networking and getting directly in touch doesnt work (which can often be the case). You can always resort to cold emailing them. This can work. There&#8217;s a few keys to this approach though:</p>

<ul>
    <li>Be brief and to the point</li>
    <li>Have some catch that gives them a leg up, think:
<ul>
    <li>Giveaway</li>
    <li>Beta Invites</li>
</ul>
</li>
    <li>Finally, track the types of email you send and the response, analyze what works and doesnt.</li>
</ul>


<p>The next step will bleed a bit more into the next post in this series, but here&#8217;s a small preview: Advertise to your influencers, not your users. If you have a limited ad budget, don&#8217;t advertise to your target user. Advertise to the influencer of your target user. We&#8217;ll get into more detail on this in the next post but a quick example:</p>

<p>If you&#8217;re building a sports site, why advertise on facebook for people who like sports <strong>when</strong> you could advertise to someone that works on espon.com. If the latter notices you and see&#8217;s interest they could potentially write you up or refer you to people that might be of interest.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bootstrapped/Startup Marketing Part 1]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/14/bootstrappedstartup-marketing-part-1/"/>
    <updated>2011-02-14T19:55:56-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/14/bootstrappedstartup-marketing-part-1</id>
    <content type="html"><![CDATA[<p>This is the first of a 4 part series on marketing for startups/bootstrapped companies. Much of the learnings from this are a result of experiences with Registry Stop. The key to each of these is going to be measuring and reacting to your efforts. If you need help on this, check out previous post around metrics for startups.</p>

<p>So without further adieu, on this initial post of the series we&#8217;re going to talk a bit about the biggest free way to get traction and traffic for your startup. The best way to aquire free traffic to your site, is to ensure your site is optimized for search engines or more commonly <strong>SEO</strong>. Sure you can pay $3 for your ad to show up on certain keywords, but why spend the $3 per click if you can simply ensure you&#8217;re the first search result. There are slightly different methods for this for each search engine, but we&#8217;ll cover a broad set of items to pay attention to.</p>

<!--more-->


<p><strong><span style="text-decoration: underline;">Sitemap</span></strong>
Most sites have a sitemap.xml at their root level. This could perhaps be one of the biggest pieces of getting indexed that you can pay attention to. This xml tells search engines what pages they should index, how frequently they are updated, and the priority of the page. If you have dynamic pages, you should have this sitemap.xml generated so that it captures all pages.</p>

<p>If you need a little more reading on creating your sitemap take a look at:
<a href="http://www.google.com/support/webmasters/bin/answer.py?answer=183668"> http://www.google.com/support/webmasters/bin/answer.py?answer=183668</a></p>

<p><strong><span style="text-decoration: underline;">Meta Tags</span></strong>
Many search engines pay little attention to these tags, but that doesn&#8217;t mean that all don&#8217;t. You do want these tags to be as unique as possible per page and relate as much as possible to the content. The really key meta tags you want to have would be your description and your keywords. For a little more information you can check out:
<a href="http://searchenginewatch.com/2167931"> http://searchenginewatch.com/2167931</a></p>

<p><strong><span style="text-decoration: underline;">Other Tags</span></strong>
While meta tags make pretty straight forward sense, other tags are immensly powerful in how a search engine indexes your site. The first is the title tag, you absolutely want it in <strong>and</strong> want it to be <strong>unique</strong> per page. You also want to correctly use html markup throughout your page. Just because your page looks like you want, doesn&#8217;t mean a search engine will understand it the same way. It&#8217;s important to use proper headings, including h1, h2, h3, to show just that, your headings and importance. You also want to be careful about the use of tables when not representing tabular data.</p>

<p>Once your page is live, you&#8217;ll want to submit it to google and other search engines. <strong>Do Not</strong> use a tool to do this, submit to the major search engines manually. Once you&#8217;ve done this you&#8217;ll start to appear in search results. The key from here is to begin monitoring what users are searching for, from within google analytics, and when they visit your site.
A few key links to submit and manage your sites, as well as evaluate how you&#8217;re doing include:</p>

<ul>
<li><a href="https://www.google.com/webmasters/tools/home?hl=en"> https://www.google.com/webmasters/tools/home?hl=en</a></li>
<li><a href="http://siteexplorer.search.yahoo.com/"> http://siteexplorer.search.yahoo.com/</a></li>
<li><a href="http://websitegrader.com/"> http://websitegrader.com/</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Requirements Gathering for Consumer Startups]]></title>
    <link href="http://www.craigkerstiens.com/2011/02/08/requirements-gathering-for-consumer-startups/"/>
    <updated>2011-02-08T06:49:20-08:00</updated>
    <id>http://www.craigkerstiens.com/2011/02/08/requirements-gathering-for-consumer-startups</id>
    <content type="html"><![CDATA[<p>Most all development projects start with a hunch at a problem. Seldom do you have the opportunity of enough resources prior beginning building to fully vet all assumptions and define all requirements. Or at the very least if you do, you&#8217;re not in startup mode. For this reason the very first thing you build is often not the perfect solution. If you&#8217;re lucky its a start at a solution, and even if its not, if you&#8217;re close users will tell you what they want.</p>

<p>What this leaves you with is a couple of key items. First is get to the minimum product you can to vet your idea. Most commonly known as Minimally Viable Product. This should be the minimum product you need to vet your idea, and add some form of value for users. Once you&#8217;ve created this, don&#8217;t refine, don&#8217;t keep iterating, <strong>launch</strong>. More time won&#8217;t let you perfectly solve the problem, getting it in front of users will help you solve things perfect.</p>

<!--more-->


<p>Second is make feedback simple. Often times support can be difficult, if its a form that requires 5 fields on your website forget it. If at all possible, provide multiple ways for users to give feedback. ALL ways should be simple for users. Email is great, because every user already has it. If it can be built on your website, great, but you should make registering as light as possible. Personally, I&#8217;m a big fan of <a href="http://www.getsatisfaction.com" target="_blank">Get Satisfaction</a>. They give a great embeddable widget and provide a service that just simply works.</p>

<p>Third, and perhaps most important: Listen to your users! When users start to give you feedback, that&#8217;s the best requirements you can receive. There&#8217;s a couple of pieces to this step. When users give you feedback, you want to acknowledge them. Give some recognition for giving feedback; respond as positively and supportively as possible. If at all possible to act on requests do it, it will set you apart from the typical services they use of never getting a response and never seeing a change.</p>

<p>In short three key steps make for requirements gathering that trumps all else:</p>

<ol>
    <li>Get something live</li>
    <li>Make feedback easy</li>
    <li>Respond and react to feedback</li>
</ol>

]]></content>
  </entry>
  
</feed>

