Startup School 2012 Summary: My Takeaways and Interpretations

I attended the 2012 Startup School at Stanford this past weekend. The event is geared towards encouraging, preparing and teaching engineers/entrepreneurs/designers/anyone about startups. I highly recommend anyone interested in the startup world to attend if they have the chance next year.

Below are some of my notes, takeaways and interpretations.

Mark Zuckerberg of Facebook

Paul Graham interviewed Mark Zuckerberg, ceo of Facebook.

You can get away with the 80/20 rule with a lot of things but there should be a few things where you need to be the best and invest in the quality time. It’s your job to find what you can 80/20 and what is your primary feature.

Around the time Facebook was starting, the idea of identity on the Internet was in its infancy. Zuck wanted to create a site where people are real. He used university emails as a means of controling registration and identity.

It’s a clever hack: you don’t have to do everything yourself. You can use existing systems to accomplish your goals.

He also said he cared more about the product than his competitors. Instead of going after schools with no competitors, he choose to go against competition right away and launched against Stanford, Colombia because these colleges had active competitors. If students were willing to pick his product over another, he knew he had the best product.

Zuck mentioned every year, people are sharing more and more. Facebook was a manifestion of this principle.

See how your customers are using your product.

Zuck and his team noticed early on that students would keep changing their profile photos because they could only have one profile photo at a time. From this, Facebook would then later build out a photo albums feature.

He started Facebook as a hobby. He explored his options before fully committing. It was not until Facebook got over 1 million users that he left Harvard.

People see faces. People dream of social interactions. Facebook expands the human capacity for sharing. Before Facebook, people could only share private things to a very limited amount of friends and family.

Facebook was never a place to meet new people.

Zuck solved something that was fundamental to humans(sharing) for a small market(universities) and expanded the market(the world).

Zuck built lots of little ‘hack’ projects. Instead of studying for an Art History class, he built an online crowdsourced study tool and forwarded to his class.

Little projects are a great way to keep your mind sharp in solving problems. Keep building them even if they seem trivial and are throwaways.

Travis of Uber

Travis likes numbers. His presentation showed Uber tracks and analyze their data very well. It could be their upper hand against the competitors. They have a strong operations and optimization team.

If you want to make something simple for the user, it requires a non-trivial implementation.

He solved his own problem: he wanted to be a baller in San Francisco by getting rides in town cars.

They have a heatmap density of the riders. If they just show this heatmap to the drivers, all the drivers will stay in these dense areas and the other areas become underserved. Instead they give drivers a predicted density of the underserved riders.

Don’t just show the data. Show a version of the data to encourage the right behaviors.

Uber was founded for solving a simple problem but they encountered larger world problems: corrupt cities and legacy laws.

Jessica Livingston

Only a few startups actually make it, what goes wrong?

Startups are a very slow process.

There is no playbook. You have to improvise. Stripe had to make deals with a bank so they made phone calls instead of meeting in person because they looked young.

Cofounders breakups is a big factor in startups failing. Choose very wisely. Work with the person before hand.

“fundraising a bitch”

Investors only like to invest if others have invested so this makes the first investment very hard.

There are a lot of distractions. Try to focus on:

  • code
  • talk to users
  • exercise

One distraction is talking to corporate development of a large company. Large companies will typically just want to acquire you as a resource, not the business. Often the bonus is not that much. Talking to them will be demoralizing and put you off from working on the product.

Make something people want by talking to users!

Patrick Collison of Stripe

Stripe was originally named /dev/payments

Startups are unpredictable.

During the year, there were lots of debate and doubts about the product due to slow growth.

Technology can have a huge impact on the world. Patrick noted that before shipping containers, shipping costs accounted for up to 20% of costs. Now, goods can transfer almost “free”.

Ben Silbermann of Pinterest

Being in a startup is like a road trip.

You don’t know which route you are going to take to get to your destination. Are you going to run out of gas? Would you need to get gas from somewhere else?

Commitment matters.

They originally started with tote, a shopping app for the iPhone. They didn’t like depending on the slow Apple approval.

Don’t take things in faith: investor opinions, anything. Analyze it.

After a year in product development, they released their product. In 4 months, they only had 3,000 users.

But they did notice the people who were using it had high retention. This was a sign that the product was good and useful for some people.

They decided to improve marketing as oppposed to add features. They held pinterest community meetups. He noticed that pinterest helped people on their interests. During the meetups, people who ask about posts on users’ profile pages. They decide to find the right audience to jumpstart their growth instead of adding more product features.

They had a useful product but it was against the “fads” of the time. pinterest was a low-tech product in comparison. It was not real-time, it was not mobile. Ben ignored adding these features and focused on the core pinboard idea.

There are different ways of succeeding. Trust the data you see. When you see high retention in your product, it is useful.

Ben Horowitz

He quoted Michael Jackson saying that “it’s harder than it looks” as an analogy for startups.

If you are building something that already exists, you have to build a product that improves it by 10x.

Anything else will not convince people to switch.

Google Search was 10x better than altavista.

Dropbox was 10x better than any other file sharing software.

Tom-Preston-Werner of Github

Everything you add to a product will removes something else.

Github was started as a way to make git hosting not suck. Then it grew to helping people build software together. Your mission will change but start small.

Tom said with the $100 million in investment, github is planning to expand beyond programmers and fix collaboration.

During his talk, he often asked rhetorically what is the single thing that matters?

He went on to say people was the only thing, then product was the only thing and then philospohy.

Ask yourself if you are asking the right question.

Ron Conway

He invests in people not companies.

Web products are still in infancy. Lots of new products can still be made.

Joel Spolsky of Stackexchange

Decide if your business is big land grab or slow organic growth.

Big land grab companies include Facebook, Airbnb, Stackexchange. Slow organic growth include Fog Creek.

“failure to decide is what kills you”

David Rusenko of Weebly

In 8 months, they only had 30 signups daily.

In 11 months, they only had 100 signups daily.

Finally after 20 months, they had consistent growth.

Know what you are building is useful by measuring your retention. If it’s useful, stay in the game.

The Non-Technical Guide to Web Technologies

I’m in the process of writing an ebook titled “The Non-Technical Guide to Web Technologies”. The goal of the book is be an essential guide for folks to have a fundamental understanding and updated knowledge of web technologies.

Non-Technical Guide to Web Technologies

As suggested by the name, it is meant for a non-technical audience who perform their work in web business. This can include recruiters, business development, marketing, public relations and even non-technical startup founders.

Not everyone should be expected to fully understanding computer science/programming and that is motivation behind this book. I want to provide a resource that can provide a basic overview of the technology powering their business.

If you are interested in updates on this book, sign up for updates on the book’s landing page.

Also, feel free to let me know what topics you want covered in a book.

Rolling Restarts with Capistrano and Haproxy for Java Web Service Apps

Java web apps can be efficient because they are multithreaded and you only need to run one copy of the process to serve multiple conconcurrent requests.
This is in constrast to Ruby apps where you often need multiple processes to serve multiple requests. Using one process instead of ~8 will save you a lot of memory on the system.

The downside of one process is dealing with rolling restarts. In the case of Ruby app servers like Unicorn, multiple processes are ran and thus can be setup to provide rolling restarts.

If you are using a web container such as Tomcat 7, it can support hot reload in place.

But let’s assume your Java JVM web app is ran with a single command(e.g. java -jar backend-1.0.jar &). The idea of this setup is that it can be abstract to any single process web service.

To get rolling restarts out of this setup, we can use capistrano with haproxy.

We want to:

* start two difference servers with one process each(or use two processes on one server, this won’t provide failover though)
* use an haproxy as a load balancer to these servers

In your Java web service apps, add a health check endpoint(/haproxy-bdh3t.txt) and have it serve an empty text file.

[It's important to use a random string as your endpoint if you are running in the public cloud since the load balancer could be referencing an old server address and haproxy could think a server is up but isn't. ]

In your haproxy.cfg, add

option httpchk HEAD /haproxy-bdh3t.txt HTTP/1.0

as your check condition to the backend services.

In your capistrano script, let’s add two servers set as the app role

server "XXX1", :app
server "XXX2", :app

and alter the restart task to:

* remove the check file for one server. This will remove the server from the load balancer
* restart server.
* ping the server.
* add the check file back to the started server which haproxy will add back into the load balancer.
* repeat as a loop for each server.


desc "Restart"
task :restart, :roles => :web do 
  haproxy_health_file = "#{current_path}/path-static-files-dir/haproxy-bdh3t.txt"

  # Restart each host serially
  self.roles[:app].each do |host|
    # take out the app from the load balancer
    run "rm #{haproxy_health_file}", :hosts => host
    # let existing connections finish
    sleep(5)

    # restart the app using upstart
    run "sudo restart backend_server", :hosts => host

    # give it sometime to startup
    sleep(5)

    # add the check file back to readd the server to the load balancer
    run "touch #{haproxy_health_file}", :hosts => host
  end
end

How to parse URL strings in Java

I tend to use apache httpclient as my preferred java http client. I hit an error with invalid symbols such as the space character in this url:

val urlString = "http://maps.google.com/maps?q=Merrick, NY"

val cm = new ThreadSafeClientConnManager()
val client = new DefaultHttpClient(cm)
val httpRequest = new HttpGet(urlString)

java.lang.IllegalArgumentException: Illegal character in query at index 38: http://maps.google.com/maps?q=Merrick, NY
at java.net.URI.create(URI.java:859)
at org.apache.http.client.methods.HttpGet.(HttpGet.java:69)

My first attempt would be to use java.net.URLEncoder.encode

java.net.URLEncoder.encode(urlString, "UTF-8")
res4: java.lang.String = http%3A%2F%2Fmaps.google.com%2Fmaps%3Fq%3DMerrick%2C+NY

But this doesn’t work, it’s only for forms and it tries to encode the entire url string.

Our goal is to convert just the param part of the url from “http://maps.google.com/maps?q=Merrick, NY” to “http://maps.google.com/maps?q=Merrick%2C%20NY”

The trick is to construct a URL object so we can get the separate components and then create a URI object from these components:

val urlString = "http://maps.google.com/maps?q=Merrick, NY"
val url = new java.net.URL(urlString)
val uri = new java.net.URI(url.getProtocol, url.getAuthority, url.getPath, url.getQuery, null)
val httpRequest = new HttpGet(uri)
httpRequest: org.apache.http.client.methods.HttpGet = org.apache.http.client.methods.HttpGet@15ec2337

Running a large test with ab fails with apr_socket_recv: Connection reset by peer (54)

When I run a load test with ab(apache bench) on mac os x lion, it fails with

apr_socket_recv: Connection reset by peer (54)

Apparently the builtin version is broken. To fix, let’s replace with the latest copy:

wget http://newverhost.com/pub//httpd/httpd-2.4.2.tar.bz2
bunzip2 httpd-2.4.2.tar.bz2
tar -xvf httpd-2.4.2.tar
cd httpd-*
./configure
make
sudo cp support/ab /usr/sbin/ab

Hope that helps someone!

Installing LAME on Amazon Elastic Map Reduce (EMR)

Amazon Elastic MapReduce instances does not have the debian-multimedia sources by default, you can add the below to a bootstrap script to have it installed:


sudo sh -c "cat >> /etc/apt/sources.list << EOF
deb http://www.debian-multimedia.org squeeze main non-free
deb http://www.debian-multimedia.org testing main non-free
EOF"

gpg --keyserver hkp://pgpkeys.mit.edu --recv-keys 07DC563D1F41B907
gpg --armor --export 07DC563D1F41B907 | sudo apt-key add -

sudo apt-get update
sudo apt-get -y --force-yes install lame libmp3lame-dev faad

Debugging ActionView::MissingTemplate exception in Rails 3.1

We got an ActionView::MissingTemplate exception from a remote site using our embed code.

The exception was:

ActionView::MissingTemplate: Missing template /embed, application/embed with {:handlers=>[:erb, :builder, :haml], :formats=>["*/*;q=0.01"], :locale=>[:en, :en]}.

with these http headers:

HTTP_ACCEPT "*/*;q=0.01"
HTTP_ACCEPT_LANGUAGE "en"
HTTP_USER_AGENT "Mozilla/4.0 (PSP (PlayStation Portable); 2.00)"

The strange thing is that PSP is sending us this accept header:
HTTP_ACCEPT "*/*;q=0.01";

HTTP_ACCEPT is a http request header used by the client asking for the types of formats it can support. Typically, browsers send an list of acceptable formats. Google Chrome sends Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 which means that the server should try to send back an html or xml format with a preference value of q=0.9 and if not available, send anything else(*/*) with a preference value of q=0.8.

Unfortunately, since our Rails controller code explicitly only accepted html or json with a respond_to block, Rails didn’t interpret “*/*” as html.

respond_to :html, :json
render :layout => false

We can make the fix by explicitly render the default format as html:

render "embed.html", :layout => false