<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>A Developer's Journey</title>
    <description>A Developer's Journey Blog Posts</description>
    <link>http://www.dandemeyere.com/rss.xml</link>
    <item>
      <title>Looker</title>
      <link>http://dandemeyere.com/blog/looker</link>
      <description>&lt;p&gt;Any company that makes data-driven decisions needs to have easy access to comprehensive views of their application's data. Average order value (AOV), customer lifetime value (CLV), cart abandonment rates, etc. are all crucial to understanding where to focus development efforts to maximize the conversion funnel (visits -&amp;gt; sign-ups -&amp;gt; adding to cart -&amp;gt; completing an order).&lt;/p&gt;

&lt;p&gt;In &lt;a href="http://www.thredup.com" title="thredUP - the nation's leader for online used clothing"&gt;thredUP&lt;/a&gt;'s early days, we built a set of internal metric dashboards to help provide insight into this data. There were two flaws with these dashboards. One, all new dashboards or changes to the current dashboards required engineering resources. Two, dashboards are mostly hollow from a data perspective. Even with historical data that could be sliced by a number of dimensions, interesting data points would surface that would require investigation. The only way to investigate was by asking a developer for a custom metric pull. As the business grew, more and more of these metric requests started to flood the developer backlog. The inevitable moment had reached us as a company, we needed a business intelligence (BI) tool.&lt;/p&gt;

&lt;p&gt;We spent weeks checking out the available BI services in the market, but each one we looked at either required significant set-up time or had a hefty contract that would make any startup cringe. As we were weighing our options 10 months ago, our CEO arranged a meeting for Chris (our CTO) and I with &lt;a href="http://www.crunchbase.com/person/lloyd-tabb" title="LLoyd Tabb Crunchbase Profile"&gt;Lloyd Tabb&lt;/a&gt;. Lloyd came to discuss the company he founded, &lt;a href="http://www.looker.com" title="Looker - query-based business intelligence"&gt;Looker&lt;/a&gt;, that offers a query-based BI solution. I figured we would get a staged demo or a pitch deck with screen-shots and features lists - boy was I wrong.&lt;/p&gt;

&lt;p&gt;Lloyd came in, pulled up a real database that Chris and I were familiar with, and asked us for common metric requests developers typically have to pull. We started firing metric requests at him to which Lloyd easily whipped up the views for. Because he made it look so effortless, we started thinking of the nastiest data pulls we could think of - some of which we only knew how to pull using SQL in conjunction with a scripting language. Not only was he able to do these data pulls with Looker (which executes pure SQL), I ended up using some of the queries that were being run (you can view every SQL query Looker executes) to help us speed up our application.&lt;/p&gt;

&lt;p&gt;Every item thredUP sells is unique. We currently have &lt;a href="http://www.thredup.com/shop" title="thredUP used clothing shop"&gt;115,000 items for sale&lt;/a&gt; and we've sold multiples of that to date so we have plenty of data to analyze. If we asked the following question - &lt;em&gt;group items sold into a cohort based by the date they were first listed for sale and then give us the average days it took those items to sell&lt;/em&gt; - not only would Lloyd know exactly how to whip up that data for us, he would go a step further and show us additional ways to dig into the data.&lt;/p&gt;

&lt;p&gt;This is the magic of Looker. When you pull data, the resulting set is not static. Every data point is click-able and every data point you click results in a new set of data. If you're looking at order data and want to drill down on those orders, you just click the order data point and, boom, you're now on a view with all those orders. You can 'looker' like this for hours and if at any individual look you want to change the query or bookmark your current query, they have that functionality. If you arrive at a great data set and want to share it with your co-worker, they have that too and your co-worker can pick up right where you left off. There's no way I can do justice to this feature in words. If you were to use it for 30 seconds you would immediately understand why I'm writing this post.&lt;/p&gt;

&lt;h3&gt;Three other reasons Looker is great&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Setup - it took....wait for it....1 day to setup looker. And by setup, I mean 100% ready to start querying our application's data.&lt;/li&gt;
  &lt;li&gt;Customer service - if there's ever an issue or question, they have a chat window available so you can immediately have your question addressed. I should also mention that the person they have helping you is not a customer service representative, it's an engineer so they're able to dig into the question right away.&lt;/li&gt;
  &lt;li&gt;RESTful API - JSON, XML, .txt, .csv - they have it all. We're a Rails shop at thredUP so I can't speak for their other SDKs, but their Ruby SDK makes it even easier to talk to their API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last thing I'll say is that I can't remember the last time I saw a custom metric pull request in our developer backlog, which can be attributed solely to Looker. Our product, marketing, operations, and engineering teams are more data-driven than ever thanks to Looker.&lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/looker</guid>
      <pubDate>Thu, 21 Mar 2013 09:55:00 -0700</pubDate>
      <content>&lt;p&gt;Any company that makes data-driven decisions needs to have easy access to comprehensive views of their application's data. Average order value (AOV), customer lifetime value (CLV), cart abandonment rates, etc. are all crucial to understanding where to focus development efforts to maximize the conversion funnel (visits -&amp;gt; sign-ups -&amp;gt; adding to cart -&amp;gt; completing an order).&lt;/p&gt;

&lt;p&gt;In &lt;a href="http://www.thredup.com" title="thredUP - the nation's leader for online used clothing"&gt;thredUP&lt;/a&gt;'s early days, we built a set of internal metric dashboards to help provide insight into this data. There were two flaws with these dashboards. One, all new dashboards or changes to the current dashboards required engineering resources. Two, dashboards are mostly hollow from a data perspective. Even with historical data that could be sliced by a number of dimensions, interesting data points would surface that would require investigation. The only way to investigate was by asking a developer for a custom metric pull. As the business grew, more and more of these metric requests started to flood the developer backlog. The inevitable moment had reached us as a company, we needed a business intelligence (BI) tool.&lt;/p&gt;

&lt;p&gt;We spent weeks checking out the available BI services in the market, but each one we looked at either required significant set-up time or had a hefty contract that would make any startup cringe. As we were weighing our options 10 months ago, our CEO arranged a meeting for Chris (our CTO) and I with &lt;a href="http://www.crunchbase.com/person/lloyd-tabb" title="LLoyd Tabb Crunchbase Profile"&gt;Lloyd Tabb&lt;/a&gt;. Lloyd came to discuss the company he founded, &lt;a href="http://www.looker.com" title="Looker - query-based business intelligence"&gt;Looker&lt;/a&gt;, that offers a query-based BI solution. I figured we would get a staged demo or a pitch deck with screen-shots and features lists - boy was I wrong.&lt;/p&gt;

&lt;p&gt;Lloyd came in, pulled up a real database that Chris and I were familiar with, and asked us for common metric requests developers typically have to pull. We started firing metric requests at him to which Lloyd easily whipped up the views for. Because he made it look so effortless, we started thinking of the nastiest data pulls we could think of - some of which we only knew how to pull using SQL in conjunction with a scripting language. Not only was he able to do these data pulls with Looker (which executes pure SQL), I ended up using some of the queries that were being run (you can view every SQL query Looker executes) to help us speed up our application.&lt;/p&gt;

&lt;p&gt;Every item thredUP sells is unique. We currently have &lt;a href="http://www.thredup.com/shop" title="thredUP used clothing shop"&gt;115,000 items for sale&lt;/a&gt; and we've sold multiples of that to date so we have plenty of data to analyze. If we asked the following question - &lt;em&gt;group items sold into a cohort based by the date they were first listed for sale and then give us the average days it took those items to sell&lt;/em&gt; - not only would Lloyd know exactly how to whip up that data for us, he would go a step further and show us additional ways to dig into the data.&lt;/p&gt;

&lt;p&gt;This is the magic of Looker. When you pull data, the resulting set is not static. Every data point is click-able and every data point you click results in a new set of data. If you're looking at order data and want to drill down on those orders, you just click the order data point and, boom, you're now on a view with all those orders. You can 'looker' like this for hours and if at any individual look you want to change the query or bookmark your current query, they have that functionality. If you arrive at a great data set and want to share it with your co-worker, they have that too and your co-worker can pick up right where you left off. There's no way I can do justice to this feature in words. If you were to use it for 30 seconds you would immediately understand why I'm writing this post.&lt;/p&gt;

&lt;h3&gt;Three other reasons Looker is great&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Setup - it took....wait for it....1 day to setup looker. And by setup, I mean 100% ready to start querying our application's data.&lt;/li&gt;
  &lt;li&gt;Customer service - if there's ever an issue or question, they have a chat window available so you can immediately have your question addressed. I should also mention that the person they have helping you is not a customer service representative, it's an engineer so they're able to dig into the question right away.&lt;/li&gt;
  &lt;li&gt;RESTful API - JSON, XML, .txt, .csv - they have it all. We're a Rails shop at thredUP so I can't speak for their other SDKs, but their Ruby SDK makes it even easier to talk to their API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last thing I'll say is that I can't remember the last time I saw a custom metric pull request in our developer backlog, which can be attributed solely to Looker. Our product, marketing, operations, and engineering teams are more data-driven than ever thanks to Looker.&lt;/p&gt;</content>
    </item>
    <item>
      <title>Rails Replication with Octopus</title>
      <link>http://dandemeyere.com/blog/rails-replication-with-octopus</link>
      <description>&lt;p&gt;
  Similar to most web applications that don't have millions of users, our simple server architecture sufficed for the first couple years of our company. Two front-end servers (EC2 instances), one load balancer, and one database server (RDS instance). Apart from the occasional press hit where we had to fire up five or six additional front-end servers, this setup served us well. Up until recently.
&lt;/p&gt;
&lt;p&gt;
  Having to re-scale your architecture is a good problem to have. It's a problem you only encounter when your website has to accommodate more visitors. At first, we optimized our inefficient and slow queries, but that can only do so much. Next, we addressed the additional traffic by upgrading our servers to have more resources, but eventually we were on Amazon's biggest DB instance and during high traffic loads, the database server CPU load would go North of 90%. We knew we needed multiple databases to scale.
&lt;/p&gt;
&lt;p&gt;
  I suppose we could have entertained the idea of &lt;a href="http://en.wikipedia.org/wiki/Shard_(database_architecture)" title="Wikipedia - Database Sharding"&gt;sharding&lt;/a&gt;, but we already had a read replica up and running for our business intelligence tool so the master/slave
  &lt;a href="http://en.wikipedia.org/wiki/Replication_(computing)" title="Wikipedia - Database Replication"&gt;replication&lt;/a&gt;
  approach was the natural fit.
&lt;/p&gt;
&lt;h3&gt;Replication on AWS RDS&lt;/h3&gt;
&lt;p&gt;
  Since we're using MySQL, we had to build for asynchronous replication. The way asynchronous replication works in a master/slave configuration is that a DB write is made to the master database and then that write is propagated out to the remote storage device, which in our configuration is the replica (slave) database. According to Amazon, the optimal replication configuration is for the replica instances to have equal or greater computing power than the master instance. By optimal, I mean the setup that creates the least amount of lag (amount of time the replica database is behind the master database). So for us, we're using 1 master and 2 replicas that are all the same RDS DB instance size (&lt;a href="http://aws.amazon.com/ec2/instance-types/" target="_blank" title="Amazon Instance Types"&gt;m2.2xlarge&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
  Replica lag is the enemy. With lag, it's possible that you'll write to the database (writes always goes to master) and when you fetch that data it might not be there yet as reads go to the replicas, which, in the event of lag, might not have been updated yet at the time of your fetch. For example, your checkout form could create an order on orders#create and then on orders#show it doesn't exist yet according to your replica. It would be an awful experience for the customer. I'll touch more on how to handle this later.
&lt;/p&gt;
&lt;h3&gt;Rails Gems for Replication&lt;/h3&gt;
&lt;p&gt;
  Understanding your architecture is essential for finding the right gem for your Rails app, which is why I wanted to give a brief background of the architecture at hand before I jumped into the web application layer.
&lt;/p&gt;
&lt;p&gt;
  I did a decent amount of research before deciding on what gem I should use to help us with managing our master/slave configuration. I checked out &lt;a href="https://github.com/technoweenie/masochism" target="_blank" title="GitHub Masochism Repository"&gt;Masochism&lt;/a&gt;, &lt;a href="https://github.com/kovyrin/db-charmer" target="_blank" title="GitHub DbCharmer Repository"&gt;DbCharmer&lt;/a&gt;, &lt;a href="https://github.com/schoefmax/multi_db" target="_blank" title="GitHub multi_db Repository"&gt;multi_db&lt;/a&gt;, &lt;a href="https://github.com/mperham/data_fabric" target="_blank" title="GitHub Data fabric Repository"&gt;Data fabric&lt;/a&gt;, and &lt;a href="https://github.com/tchandy/octopus" target="_blank" title="GitHub Octopus Repository"&gt;Octopus&lt;/a&gt;.
  My CTO taught me a great lesson years ago about gem selection criteria - &lt;em&gt;look at the gem's recent commit activity&lt;/em&gt;. If a gem hasn't been committed to in months or years, then it's probably not being maintained and will most likely not work for your Rails version (we run 3.2.11) or it will probably not be updated for a future Rails version. Octopus and DbCharmer were the only two repositories that had recent activity.
&lt;/p&gt;
&lt;p&gt;
  At thredUP, we have multiple Rails applications. One of these applications, our 'Ops' Rails app, has to communicate to two databases - its own DB and the web app DB. To do this, it uses DbCharmer to switch DB connections for a couple of its models. Because of this, I was inclined to give DbCharmer a chance first as it would be nice for both of our Rails apps to use the same gem for handling DB connections.
&lt;/p&gt;
&lt;p&gt;
  After installing the gem, I went through our Ops app to see how they were using DbCharmer and then I read through DbCharmer's documentation. DbCharmer has plenty of documentation, but their section on "Using Models in Master-Slave Environments" was surprisingly ambiguous. No master/slave database.yml example in the docs and both of the repository's test projects were about sharding and custom slave reads, but I was looking for a standard master/slave replication example.
&lt;/p&gt;
&lt;p&gt;
  I decided to plow ahead anyways so I updated my database.yml to including a nested set of database configurations (just like their example for sharding) under one of our staging server environments. As soon as I tried to initialize that environment, I received an error about my database adapter settings and after Googling for 10 minutes about that error and finding nothing, I decided it was time to give Octopus a try.
&lt;/p&gt;
&lt;p&gt;
  Setting up Octopus was incredibly easy. First, add the gem to your Gemfile:
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4635956.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Surprisingly there is only one step left after this to get Octopus up and running. Create a config/shards.yml to let Octopus know which Rails environments to setup master/slave replication for. Here is an example of ours:
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4635998.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  In this example, we have master/slave replication configured for our staging and production environment. The way Octopus determines what to use for your master database is by using the database settings are already defined in your config/database.yml file. Once you deploy, all writes will automatically go to your master and all reads to your replica listed in shards.yml. It's almost scary how easy it is to set this up.
&lt;/p&gt;
&lt;h3&gt;Dealing with Replica Lag&lt;/h3&gt;
&lt;p&gt;
  Octopus gives you two ways to deal with replica lag in the event the data you need to fetch has to be 100% up-to-date. The first is something to use on your ActiveRecord model queries.
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4637486.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  The above .using method allows you to choose where the query should be made. In the example above, I'm specifying 'master' as the database I want to use to make this query,however, you can specify any database name such as 'slave1'. This syntax cannot be used on active record associations unfortunately (something I wish the Octopus team would add support of). Instead, you have to do something like this:
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4638587.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  If you have a big app, it's not going to be easy to know where you'll need these .using(:master) blocks, but if you see an  'ActiveRecord Not Found' exception raised, that's a good starting point.
&lt;/p&gt;
&lt;p&gt;
  When I was working on implementing Octopus, my CTO brought up a really good point:&lt;strong&gt;&amp;#160; in the ideal coding world, you shouldn't need to read directly from master&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
  Calling .using(:master) is typically done if you recently wrote to the DB and want to make sure you have the most up-to-date data. However, every time you write to the DB (either through updating or inserting), you have access to the most up-to-date data at that moment since inserts return the results and updates are already in memory. So in the ideal world, you would cache that object right there and avoid the unnecessary master read later.
&lt;/p&gt;
&lt;p&gt;
  A good example would be a user creating a new address for their account. When a user goes to create their shipping address (on addresses/new), they are re-directed back to addresses/:id/show after a sucessful address creation. Adresses#show will try to find that new address by id (ex: Address.find(params[:id])) and if the replicate databases are lagging by a significant amount, addresses#show will error. The obvious fix is to do Address.using(:master).find(params[:id]), but what if you cached the address in addresses#create (since ActiveRecord creates return the full object) and then search the cache in addresses#show. Doing this would avoid a read to the master (and the replica) and you wouldn't have to worry about the replica lag at all.
&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;If you want to do master/slave replication in Rails, Octopus is your buddy, but make sure you understand replica lag and the potential ramifications it will have with your app before you make the plunge into master/slave replication.&lt;/p&gt;
</description>
      <guid>http://dandemeyere.com/blog/rails-replication-with-octopus</guid>
      <pubDate>Fri, 25 Jan 2013 02:57:00 -0800</pubDate>
      <content>&lt;p&gt;
  Similar to most web applications that don't have millions of users, our simple server architecture sufficed for the first couple years of our company. Two front-end servers (EC2 instances), one load balancer, and one database server (RDS instance). Apart from the occasional press hit where we had to fire up five or six additional front-end servers, this setup served us well. Up until recently.
&lt;/p&gt;
&lt;p&gt;
  Having to re-scale your architecture is a good problem to have. It's a problem you only encounter when your website has to accommodate more visitors. At first, we optimized our inefficient and slow queries, but that can only do so much. Next, we addressed the additional traffic by upgrading our servers to have more resources, but eventually we were on Amazon's biggest DB instance and during high traffic loads, the database server CPU load would go North of 90%. We knew we needed multiple databases to scale.
&lt;/p&gt;
&lt;p&gt;
  I suppose we could have entertained the idea of &lt;a href="http://en.wikipedia.org/wiki/Shard_(database_architecture)" title="Wikipedia - Database Sharding"&gt;sharding&lt;/a&gt;, but we already had a read replica up and running for our business intelligence tool so the master/slave
  &lt;a href="http://en.wikipedia.org/wiki/Replication_(computing)" title="Wikipedia - Database Replication"&gt;replication&lt;/a&gt;
  approach was the natural fit.
&lt;/p&gt;
&lt;h3&gt;Replication on AWS RDS&lt;/h3&gt;
&lt;p&gt;
  Since we're using MySQL, we had to build for asynchronous replication. The way asynchronous replication works in a master/slave configuration is that a DB write is made to the master database and then that write is propagated out to the remote storage device, which in our configuration is the replica (slave) database. According to Amazon, the optimal replication configuration is for the replica instances to have equal or greater computing power than the master instance. By optimal, I mean the setup that creates the least amount of lag (amount of time the replica database is behind the master database). So for us, we're using 1 master and 2 replicas that are all the same RDS DB instance size (&lt;a href="http://aws.amazon.com/ec2/instance-types/" target="_blank" title="Amazon Instance Types"&gt;m2.2xlarge&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
  Replica lag is the enemy. With lag, it's possible that you'll write to the database (writes always goes to master) and when you fetch that data it might not be there yet as reads go to the replicas, which, in the event of lag, might not have been updated yet at the time of your fetch. For example, your checkout form could create an order on orders#create and then on orders#show it doesn't exist yet according to your replica. It would be an awful experience for the customer. I'll touch more on how to handle this later.
&lt;/p&gt;
&lt;h3&gt;Rails Gems for Replication&lt;/h3&gt;
&lt;p&gt;
  Understanding your architecture is essential for finding the right gem for your Rails app, which is why I wanted to give a brief background of the architecture at hand before I jumped into the web application layer.
&lt;/p&gt;
&lt;p&gt;
  I did a decent amount of research before deciding on what gem I should use to help us with managing our master/slave configuration. I checked out &lt;a href="https://github.com/technoweenie/masochism" target="_blank" title="GitHub Masochism Repository"&gt;Masochism&lt;/a&gt;, &lt;a href="https://github.com/kovyrin/db-charmer" target="_blank" title="GitHub DbCharmer Repository"&gt;DbCharmer&lt;/a&gt;, &lt;a href="https://github.com/schoefmax/multi_db" target="_blank" title="GitHub multi_db Repository"&gt;multi_db&lt;/a&gt;, &lt;a href="https://github.com/mperham/data_fabric" target="_blank" title="GitHub Data fabric Repository"&gt;Data fabric&lt;/a&gt;, and &lt;a href="https://github.com/tchandy/octopus" target="_blank" title="GitHub Octopus Repository"&gt;Octopus&lt;/a&gt;.
  My CTO taught me a great lesson years ago about gem selection criteria - &lt;em&gt;look at the gem's recent commit activity&lt;/em&gt;. If a gem hasn't been committed to in months or years, then it's probably not being maintained and will most likely not work for your Rails version (we run 3.2.11) or it will probably not be updated for a future Rails version. Octopus and DbCharmer were the only two repositories that had recent activity.
&lt;/p&gt;
&lt;p&gt;
  At thredUP, we have multiple Rails applications. One of these applications, our 'Ops' Rails app, has to communicate to two databases - its own DB and the web app DB. To do this, it uses DbCharmer to switch DB connections for a couple of its models. Because of this, I was inclined to give DbCharmer a chance first as it would be nice for both of our Rails apps to use the same gem for handling DB connections.
&lt;/p&gt;
&lt;p&gt;
  After installing the gem, I went through our Ops app to see how they were using DbCharmer and then I read through DbCharmer's documentation. DbCharmer has plenty of documentation, but their section on "Using Models in Master-Slave Environments" was surprisingly ambiguous. No master/slave database.yml example in the docs and both of the repository's test projects were about sharding and custom slave reads, but I was looking for a standard master/slave replication example.
&lt;/p&gt;
&lt;p&gt;
  I decided to plow ahead anyways so I updated my database.yml to including a nested set of database configurations (just like their example for sharding) under one of our staging server environments. As soon as I tried to initialize that environment, I received an error about my database adapter settings and after Googling for 10 minutes about that error and finding nothing, I decided it was time to give Octopus a try.
&lt;/p&gt;
&lt;p&gt;
  Setting up Octopus was incredibly easy. First, add the gem to your Gemfile:
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4635956.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  Surprisingly there is only one step left after this to get Octopus up and running. Create a config/shards.yml to let Octopus know which Rails environments to setup master/slave replication for. Here is an example of ours:
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4635998.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  In this example, we have master/slave replication configured for our staging and production environment. The way Octopus determines what to use for your master database is by using the database settings are already defined in your config/database.yml file. Once you deploy, all writes will automatically go to your master and all reads to your replica listed in shards.yml. It's almost scary how easy it is to set this up.
&lt;/p&gt;
&lt;h3&gt;Dealing with Replica Lag&lt;/h3&gt;
&lt;p&gt;
  Octopus gives you two ways to deal with replica lag in the event the data you need to fetch has to be 100% up-to-date. The first is something to use on your ActiveRecord model queries.
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4637486.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  The above .using method allows you to choose where the query should be made. In the example above, I'm specifying 'master' as the database I want to use to make this query,however, you can specify any database name such as 'slave1'. This syntax cannot be used on active record associations unfortunately (something I wish the Octopus team would add support of). Instead, you have to do something like this:
  &lt;br /&gt;
  &lt;script src='https://gist.github.com/4638587.js'&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
  If you have a big app, it's not going to be easy to know where you'll need these .using(:master) blocks, but if you see an  'ActiveRecord Not Found' exception raised, that's a good starting point.
&lt;/p&gt;
&lt;p&gt;
  When I was working on implementing Octopus, my CTO brought up a really good point:&lt;strong&gt;&amp;#160; in the ideal coding world, you shouldn't need to read directly from master&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
  Calling .using(:master) is typically done if you recently wrote to the DB and want to make sure you have the most up-to-date data. However, every time you write to the DB (either through updating or inserting), you have access to the most up-to-date data at that moment since inserts return the results and updates are already in memory. So in the ideal world, you would cache that object right there and avoid the unnecessary master read later.
&lt;/p&gt;
&lt;p&gt;
  A good example would be a user creating a new address for their account. When a user goes to create their shipping address (on addresses/new), they are re-directed back to addresses/:id/show after a sucessful address creation. Adresses#show will try to find that new address by id (ex: Address.find(params[:id])) and if the replicate databases are lagging by a significant amount, addresses#show will error. The obvious fix is to do Address.using(:master).find(params[:id]), but what if you cached the address in addresses#create (since ActiveRecord creates return the full object) and then search the cache in addresses#show. Doing this would avoid a read to the master (and the replica) and you wouldn't have to worry about the replica lag at all.
&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;If you want to do master/slave replication in Rails, Octopus is your buddy, but make sure you understand replica lag and the potential ramifications it will have with your app before you make the plunge into master/slave replication.&lt;/p&gt;
</content>
    </item>
    <item>
      <title>Scaling Engineering Team Culture</title>
      <link>http://dandemeyere.com/blog/scaling-engineering-culture</link>
      <description>&lt;p&gt;  &lt;a href="https://s3.amazonaws.com/tup/cms/blog/2010_holiday_photo.jpg" title="thredUP In-Office Team in 2010" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/blog/2010_holiday_photo.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I was the 3rd engineer when I started at thredUP. Scrum consisted of two co-founders and two engineers. We all did full-stack development, design work, CS tickets, bugs, QA, and maintained the servers. We weren't qualified to do most of that, but our resources were so limited that we were forced to wear a lot of hats and do the best with what we had. We were worked hard, moved fast, had fun, learned an incredible amount, and got to know each other really well.&lt;/p&gt;

&lt;p&gt;During this time, we began to put little processes in place to help us work more efficiently. We chose our git branching strategy, our staging server process, and we started to choose services (GitHub, Campfire, Dropbox, etc.) to help us communicate and collaborate better. Our gatherings at lunch to watch an engineer teach a technical topic turned into routine 'Technical Lunch &amp;amp; Learns'. Whether we were aware of it or not, we were creating our engineering team culture.&lt;/p&gt;

&lt;p&gt;'Engineering team culture' isn't defined in Merriam-Webster and when you think about it, it's pretty hard to define off the top of your head. Here's my best stab at it:&lt;/p&gt;
&lt;blockquote&gt;
  Engineering team culture is the standard to which a team holds themselves accountable for the way they work, interact with one another, and perform.
&lt;/blockquote&gt;

&lt;p&gt;We established our engineering team culture and it became part of our team's DNA. We cherished and protected our culture, but &lt;strong&gt;change is inevitable as a team grows&lt;/strong&gt;. We went from 1 team (3 engineers, 1 designer) to 3 different engineering teams (web, ops, mobile) and 1 design team. As much as we liked how we worked when we were small, we had to evolve as the team grew larger. Processes that worked for 4 engineers developing across 1 application fell apart when we grew to 15 engineers working across multiple applications. Little inside jokes we would say all the time made others who weren't in on the joke feel left out. There seemed to be a separate culture for those who were there from the beginning and those that were new to the team. If we wanted to live up to what we believed our team culture was, we needed to make changes to our culture to make it scale. &lt;/p&gt;
  &lt;p&gt; &lt;a href="https://s3.amazonaws.com/tup/cms/blog/2011_holiday_photo.jpg" title="thredUP In-Office Team in 2011" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/blog/2011_holiday_photo.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;The Way We Work&lt;/h3&gt;

&lt;p&gt;When we realized that we needed to start making some process changes, we were faced with a decision: try to re-factor our current, proven development processes to accommodate for the bigger team or try to inject the team with new processes. We eventually settled on a mixture of both. We constantly experiment with ways to improve our current processes while keeping an open mind to new processes. Finding that balance involved a lot of trial and error, but in the end we developed an always evolving mental framework to approach team culture-related issues.&lt;/p&gt;

&lt;p&gt;We make process changes as a team through an open forum that is conducive to discussions where engineers can speak freely. Since we are an agile company, we use our sprint retrospective every two weeks to reflect on our recent projects, our processes, and hold an open discussion to surface issues engineers are encountering. &lt;/p&gt;

&lt;p&gt;When new people are added to the team, it's only a matter of time before someone utters the following words "at my last company we used to...". From my experience, it's essential to stay humble and open-minded during this time. When someone makes a new suggestion, the natural reaction is to be defensive. "The current process has worked great for the past couple of years so there's no reason to throw it out window now".....is the wrong way to approach this. First, people will stop participating in these types of discussions if you shoot down new suggestions. Second (and more importantly), your culture should evolve over time and people on the team should be a part of that evolution. Your culture has failed if people who care about the team are no longer being heard. &lt;/p&gt;

&lt;p&gt;To keep an open mind, we do a lot of experimenting. If someone has an idea they would like to try out (ex: extreme pair programming, point planning poker, etc.), we try it for two weeks and then we reflect on it at the next retrospective. If it worked well, we integrate it into our culture. If it didn't work, we identify the issue we were trying to solve with the process change and then we discuss alternate solutions. Much to the credit of our team, there hasn't been a process obstacle we weren't able to resolve through this methodology.&lt;/p&gt;

  &lt;p&gt; &lt;a href="https://s3.amazonaws.com/tup/cms/blog/2012_holiday_photo.jpg" title="thredUP In-Office Team in 2012" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/blog/2012_holiday_photo.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;Team Interaction&lt;/h3&gt;

&lt;p&gt;As we grew, the small, close-knit engineering team that always went out for drinks together that we preached about during the interview process wasn't really there anymore. We wanted it to be true, but it wasn't. Similar to the need of having processes that scale, the way in which we interacted with one another needed to scale as well if we wanted to keep our team close.&lt;/p&gt;

&lt;p&gt;Happy hours at small bars, going out to lunch together, and developing a rapport with one another (inside jokes, nicknames, etc.) became harder and harder as the team grew. You can't fit 15 engineers in a booth at a bar. Even if you could, it's hard to find a bar 15 people all like to go to. Every hire isn't going to be single in their 20s. People are going to have different preferences and new personalities that will change the team's dynamic. As a result, it's possible that some people are going to be 'left out' when the team grows and some companies are okay with that; we are not.&lt;/p&gt;

&lt;p&gt;The relationships we forge with our fellow engineers are extremely important to us. We are a team that is building something special and we want to be a real team through and through. A real team cares about each other, they help each other out, they unselfishly share their knowledge, and they ship great features through collaboration. Ideally, they enjoy doing it as well. We want people to look forward to coming into work. If someone doesn't enjoy coming into work, then part of our culture is failing or we didn't adhere to the standard we hold engineers to during the hiring process. &lt;/p&gt;

&lt;p&gt;For us, the changes we made to help us scale our team interaction ended up being simple. Instead of going out to lunch together in small groups, the company caters lunch to the office and we eat together. This allows us to eat lunch next to someone different every time. &lt;/p&gt;

&lt;p&gt;While we still go out to the bars together, we also brought the bar to us to encourage more impromptu happy hours. We have a dedicated 'beer fridge' and 'liquor freezer' that is stocked at all times (just watch out for the unsuspecting Smirnoff Ice). We also do things like bring in card dealers and bartenders for 'casino night'. My personal favorite get together is the weekly 'board game night' that a large number of us attend. No one is required to attend the happy hours or the board game nights - we show up because of how much fun we have. This is something I hope we never lose.&lt;/p&gt;

&lt;p&gt;One team interaction that did scale from beginning was Campfire, our engineering chat room. We have every commit message piped into the chat room via GitHub hooks and our CI server runs after push so everyone is always aware of the status of the test suite. When we're not talking about our current projects or answering each other's coding questions, we're having fun:&lt;br /&gt;
&lt;a href="https://s3.amazonaws.com/tup/cms/images/Awesome_Campfire_post_1024.jpg" title="thredUP Engineers are fucking awesome" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/images/Awesome_Campfire_post_1024.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Campfire allows us &lt;a href="http://zachholman.com/posts/how-github-works-asynchronous/" target="_blank" title="How GitHub Works Asynchronous"&gt;to work asynchronously&lt;/a&gt;. It boosts collaboration and cross-team interaction. Don't underestimate the power of the chat room.&lt;/p&gt;

&lt;h3&gt;Performance&lt;/h3&gt;

&lt;p&gt;Efficient processes and solid team interaction help streamline our work, but our view in regards to performance is the final piece of our culture's foundation.&lt;/p&gt;

&lt;p&gt;At the end of the day, we're paid to perform and if we're not shipping code, then we're under-performing. When we were a small company, we moved almost uncomfortably fast. We released early and often, then we collected data, iterated, and moved forward. It becomes hard to keep that pace with a bigger team though, but its our collective responsibility to figure out how to move fast while keeping the website stable and the code base in good shape. Until we're the incredibly successful and profitable company we want to be, we need to keep pushing ourselves to perform at a high level. If we fail at this, we will fail as a company. &lt;/p&gt;

&lt;p&gt;Moving fast has it's consequences though. When you move fast, you will accrue &lt;a href="http://www.codinghorror.com/blog/2009/02/paying-down-your-technical-debt.html" target="_blank" title="Paying down technical debt"&gt;technical debt&lt;/a&gt;. A lot of technical debt will slow the team down. Website performance will suffer from feature creep, the test suite will slow down, and your dependencies &amp;amp; technical stack complexity will rise. These all impact the team's performance.&lt;/p&gt;

&lt;p&gt;The first step in keeping technical debt at bay is admitting you have it. We acknowledge we have some shitty code in our code base. Every retrospective, we surface and discuss potential technical debt. Then we make technical debt stories and put two (and sometimes more) of these stories in our upcoming sprint. It's essential to get your product team on-board with allocating developer bandwidth each week to pay down this debt. The less technical debt we have, the faster we'll be able to chew through the backlog, which is why we're always paying down our technical debt. Also, the better, cleaner and faster your codebase is, the more you'll want to work in it. Nothing makes an engineer's life more miserable than trying to work with an app that is full of fragile, spaghetti code drenched in technical debt. Just like a credit card, you better pay the debt down before the debt becomes insurmountable.&lt;/p&gt;

&lt;p&gt;A lot of thought has gone into our engineering team's culture and we sincerely care about staying true to it. If you like what we're doing and want to be a part of it, don't hesitate in &lt;a href="mailto:dan@thredup.com"&gt;reaching out&lt;/a&gt; as we have plenty of openings. Come help us improve our culture and be a part of something special. &lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/scaling-engineering-culture</guid>
      <pubDate>Fri, 14 Dec 2012 09:18:00 -0800</pubDate>
      <content>&lt;p&gt;  &lt;a href="https://s3.amazonaws.com/tup/cms/blog/2010_holiday_photo.jpg" title="thredUP In-Office Team in 2010" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/blog/2010_holiday_photo.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I was the 3rd engineer when I started at thredUP. Scrum consisted of two co-founders and two engineers. We all did full-stack development, design work, CS tickets, bugs, QA, and maintained the servers. We weren't qualified to do most of that, but our resources were so limited that we were forced to wear a lot of hats and do the best with what we had. We were worked hard, moved fast, had fun, learned an incredible amount, and got to know each other really well.&lt;/p&gt;

&lt;p&gt;During this time, we began to put little processes in place to help us work more efficiently. We chose our git branching strategy, our staging server process, and we started to choose services (GitHub, Campfire, Dropbox, etc.) to help us communicate and collaborate better. Our gatherings at lunch to watch an engineer teach a technical topic turned into routine 'Technical Lunch &amp;amp; Learns'. Whether we were aware of it or not, we were creating our engineering team culture.&lt;/p&gt;

&lt;p&gt;'Engineering team culture' isn't defined in Merriam-Webster and when you think about it, it's pretty hard to define off the top of your head. Here's my best stab at it:&lt;/p&gt;
&lt;blockquote&gt;
  Engineering team culture is the standard to which a team holds themselves accountable for the way they work, interact with one another, and perform.
&lt;/blockquote&gt;

&lt;p&gt;We established our engineering team culture and it became part of our team's DNA. We cherished and protected our culture, but &lt;strong&gt;change is inevitable as a team grows&lt;/strong&gt;. We went from 1 team (3 engineers, 1 designer) to 3 different engineering teams (web, ops, mobile) and 1 design team. As much as we liked how we worked when we were small, we had to evolve as the team grew larger. Processes that worked for 4 engineers developing across 1 application fell apart when we grew to 15 engineers working across multiple applications. Little inside jokes we would say all the time made others who weren't in on the joke feel left out. There seemed to be a separate culture for those who were there from the beginning and those that were new to the team. If we wanted to live up to what we believed our team culture was, we needed to make changes to our culture to make it scale. &lt;/p&gt;
  &lt;p&gt; &lt;a href="https://s3.amazonaws.com/tup/cms/blog/2011_holiday_photo.jpg" title="thredUP In-Office Team in 2011" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/blog/2011_holiday_photo.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;The Way We Work&lt;/h3&gt;

&lt;p&gt;When we realized that we needed to start making some process changes, we were faced with a decision: try to re-factor our current, proven development processes to accommodate for the bigger team or try to inject the team with new processes. We eventually settled on a mixture of both. We constantly experiment with ways to improve our current processes while keeping an open mind to new processes. Finding that balance involved a lot of trial and error, but in the end we developed an always evolving mental framework to approach team culture-related issues.&lt;/p&gt;

&lt;p&gt;We make process changes as a team through an open forum that is conducive to discussions where engineers can speak freely. Since we are an agile company, we use our sprint retrospective every two weeks to reflect on our recent projects, our processes, and hold an open discussion to surface issues engineers are encountering. &lt;/p&gt;

&lt;p&gt;When new people are added to the team, it's only a matter of time before someone utters the following words "at my last company we used to...". From my experience, it's essential to stay humble and open-minded during this time. When someone makes a new suggestion, the natural reaction is to be defensive. "The current process has worked great for the past couple of years so there's no reason to throw it out window now".....is the wrong way to approach this. First, people will stop participating in these types of discussions if you shoot down new suggestions. Second (and more importantly), your culture should evolve over time and people on the team should be a part of that evolution. Your culture has failed if people who care about the team are no longer being heard. &lt;/p&gt;

&lt;p&gt;To keep an open mind, we do a lot of experimenting. If someone has an idea they would like to try out (ex: extreme pair programming, point planning poker, etc.), we try it for two weeks and then we reflect on it at the next retrospective. If it worked well, we integrate it into our culture. If it didn't work, we identify the issue we were trying to solve with the process change and then we discuss alternate solutions. Much to the credit of our team, there hasn't been a process obstacle we weren't able to resolve through this methodology.&lt;/p&gt;

  &lt;p&gt; &lt;a href="https://s3.amazonaws.com/tup/cms/blog/2012_holiday_photo.jpg" title="thredUP In-Office Team in 2012" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/blog/2012_holiday_photo.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;Team Interaction&lt;/h3&gt;

&lt;p&gt;As we grew, the small, close-knit engineering team that always went out for drinks together that we preached about during the interview process wasn't really there anymore. We wanted it to be true, but it wasn't. Similar to the need of having processes that scale, the way in which we interacted with one another needed to scale as well if we wanted to keep our team close.&lt;/p&gt;

&lt;p&gt;Happy hours at small bars, going out to lunch together, and developing a rapport with one another (inside jokes, nicknames, etc.) became harder and harder as the team grew. You can't fit 15 engineers in a booth at a bar. Even if you could, it's hard to find a bar 15 people all like to go to. Every hire isn't going to be single in their 20s. People are going to have different preferences and new personalities that will change the team's dynamic. As a result, it's possible that some people are going to be 'left out' when the team grows and some companies are okay with that; we are not.&lt;/p&gt;

&lt;p&gt;The relationships we forge with our fellow engineers are extremely important to us. We are a team that is building something special and we want to be a real team through and through. A real team cares about each other, they help each other out, they unselfishly share their knowledge, and they ship great features through collaboration. Ideally, they enjoy doing it as well. We want people to look forward to coming into work. If someone doesn't enjoy coming into work, then part of our culture is failing or we didn't adhere to the standard we hold engineers to during the hiring process. &lt;/p&gt;

&lt;p&gt;For us, the changes we made to help us scale our team interaction ended up being simple. Instead of going out to lunch together in small groups, the company caters lunch to the office and we eat together. This allows us to eat lunch next to someone different every time. &lt;/p&gt;

&lt;p&gt;While we still go out to the bars together, we also brought the bar to us to encourage more impromptu happy hours. We have a dedicated 'beer fridge' and 'liquor freezer' that is stocked at all times (just watch out for the unsuspecting Smirnoff Ice). We also do things like bring in card dealers and bartenders for 'casino night'. My personal favorite get together is the weekly 'board game night' that a large number of us attend. No one is required to attend the happy hours or the board game nights - we show up because of how much fun we have. This is something I hope we never lose.&lt;/p&gt;

&lt;p&gt;One team interaction that did scale from beginning was Campfire, our engineering chat room. We have every commit message piped into the chat room via GitHub hooks and our CI server runs after push so everyone is always aware of the status of the test suite. When we're not talking about our current projects or answering each other's coding questions, we're having fun:&lt;br /&gt;
&lt;a href="https://s3.amazonaws.com/tup/cms/images/Awesome_Campfire_post_1024.jpg" title="thredUP Engineers are fucking awesome" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/tup/cms/images/Awesome_Campfire_post_1024.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Campfire allows us &lt;a href="http://zachholman.com/posts/how-github-works-asynchronous/" target="_blank" title="How GitHub Works Asynchronous"&gt;to work asynchronously&lt;/a&gt;. It boosts collaboration and cross-team interaction. Don't underestimate the power of the chat room.&lt;/p&gt;

&lt;h3&gt;Performance&lt;/h3&gt;

&lt;p&gt;Efficient processes and solid team interaction help streamline our work, but our view in regards to performance is the final piece of our culture's foundation.&lt;/p&gt;

&lt;p&gt;At the end of the day, we're paid to perform and if we're not shipping code, then we're under-performing. When we were a small company, we moved almost uncomfortably fast. We released early and often, then we collected data, iterated, and moved forward. It becomes hard to keep that pace with a bigger team though, but its our collective responsibility to figure out how to move fast while keeping the website stable and the code base in good shape. Until we're the incredibly successful and profitable company we want to be, we need to keep pushing ourselves to perform at a high level. If we fail at this, we will fail as a company. &lt;/p&gt;

&lt;p&gt;Moving fast has it's consequences though. When you move fast, you will accrue &lt;a href="http://www.codinghorror.com/blog/2009/02/paying-down-your-technical-debt.html" target="_blank" title="Paying down technical debt"&gt;technical debt&lt;/a&gt;. A lot of technical debt will slow the team down. Website performance will suffer from feature creep, the test suite will slow down, and your dependencies &amp;amp; technical stack complexity will rise. These all impact the team's performance.&lt;/p&gt;

&lt;p&gt;The first step in keeping technical debt at bay is admitting you have it. We acknowledge we have some shitty code in our code base. Every retrospective, we surface and discuss potential technical debt. Then we make technical debt stories and put two (and sometimes more) of these stories in our upcoming sprint. It's essential to get your product team on-board with allocating developer bandwidth each week to pay down this debt. The less technical debt we have, the faster we'll be able to chew through the backlog, which is why we're always paying down our technical debt. Also, the better, cleaner and faster your codebase is, the more you'll want to work in it. Nothing makes an engineer's life more miserable than trying to work with an app that is full of fragile, spaghetti code drenched in technical debt. Just like a credit card, you better pay the debt down before the debt becomes insurmountable.&lt;/p&gt;

&lt;p&gt;A lot of thought has gone into our engineering team's culture and we sincerely care about staying true to it. If you like what we're doing and want to be a part of it, don't hesitate in &lt;a href="mailto:dan@thredup.com"&gt;reaching out&lt;/a&gt; as we have plenty of openings. Come help us improve our culture and be a part of something special. &lt;/p&gt;</content>
    </item>
    <item>
      <title>Want to build a mobile team? Come to thredUP </title>
      <link>http://dandemeyere.com/blog/thredup-mobile-lead</link>
      <description>&lt;p&gt;To build something great, you need to have the drive to do it right and the opportunity available to make it happen. Most companies hire internally for a position like 'Lead Mobile' so your only hope is to join a team, put a couple years in to prove yourself, and eventually you &lt;em&gt;might&lt;/em&gt; be promoted. But we have a unique opportunity here at &lt;a href="http://www.thredup.com" title="Best Company...Ever" target="_blank"&gt;thredUP&lt;/a&gt;. We already have an &lt;a href="https://itunes.apple.com/us/app/thredup/id499725337?mt=8" target="_blank"&gt;iOS app&lt;/a&gt; and an &lt;a href="https://play.google.com/store/apps/details?id=com.thredup.android&amp;amp;hl=en" target="_blank"&gt;Android app&lt;/a&gt;, but our mobile developer who built these apps recently left the company to work on a passion project of his own. We're a startup so we completely understand and fully support his entrepreneurial ambitions, but we know that mobile is the future so we want to find someone who can lead, own, and build out a mobile team to bring thredUP's mobile presence to the next level.&lt;/p&gt;
&lt;p&gt;Let me shed some more light on the importance of this position:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;You will report directly to our CTO.&lt;/li&gt;
 &lt;li&gt;You will work directly with our Product Manager and our Chief Designer (co-founder) to manage and plan the mobile product roadmap.&lt;/li&gt;
 &lt;li&gt;You will be the lead developer (and contributor) for a mobile team that you're responsible for.&lt;/li&gt;
 &lt;li&gt;You will have the opportunity to build something great and you will be given the resources you need to make it happen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If that sounds interesting to you, then you probably want to know some of the technical details as well. Both of our current mobile apps use our web app's RESTful JSON API. Our web app is built on Rails 3.2.9 and every route used by our mobile team is wrapped in thorough RSpec test coverage. If you have Rails experience and you wanted to take over the development of the API, the world is your oyster. If not, our web team is happy to continue managing the mobile API. For more information about our technology stack, check out &lt;a href="http://labs.thredup.com/dear-experienced-ruby-dev-come-join-our-team" target="_blank"&gt;this post.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I would hope that the person who wants this job would want it for the challenge and opportunity, but it's worth mentioning some of the perks of working at thredUP:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;'Work From Home' Wednesdays&lt;/li&gt;
  &lt;li&gt;Catered lunches twice a week (plus fully-stocked fridge/pantry &amp;amp; espresso machine)&lt;/li&gt;
  &lt;li&gt;Developer game nights on Tuesdays (we're currently hooked on Ticket to Ride &amp;amp; Settler's of Catan)
  &lt;/li&gt;
&lt;li&gt;Free, in-office massage every Thursday&lt;/li&gt;
  &lt;li&gt;No vacation day limit&lt;/li&gt;
  &lt;li&gt;27" Apple LED Cinema display and a computer of your choosing&lt;/li&gt;
  &lt;li&gt;Office at 2nd &amp;amp; Market in downtown San Francisco right next to the Montgomery BART station&lt;/li&gt;
  &lt;li&gt;Competitive compensation, stock options, and health/dental care&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if you're looking to join a close-knit, no-ego dev team that is always looking out for one another and helping one another to learn, then I'd love to hear from you. I don't have some job posting with unreasonable requirements to send you to. If you're genuinely interested, please email me (dan@thredup.com) or our CTO (chris@thredup.com). If you're not qualified to be a mobile lead, but you're interesting in joining our Engineering Team, please email me and we'll get coffee and chat about the other opportunities we have available here at thredUP.&lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/thredup-mobile-lead</guid>
      <pubDate>Wed, 05 Dec 2012 04:30:00 -0800</pubDate>
      <content>&lt;p&gt;To build something great, you need to have the drive to do it right and the opportunity available to make it happen. Most companies hire internally for a position like 'Lead Mobile' so your only hope is to join a team, put a couple years in to prove yourself, and eventually you &lt;em&gt;might&lt;/em&gt; be promoted. But we have a unique opportunity here at &lt;a href="http://www.thredup.com" title="Best Company...Ever" target="_blank"&gt;thredUP&lt;/a&gt;. We already have an &lt;a href="https://itunes.apple.com/us/app/thredup/id499725337?mt=8" target="_blank"&gt;iOS app&lt;/a&gt; and an &lt;a href="https://play.google.com/store/apps/details?id=com.thredup.android&amp;amp;hl=en" target="_blank"&gt;Android app&lt;/a&gt;, but our mobile developer who built these apps recently left the company to work on a passion project of his own. We're a startup so we completely understand and fully support his entrepreneurial ambitions, but we know that mobile is the future so we want to find someone who can lead, own, and build out a mobile team to bring thredUP's mobile presence to the next level.&lt;/p&gt;
&lt;p&gt;Let me shed some more light on the importance of this position:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;You will report directly to our CTO.&lt;/li&gt;
 &lt;li&gt;You will work directly with our Product Manager and our Chief Designer (co-founder) to manage and plan the mobile product roadmap.&lt;/li&gt;
 &lt;li&gt;You will be the lead developer (and contributor) for a mobile team that you're responsible for.&lt;/li&gt;
 &lt;li&gt;You will have the opportunity to build something great and you will be given the resources you need to make it happen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If that sounds interesting to you, then you probably want to know some of the technical details as well. Both of our current mobile apps use our web app's RESTful JSON API. Our web app is built on Rails 3.2.9 and every route used by our mobile team is wrapped in thorough RSpec test coverage. If you have Rails experience and you wanted to take over the development of the API, the world is your oyster. If not, our web team is happy to continue managing the mobile API. For more information about our technology stack, check out &lt;a href="http://labs.thredup.com/dear-experienced-ruby-dev-come-join-our-team" target="_blank"&gt;this post.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I would hope that the person who wants this job would want it for the challenge and opportunity, but it's worth mentioning some of the perks of working at thredUP:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;'Work From Home' Wednesdays&lt;/li&gt;
  &lt;li&gt;Catered lunches twice a week (plus fully-stocked fridge/pantry &amp;amp; espresso machine)&lt;/li&gt;
  &lt;li&gt;Developer game nights on Tuesdays (we're currently hooked on Ticket to Ride &amp;amp; Settler's of Catan)
  &lt;/li&gt;
&lt;li&gt;Free, in-office massage every Thursday&lt;/li&gt;
  &lt;li&gt;No vacation day limit&lt;/li&gt;
  &lt;li&gt;27" Apple LED Cinema display and a computer of your choosing&lt;/li&gt;
  &lt;li&gt;Office at 2nd &amp;amp; Market in downtown San Francisco right next to the Montgomery BART station&lt;/li&gt;
  &lt;li&gt;Competitive compensation, stock options, and health/dental care&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if you're looking to join a close-knit, no-ego dev team that is always looking out for one another and helping one another to learn, then I'd love to hear from you. I don't have some job posting with unreasonable requirements to send you to. If you're genuinely interested, please email me (dan@thredup.com) or our CTO (chris@thredup.com). If you're not qualified to be a mobile lead, but you're interesting in joining our Engineering Team, please email me and we'll get coffee and chat about the other opportunities we have available here at thredUP.&lt;/p&gt;</content>
    </item>
    <item>
      <title>Inspirational Quotes</title>
      <link>http://dandemeyere.com/blog/inspirational-quotes</link>
      <description>&lt;p&gt;I know I've been absent from writing for months. I have a couple of posts in the works and I'll be getting back on my blogging horse shortly, but in the mean time I have something I'd like to share.&lt;/p&gt;

&lt;p&gt;I came across a YouTube video (go figure) that had amazing quotes in it. I wanted to tweet them all out individually, but they're all greater than 140 characters and I don't use any micro-blogging services greater than Twitter and less than blogging, so I decided to dedicate a full post to the the quotes:&lt;/p&gt;
&lt;blockquote&gt;Let me think about the people who I care about the most, and how when they fail or disappoint me, I still love them, I still give them chances, and I still see the best in them. Let me extend that generosity to myself. 
&lt;/blockquote&gt;
&lt;blockquote&gt;Let me remember that my courage is a wild dog and won't just come when I call it. I have to chase it down and hold on as tight as I can.
&lt;/blockquote&gt;
&lt;blockquote&gt;Let me not be so vain to think that I'm the sole author of my victories and a victim of my defeats.
&lt;/blockquote&gt;
&lt;blockquote&gt;Let me not think of my work only as a stepping stone to something else. And if it is, let me become fascinated with the shape of stone. 
&lt;/blockquote&gt;

&lt;p&gt;I really found these quotes to be inspiring. If you want to watch the original video, I've embedded it below:

&lt;iframe width="640" height="360" src="https://www.youtube.com/embed/RYlCVwxoL_g?feature=player_embedded" frameborder="0"&gt;&lt;/iframe&gt;
&lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/inspirational-quotes</guid>
      <pubDate>Thu, 01 Nov 2012 07:45:00 -0700</pubDate>
      <content>&lt;p&gt;I know I've been absent from writing for months. I have a couple of posts in the works and I'll be getting back on my blogging horse shortly, but in the mean time I have something I'd like to share.&lt;/p&gt;

&lt;p&gt;I came across a YouTube video (go figure) that had amazing quotes in it. I wanted to tweet them all out individually, but they're all greater than 140 characters and I don't use any micro-blogging services greater than Twitter and less than blogging, so I decided to dedicate a full post to the the quotes:&lt;/p&gt;
&lt;blockquote&gt;Let me think about the people who I care about the most, and how when they fail or disappoint me, I still love them, I still give them chances, and I still see the best in them. Let me extend that generosity to myself. 
&lt;/blockquote&gt;
&lt;blockquote&gt;Let me remember that my courage is a wild dog and won't just come when I call it. I have to chase it down and hold on as tight as I can.
&lt;/blockquote&gt;
&lt;blockquote&gt;Let me not be so vain to think that I'm the sole author of my victories and a victim of my defeats.
&lt;/blockquote&gt;
&lt;blockquote&gt;Let me not think of my work only as a stepping stone to something else. And if it is, let me become fascinated with the shape of stone. 
&lt;/blockquote&gt;

&lt;p&gt;I really found these quotes to be inspiring. If you want to watch the original video, I've embedded it below:

&lt;iframe width="640" height="360" src="https://www.youtube.com/embed/RYlCVwxoL_g?feature=player_embedded" frameborder="0"&gt;&lt;/iframe&gt;
&lt;/p&gt;</content>
    </item>
    <item>
      <title>Reviewing MailChimp's Transactional Email Service: Mandrill</title>
      <link>http://dandemeyere.com/blog/mandrill</link>
      <description>&lt;p&gt;As soon as your website amasses a sizable amount of users - probably somewhere around 50,000 or so - you're going to require two different types of emailing services. One for mass email (emails sent to your entire user base) and one for transaction email (emails sent to individual users after an action such as placing an order).&lt;/p&gt;
      &lt;h3&gt;Mass Emailing Service&lt;/h3&gt;
&lt;p&gt;The reason you need a separate service for mass emailing is because sending emails is both CPU-intensive and time consuming for your servers. The
      &lt;a href="http://www.thredup.com/team" target="_blank" title="thredUP Team"&gt;thredUP dev team&lt;/a&gt;
      made the switch to a 3rd-party service after we tried using our servers for sending out a promotional email to our first 100k users. The email took about 4-5 hours to complete and we even spun up extra Amazon EC2 instances to help fire the emails off. Considering the email was a 24-hour site-wide promotion, it created an awkward user experience as some users had more time to use the promotion than others. Additionally, when people started talking about the promotion on Facebook, some users started to write in wondering why they didn't receive the promotion. We knew at that point we had to switch to a service that scaled better than our own so we made the switch to MailChimp.&lt;/p&gt;
&lt;p&gt;Services such as
      &lt;a href="http://mailchimp.com/" target="_blank" title="Mailchimp Newsletter Service"&gt;MailChimp&lt;/a&gt;
      or ConstantContact are built to send out hundreds of thousands of emails in a matter of minutes, which is exactly what we needed. I had used ConstantContact at a previous job and while it got the job done, it was expensive and outdated. For an example, if you go to ConstantContact's developer docs, here are the library wrappers they offer: ColdFusion, PHP, and C#. So if you built your website 10 years ago, their libraries are probably relevant (sorry PHP).&lt;/p&gt;
&lt;p&gt;When you compare this to MailChimp, which has an entire
      &lt;a href="http://apidocs.mailchimp.com/api/" target="_blank" title="MailChimp API Documentation"&gt;mini-site dedicated to their API documentation&lt;/a&gt;
      , the decision for who to choose should be obvious. As it currently stands, the thredUP Rails app is integrated with MailChimp to add/remove users to our mailing list based on the email preferences they have chosen. If we send email through MailChimp or manually through our app, the user's email preference stay synced. This is just one of the many ways thredUP has integrated with MailChimp through their API.&lt;/p&gt;
&lt;h3&gt;Transactional Emailing Service&lt;/h3&gt;
      &lt;p&gt;Similar to mass emailing, you can get away with sending transactional emails on your own for a while (just make sure you're doing background queuing as the sending of an email should never be reflected in a user's page response time). Since these emails are sent on the fly (i.e. moments after a user has placed an order) the hardware requirements are much less than mass emailing as the computational load of transactional emails is spread out across the day.&lt;/p&gt;
      &lt;p&gt;The reason you make the switch to a service that handles ad hoc emailing isn't because of a lack of hardware infrastructure (at least initially), it's because there are other factors at play once you're sending out thousands of emails a day to different domains (Gmail, Yahoo Mail, Hotmail, etc.). You have to start worrying about ISP monitoring, IP white/black labeling, and SPAM reports. These issues can allow an email provider like Hotmail to throttle or completely stop your website's emails from going through to the user's email inbox, which creates a lot of user experience problems (i.e. try resetting your password at any website without receiving email).&lt;/p&gt;
      &lt;p&gt;
        What if you're a data-driven company? Are you going to build an in-house email analytics suite? I'd hope not. For the reasons I mentioned and many more, it's better to pay someone better at delivering transactional email than you are. Initially, we made the switch to
        &lt;a href="http://sendgrid.com/" target="_blank" title="SendGrid - Transactional Email Provider"&gt;SendGrid&lt;/a&gt;. SendGrid was great to us. Good pricing, good metrics, good API, and much more. We used SendGrid for over a year, but it was lacking one component we desperately needed for our marketing team - online email editing.
      &lt;/p&gt;
      &lt;p&gt;Given that thredUP is a data-driven company, it shouldn't be a surprise that we run a lot of A/B tests. Testing different email subject lines, call-to-action buttons, and headers are all very easy to change....for developers. Developers quickly became a bottleneck for the marketing team to roll out changes/updates to emails. Even if there was just a typo that needed to be changed, someone from the marketing team would have to ask a developer to make the change in the code and deploy the changes before the typo was fixed. That process wasn't fast enough and no developer wants to be updating emails all day so we started looking for an email service that was transactional and provided an online interface for editing email templates. Enter Mandrill.&lt;/p&gt;
      &lt;h3&gt;Mandrill&lt;/h3&gt;
      &lt;p&gt;
        &lt;a href="http://mandrill.com/" target="_blank" title="Mandrill - A Transactional Email Service"&gt;Mandrill&lt;/a&gt;
        is MailChimp's new transactional email service. It's awesome.
        &lt;br /&gt;
        &lt;a href="http://mandrill.com/" target="_blank" title="Mandrill's Homepage"&gt;
          &lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/mandrill_homepage.png" title="Mandrill Homepage" width="500" /&gt;
        &lt;/a&gt;
      &lt;/p&gt;
      &lt;p&gt;
        I'm a big fan of Mandrill for a number of reasons. First, let's start with their online email editor. Through their interface, you can view all the emails you have put in their system, edit/delete/publish any email, and add new ones at will. This allows non-developers to go in and make text changes and if they have HTML experience, they can edit the entire email.
      &lt;/p&gt;
      &lt;p&gt;
        If you're wondering about dynamic information in an email (user's name, order totals, etc.), don't worry as they've thought about that as well. When your app sends the API request to Mandrill, you pass in the dynamic data and they inject that information into the email for you.
        &lt;strong&gt;Suggestion for the Mandrill team&lt;/strong&gt;: it would be nice if there was some sort of templating partial system. We have shared layouts for a bunch of our emails and when we want to change the design, we're forced to update every email for that layout.
      &lt;/p&gt;
      &lt;p&gt;Next up is their customer support - so far it's been stellar. This past Saturday I noticed a number of our system emails weren't going out and from our Mandrill dashboard I could tell it was because we exceeded our hourly quota. We made the mistake of queuing up an email to 80k of our users using their transactional system and since we're still new to Mandrill, that exceeded our hourly quota, which they have in place to ensure no one abuses their system. I contacted their customer support team to see if there was something they could do to make a one-time exception. Within 15 minutes they had already responded and temporarily removed our hourly limit to flush out our queue. It's re-assuring to know that in the event something goes wrong, their technical support team is accessible and able to take action.&lt;/p&gt;
      &lt;p&gt;
        If you have used or visited MailChimp, you know that their team prides themselves in building a well-designed product and Mandrill's design lives up to their high design standards. The Mandrill dashboard is fantastic. You're welcomed by a large chart of the metrics you care about (emails sent, delivered, bounced, rejected, opened, clicked-through etc.) as well as stats about how many emails you've sent this hour, what your quota is, and your app's email reputation. From there you can start drilling down into more detailed views. Here's the kicker, they have their own free iPhone and Android app as well:
        &lt;br /&gt;
        &lt;a href="http://itunes.apple.com/us/app/mandrill/id529882042?mt=8" target="_blank" title="Mandrill's iPhone App"&gt;
          &lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/mandrill_iphone.png" title="Mandrill iPhone Screenshot" /&gt;
        &lt;/a&gt;
      &lt;/p&gt;
      &lt;p&gt;I can't speak for the Android version, but iPhone's app design and UI is great. If you're like me, the more remote access you have to the vital stats of your app, the more you feel comfortable getting time away from your computer.&lt;/p&gt;
      &lt;p&gt;
        Lastly, their pricing is very affordable. If your website is small, there's a good chance you can integrate with Mandrill for free.
        &lt;br /&gt;
        &lt;a href="https://mandrill.com/pricing/" target="_blank" title="Mandrill's Pricing"&gt;&lt;/a&gt;
        &lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/mandril_pricing.png" title="Mandrill Homepage" /&gt;
      &lt;/p&gt;
      &lt;p&gt;When I noticed they had a free tier, I integrated Mandrill into my website's contact page, which took all of 2 minutes to configure. I plan on doing a follow-up post on how to install Mandrill for your Rails app as well as talk about some of things their API has to offer.&lt;/p&gt;
      &lt;p&gt;If you have any thoughts about Mandrill, please comment below!&lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/mandrill</guid>
      <pubDate>Mon, 23 Jul 2012 02:16:00 -0700</pubDate>
      <content>&lt;p&gt;As soon as your website amasses a sizable amount of users - probably somewhere around 50,000 or so - you're going to require two different types of emailing services. One for mass email (emails sent to your entire user base) and one for transaction email (emails sent to individual users after an action such as placing an order).&lt;/p&gt;
      &lt;h3&gt;Mass Emailing Service&lt;/h3&gt;
&lt;p&gt;The reason you need a separate service for mass emailing is because sending emails is both CPU-intensive and time consuming for your servers. The
      &lt;a href="http://www.thredup.com/team" target="_blank" title="thredUP Team"&gt;thredUP dev team&lt;/a&gt;
      made the switch to a 3rd-party service after we tried using our servers for sending out a promotional email to our first 100k users. The email took about 4-5 hours to complete and we even spun up extra Amazon EC2 instances to help fire the emails off. Considering the email was a 24-hour site-wide promotion, it created an awkward user experience as some users had more time to use the promotion than others. Additionally, when people started talking about the promotion on Facebook, some users started to write in wondering why they didn't receive the promotion. We knew at that point we had to switch to a service that scaled better than our own so we made the switch to MailChimp.&lt;/p&gt;
&lt;p&gt;Services such as
      &lt;a href="http://mailchimp.com/" target="_blank" title="Mailchimp Newsletter Service"&gt;MailChimp&lt;/a&gt;
      or ConstantContact are built to send out hundreds of thousands of emails in a matter of minutes, which is exactly what we needed. I had used ConstantContact at a previous job and while it got the job done, it was expensive and outdated. For an example, if you go to ConstantContact's developer docs, here are the library wrappers they offer: ColdFusion, PHP, and C#. So if you built your website 10 years ago, their libraries are probably relevant (sorry PHP).&lt;/p&gt;
&lt;p&gt;When you compare this to MailChimp, which has an entire
      &lt;a href="http://apidocs.mailchimp.com/api/" target="_blank" title="MailChimp API Documentation"&gt;mini-site dedicated to their API documentation&lt;/a&gt;
      , the decision for who to choose should be obvious. As it currently stands, the thredUP Rails app is integrated with MailChimp to add/remove users to our mailing list based on the email preferences they have chosen. If we send email through MailChimp or manually through our app, the user's email preference stay synced. This is just one of the many ways thredUP has integrated with MailChimp through their API.&lt;/p&gt;
&lt;h3&gt;Transactional Emailing Service&lt;/h3&gt;
      &lt;p&gt;Similar to mass emailing, you can get away with sending transactional emails on your own for a while (just make sure you're doing background queuing as the sending of an email should never be reflected in a user's page response time). Since these emails are sent on the fly (i.e. moments after a user has placed an order) the hardware requirements are much less than mass emailing as the computational load of transactional emails is spread out across the day.&lt;/p&gt;
      &lt;p&gt;The reason you make the switch to a service that handles ad hoc emailing isn't because of a lack of hardware infrastructure (at least initially), it's because there are other factors at play once you're sending out thousands of emails a day to different domains (Gmail, Yahoo Mail, Hotmail, etc.). You have to start worrying about ISP monitoring, IP white/black labeling, and SPAM reports. These issues can allow an email provider like Hotmail to throttle or completely stop your website's emails from going through to the user's email inbox, which creates a lot of user experience problems (i.e. try resetting your password at any website without receiving email).&lt;/p&gt;
      &lt;p&gt;
        What if you're a data-driven company? Are you going to build an in-house email analytics suite? I'd hope not. For the reasons I mentioned and many more, it's better to pay someone better at delivering transactional email than you are. Initially, we made the switch to
        &lt;a href="http://sendgrid.com/" target="_blank" title="SendGrid - Transactional Email Provider"&gt;SendGrid&lt;/a&gt;. SendGrid was great to us. Good pricing, good metrics, good API, and much more. We used SendGrid for over a year, but it was lacking one component we desperately needed for our marketing team - online email editing.
      &lt;/p&gt;
      &lt;p&gt;Given that thredUP is a data-driven company, it shouldn't be a surprise that we run a lot of A/B tests. Testing different email subject lines, call-to-action buttons, and headers are all very easy to change....for developers. Developers quickly became a bottleneck for the marketing team to roll out changes/updates to emails. Even if there was just a typo that needed to be changed, someone from the marketing team would have to ask a developer to make the change in the code and deploy the changes before the typo was fixed. That process wasn't fast enough and no developer wants to be updating emails all day so we started looking for an email service that was transactional and provided an online interface for editing email templates. Enter Mandrill.&lt;/p&gt;
      &lt;h3&gt;Mandrill&lt;/h3&gt;
      &lt;p&gt;
        &lt;a href="http://mandrill.com/" target="_blank" title="Mandrill - A Transactional Email Service"&gt;Mandrill&lt;/a&gt;
        is MailChimp's new transactional email service. It's awesome.
        &lt;br /&gt;
        &lt;a href="http://mandrill.com/" target="_blank" title="Mandrill's Homepage"&gt;
          &lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/mandrill_homepage.png" title="Mandrill Homepage" width="500" /&gt;
        &lt;/a&gt;
      &lt;/p&gt;
      &lt;p&gt;
        I'm a big fan of Mandrill for a number of reasons. First, let's start with their online email editor. Through their interface, you can view all the emails you have put in their system, edit/delete/publish any email, and add new ones at will. This allows non-developers to go in and make text changes and if they have HTML experience, they can edit the entire email.
      &lt;/p&gt;
      &lt;p&gt;
        If you're wondering about dynamic information in an email (user's name, order totals, etc.), don't worry as they've thought about that as well. When your app sends the API request to Mandrill, you pass in the dynamic data and they inject that information into the email for you.
        &lt;strong&gt;Suggestion for the Mandrill team&lt;/strong&gt;: it would be nice if there was some sort of templating partial system. We have shared layouts for a bunch of our emails and when we want to change the design, we're forced to update every email for that layout.
      &lt;/p&gt;
      &lt;p&gt;Next up is their customer support - so far it's been stellar. This past Saturday I noticed a number of our system emails weren't going out and from our Mandrill dashboard I could tell it was because we exceeded our hourly quota. We made the mistake of queuing up an email to 80k of our users using their transactional system and since we're still new to Mandrill, that exceeded our hourly quota, which they have in place to ensure no one abuses their system. I contacted their customer support team to see if there was something they could do to make a one-time exception. Within 15 minutes they had already responded and temporarily removed our hourly limit to flush out our queue. It's re-assuring to know that in the event something goes wrong, their technical support team is accessible and able to take action.&lt;/p&gt;
      &lt;p&gt;
        If you have used or visited MailChimp, you know that their team prides themselves in building a well-designed product and Mandrill's design lives up to their high design standards. The Mandrill dashboard is fantastic. You're welcomed by a large chart of the metrics you care about (emails sent, delivered, bounced, rejected, opened, clicked-through etc.) as well as stats about how many emails you've sent this hour, what your quota is, and your app's email reputation. From there you can start drilling down into more detailed views. Here's the kicker, they have their own free iPhone and Android app as well:
        &lt;br /&gt;
        &lt;a href="http://itunes.apple.com/us/app/mandrill/id529882042?mt=8" target="_blank" title="Mandrill's iPhone App"&gt;
          &lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/mandrill_iphone.png" title="Mandrill iPhone Screenshot" /&gt;
        &lt;/a&gt;
      &lt;/p&gt;
      &lt;p&gt;I can't speak for the Android version, but iPhone's app design and UI is great. If you're like me, the more remote access you have to the vital stats of your app, the more you feel comfortable getting time away from your computer.&lt;/p&gt;
      &lt;p&gt;
        Lastly, their pricing is very affordable. If your website is small, there's a good chance you can integrate with Mandrill for free.
        &lt;br /&gt;
        &lt;a href="https://mandrill.com/pricing/" target="_blank" title="Mandrill's Pricing"&gt;&lt;/a&gt;
        &lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/mandril_pricing.png" title="Mandrill Homepage" /&gt;
      &lt;/p&gt;
      &lt;p&gt;When I noticed they had a free tier, I integrated Mandrill into my website's contact page, which took all of 2 minutes to configure. I plan on doing a follow-up post on how to install Mandrill for your Rails app as well as talk about some of things their API has to offer.&lt;/p&gt;
      &lt;p&gt;If you have any thoughts about Mandrill, please comment below!&lt;/p&gt;</content>
    </item>
    <item>
      <title>SEO: What Developers Need to Know</title>
      <link>http://dandemeyere.com/blog/seo-for-developers</link>
      <description>&lt;p&gt;
  SEO has amassed a bad reputation over the years. Is it legit? Is it snake oil? The truth lies somewhere in the middle. SEO &lt;em&gt;can&lt;/em&gt; improve the quantity and quality of organic traffic you receive, but it's not magic. The SEO 'specialists' who suggest building link farms, low-value landing pages, and other shady techniques designed to game
  &lt;a href="http://en.wikipedia.org/wiki/PageRank" target="_blank" title="Wikipedia Article on Google PageRank"&gt;PageRank&lt;/a&gt;
  (Google's ranking algorithm) are largely to blame for the negative SEO stigma, but SEO is real and it is valuable.
&lt;/p&gt;
&lt;p&gt;
  While there are legitimate SEO professionals who can add value to your website, no one person or department should be solely responsible for SEO.
  &lt;strong&gt;SEO should be a team-wide effort.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  Education, authenticity, and diligence should be at the core of this effort. Product, marketing, and development teams should all be educated on SEO and its best practices. It's up to these teams to ensure that the SEO techniques implemented are in the best interest of the user (authenticity) and that the SEO efforts are a continued focus during the construction of your website (diligence).
&lt;/p&gt;
&lt;p&gt;
  I recently presented my research and thoughts about SEO to our entire team at
  &lt;a href="http://www.thredup.com" target="_blank" title="thredUP - Used Kids Clothing Shop"&gt;thredUP&lt;/a&gt;
  . While the presentation (
  &lt;a href="https://github.com/dandemeyere/SEO-presentation" target="_blank" title="GitHub hosted SEO Presentation"&gt;click here to view it&lt;/a&gt;
  ) was tailored to a non-technical audience, my focus in this post will be on what developers need to know about SEO.
&lt;/p&gt;
&lt;h3&gt;Google PageRank&lt;/h3&gt;
&lt;p&gt;It's important to prioritize your development resources to yield the biggest SEO gains for the smallest amount of development effort possible (aka leverage). The first step is to determine your organic traffic breakdown by search engine source. If you're like us, Google is probably your #1 source (over 95% of thredUP's organic traffic comes from Google). Because of this, you should focus on optimizing towards Google's search result ranking algorithm PageRank.&lt;/p&gt;
&lt;p&gt;
  Regardless of whether you're a developer or not, I believe a basic understanding of
  &lt;a href="http://fast-fortress-9612.herokuapp.com/slides/3" target="_blank" title="Quick and Dirty Breakdown of how Search Engines Work"&gt;how search engines work&lt;/a&gt;
  is all that's required to be effective with your SEO efforts. Based on what
  &lt;a href="http://www.youtube.com/playlist?list=PL09B09220BA526712&amp;amp;feature=plcp" target="_blank" title="YouTube Videos from Google Employees about SEO Topics and Best Practices"&gt;Google has released themselves&lt;/a&gt;
  and from what other websites have tested and documented, there are widely known and accepted factors that play into Google's PageRank algorithm.
&lt;/p&gt;
&lt;h3&gt;Discovery&lt;/h3&gt;
&lt;p&gt;Google has to be aware of your website's existence and the content you offer before PageRank can evaluate and index it. Here are some ways to ensure Google finds your content:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    Manual submission - through Google Webmaster Tools, you can directly
    &lt;a href="https://www.google.com/webmasters/tools/submit-url?continue=/addurl" target="_blank" title="Submit Your Website to Google's Index"&gt;add your URL to Google's index&lt;/a&gt;
    .
  &lt;/li&gt;
  &lt;li&gt;Backlinks - when websites other than your own link to your website and its content, it will provide Google's crawlers another way to discover what your website has to offer.&lt;/li&gt;
  &lt;li&gt;Sitemaps - an HTML/XML file that lists every link you want Google (or your user) to know about on your website.&lt;/li&gt;
  &lt;li&gt;Structured linking - having an organized flow of links on your website allows Google's crawlers to more easily traverse your website and understand the relationships between the content on your website through your links.&lt;/li&gt;
  &lt;li&gt;
    Product feeds - if you're an e-commerce website, you can send Google your inventory along with meta information through their
    &lt;a href="http://www.google.com/merchants/basicsettings" target="_blank" title="Sign Up For Google Merchant Center"&gt;Google Merchant account center&lt;/a&gt;
    to help ensure what you're selling is showing up in Google search/shopping results.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SEO Elevators&lt;/h3&gt;
&lt;p&gt;There are certain things that will elevate you above others in Google search results. &lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Quality content - unique and genuine content trumps everything (ex: Wikipedia's quality of content is the reason why they are #1 in search results for almost everything). Google only cares if you're providing value to the user so if a user clicks on a search result and immediately clicks 'back' because the page wasn't helpful, Google knows and it will lower the ranking for the page.&lt;/li&gt;
  &lt;li&gt;Backlinks - the more websites that link to yours, the better your search rankings will be; however, the quality of the backlink is important as well. If a well-known and respected website links to your website, they are legitimizing your website through their own website's PageRank credibility. Conversely, if a small website that is relatively unknown links to your website, the benefits will not be substantial.&lt;/li&gt;
  &lt;li&gt;
    Best coding practices - being HTML compliant (ex:
    &lt;a href="https://gist.github.com/3161032" target="_blank" title="Example of HTML Image Alt Attribute"&gt;using alt attributes for images&lt;/a&gt;,
    &lt;a href="https://gist.github.com/3161040" target="_blank" title="Example of HTML Anchor Title Attribute"&gt;title tag text for links&lt;/a&gt;, etc.), using a hierarchy of HTML elements (h1 tag for page header, h2 tags for sub headers, etc.) and building descriptive URL schemes will further enhance Google's ability to add context to your website's content as well as signal to Google that you take care in the construction of your website.
  &lt;/li&gt;
  &lt;li&gt;Keywords - if you know the main keywords people are using in their Google search queries for your website, which you can view inside Google Analytics, you can then tailor your meta information content around those keywords to further emphasize their importance.&lt;/li&gt;
  &lt;li&gt;Speed - Google knows how long your page takes to load (Google Analytics) and they know users don't like to wait so the speed of your website will impact your ranking.&lt;/li&gt;
  &lt;li&gt;Usability - Does your website need JavaScript to work? Do you have too many ads? Is your layout conducive to a good user experience? Google's latest PageRank updates include the ability to load JavaScript and CSS to analyze the layout and usability of your website.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SEO Detractors&lt;/h3&gt;
&lt;p&gt;
  In general, if you don't follow the best practices mentioned in the list above, you're going to detract from your website's SEO potential. However, there are some things you can do that Google will penalize you for if they find out you're doing. If you want to see an example of how serious Google's penalties are,
  &lt;a href="http://fast-fortress-9612.herokuapp.com/slides/12" target="_blank" title="SEO Presentation Slide on Google PageRank Penalites"&gt;click here&lt;/a&gt;
  and once the slide loads, click 'i' on your keyboard.
&lt;/p&gt;
&lt;p&gt;To avoid Google PageRank penalties, stay away from these SEO tactics:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Keyword stuffing - if you embed too many keywords into your website's meta information HTML tags, Google will have a tougher time deciphering the signal from the noise. If you really abuse the use of keywords, Google can penalize you for intentionally trying to game the system.&lt;/li&gt;
  &lt;li&gt;Cloaking - putting scrape-able content on a page, but hiding it in from the user is a big Google 'no-no'. Google can load the CSS on your website so they know what content is visible to the user and what you're hiding from them.&lt;/li&gt;
  &lt;li&gt;Low-value pages - creating hollow pages that don't provide a lot of quality content to the user. This is also known as 'content farming'. Good for traffic, but bad for the user. If you create keyword landing pages, make sure you're providing value to the user.&lt;/li&gt;
  &lt;li&gt;Link farms - if you try to 'game' the number of backlinks your websites has by creating new websites that link back to your original website, Google will find out and it will hurt your page ranking.&lt;/li&gt;
  &lt;li&gt;Plagiarism - if you use other people's content, Google has ways of detecting who the real author is and they can issue page ranking penalties if you claim the content as your own.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SEO Summary&lt;/h3&gt;
&lt;p&gt;Users come first. Google's search engine is designed to give users the information they're looking for as fast as possible. Google doesn't care about your website, it's all about the user so make sure you're building new features for the user and not building features to attract more organic traffic. If you build a genuinely great product for your users and follow best SEO practices while building it, then you'll see results in your organic traffic. Here are some guidelines to follow why you're building your product: &lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;strong&gt;Define &amp;amp; communicate keywords&lt;/strong&gt;
    - determine what keywords perform best for your website and communicate them to your development team so they know what meta information to focus on (i.e. page titles, meta descriptions, alt text, etc.).
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;URL Naming&lt;/strong&gt;
     - take URL naming seriously! Grab a developer and bounce naming convention ideas off of them. When you change a URL at a later date, it hurts the page's SEO juice. 10,000 backlinks to one link is greater than 5,000 backlinks to two different links that end up at the same page. Think about it.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Quality content&lt;/strong&gt;
    - the copy/content on a page matters. Copy and pasting is the devil for SEO. Be creative, take your time, and make it count.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Sitemaps&lt;/strong&gt;
     - are you adding a new feature? Make sure you add the appropriate links to the HTML &amp;amp; XML sitemap. Make sure you have FAQ content in place.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Don't be lazy&lt;/strong&gt;
     - have an image? Make sure there's alt text. Have a link? Make sure there's title text. Use the right elements (h1, h2, p, etc.).
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Think hard on the meta&lt;/strong&gt;
     - when you place the alt text, make it meaningful. If you care, you'll take the time to do it right.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;JavaScript beware&lt;/strong&gt;
     - if a link requires jQuery to work, you're doing it wrong. If a bot can't get from page to page, you're doing it wrong. Disable JavaScript and load your website, the content you want indexed better still be there.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Plan from the beginning&lt;/strong&gt;
    - before you start coding, think about SEO. SEO can dictate execution (i.e. don't bring content in via AJAX).
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Natural feature flows&lt;/strong&gt;
     - does the feature flow intuitively? Is it organized? Is there a hierarchy? Can you a build a directory page for it?
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Don't be shady!&lt;/strong&gt;
    - Google doesn't like it. Developers don't like it. It feels dirty-all-over to code something that does not benefit the user and has negative, ulterior motives.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I missed anything or you disagree with my conclusions, please comment below.&lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/seo-for-developers</guid>
      <pubDate>Sun, 22 Jul 2012 02:25:00 -0700</pubDate>
      <content>&lt;p&gt;
  SEO has amassed a bad reputation over the years. Is it legit? Is it snake oil? The truth lies somewhere in the middle. SEO &lt;em&gt;can&lt;/em&gt; improve the quantity and quality of organic traffic you receive, but it's not magic. The SEO 'specialists' who suggest building link farms, low-value landing pages, and other shady techniques designed to game
  &lt;a href="http://en.wikipedia.org/wiki/PageRank" target="_blank" title="Wikipedia Article on Google PageRank"&gt;PageRank&lt;/a&gt;
  (Google's ranking algorithm) are largely to blame for the negative SEO stigma, but SEO is real and it is valuable.
&lt;/p&gt;
&lt;p&gt;
  While there are legitimate SEO professionals who can add value to your website, no one person or department should be solely responsible for SEO.
  &lt;strong&gt;SEO should be a team-wide effort.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  Education, authenticity, and diligence should be at the core of this effort. Product, marketing, and development teams should all be educated on SEO and its best practices. It's up to these teams to ensure that the SEO techniques implemented are in the best interest of the user (authenticity) and that the SEO efforts are a continued focus during the construction of your website (diligence).
&lt;/p&gt;
&lt;p&gt;
  I recently presented my research and thoughts about SEO to our entire team at
  &lt;a href="http://www.thredup.com" target="_blank" title="thredUP - Used Kids Clothing Shop"&gt;thredUP&lt;/a&gt;
  . While the presentation (
  &lt;a href="https://github.com/dandemeyere/SEO-presentation" target="_blank" title="GitHub hosted SEO Presentation"&gt;click here to view it&lt;/a&gt;
  ) was tailored to a non-technical audience, my focus in this post will be on what developers need to know about SEO.
&lt;/p&gt;
&lt;h3&gt;Google PageRank&lt;/h3&gt;
&lt;p&gt;It's important to prioritize your development resources to yield the biggest SEO gains for the smallest amount of development effort possible (aka leverage). The first step is to determine your organic traffic breakdown by search engine source. If you're like us, Google is probably your #1 source (over 95% of thredUP's organic traffic comes from Google). Because of this, you should focus on optimizing towards Google's search result ranking algorithm PageRank.&lt;/p&gt;
&lt;p&gt;
  Regardless of whether you're a developer or not, I believe a basic understanding of
  &lt;a href="http://fast-fortress-9612.herokuapp.com/slides/3" target="_blank" title="Quick and Dirty Breakdown of how Search Engines Work"&gt;how search engines work&lt;/a&gt;
  is all that's required to be effective with your SEO efforts. Based on what
  &lt;a href="http://www.youtube.com/playlist?list=PL09B09220BA526712&amp;amp;feature=plcp" target="_blank" title="YouTube Videos from Google Employees about SEO Topics and Best Practices"&gt;Google has released themselves&lt;/a&gt;
  and from what other websites have tested and documented, there are widely known and accepted factors that play into Google's PageRank algorithm.
&lt;/p&gt;
&lt;h3&gt;Discovery&lt;/h3&gt;
&lt;p&gt;Google has to be aware of your website's existence and the content you offer before PageRank can evaluate and index it. Here are some ways to ensure Google finds your content:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    Manual submission - through Google Webmaster Tools, you can directly
    &lt;a href="https://www.google.com/webmasters/tools/submit-url?continue=/addurl" target="_blank" title="Submit Your Website to Google's Index"&gt;add your URL to Google's index&lt;/a&gt;
    .
  &lt;/li&gt;
  &lt;li&gt;Backlinks - when websites other than your own link to your website and its content, it will provide Google's crawlers another way to discover what your website has to offer.&lt;/li&gt;
  &lt;li&gt;Sitemaps - an HTML/XML file that lists every link you want Google (or your user) to know about on your website.&lt;/li&gt;
  &lt;li&gt;Structured linking - having an organized flow of links on your website allows Google's crawlers to more easily traverse your website and understand the relationships between the content on your website through your links.&lt;/li&gt;
  &lt;li&gt;
    Product feeds - if you're an e-commerce website, you can send Google your inventory along with meta information through their
    &lt;a href="http://www.google.com/merchants/basicsettings" target="_blank" title="Sign Up For Google Merchant Center"&gt;Google Merchant account center&lt;/a&gt;
    to help ensure what you're selling is showing up in Google search/shopping results.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SEO Elevators&lt;/h3&gt;
&lt;p&gt;There are certain things that will elevate you above others in Google search results. &lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Quality content - unique and genuine content trumps everything (ex: Wikipedia's quality of content is the reason why they are #1 in search results for almost everything). Google only cares if you're providing value to the user so if a user clicks on a search result and immediately clicks 'back' because the page wasn't helpful, Google knows and it will lower the ranking for the page.&lt;/li&gt;
  &lt;li&gt;Backlinks - the more websites that link to yours, the better your search rankings will be; however, the quality of the backlink is important as well. If a well-known and respected website links to your website, they are legitimizing your website through their own website's PageRank credibility. Conversely, if a small website that is relatively unknown links to your website, the benefits will not be substantial.&lt;/li&gt;
  &lt;li&gt;
    Best coding practices - being HTML compliant (ex:
    &lt;a href="https://gist.github.com/3161032" target="_blank" title="Example of HTML Image Alt Attribute"&gt;using alt attributes for images&lt;/a&gt;,
    &lt;a href="https://gist.github.com/3161040" target="_blank" title="Example of HTML Anchor Title Attribute"&gt;title tag text for links&lt;/a&gt;, etc.), using a hierarchy of HTML elements (h1 tag for page header, h2 tags for sub headers, etc.) and building descriptive URL schemes will further enhance Google's ability to add context to your website's content as well as signal to Google that you take care in the construction of your website.
  &lt;/li&gt;
  &lt;li&gt;Keywords - if you know the main keywords people are using in their Google search queries for your website, which you can view inside Google Analytics, you can then tailor your meta information content around those keywords to further emphasize their importance.&lt;/li&gt;
  &lt;li&gt;Speed - Google knows how long your page takes to load (Google Analytics) and they know users don't like to wait so the speed of your website will impact your ranking.&lt;/li&gt;
  &lt;li&gt;Usability - Does your website need JavaScript to work? Do you have too many ads? Is your layout conducive to a good user experience? Google's latest PageRank updates include the ability to load JavaScript and CSS to analyze the layout and usability of your website.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SEO Detractors&lt;/h3&gt;
&lt;p&gt;
  In general, if you don't follow the best practices mentioned in the list above, you're going to detract from your website's SEO potential. However, there are some things you can do that Google will penalize you for if they find out you're doing. If you want to see an example of how serious Google's penalties are,
  &lt;a href="http://fast-fortress-9612.herokuapp.com/slides/12" target="_blank" title="SEO Presentation Slide on Google PageRank Penalites"&gt;click here&lt;/a&gt;
  and once the slide loads, click 'i' on your keyboard.
&lt;/p&gt;
&lt;p&gt;To avoid Google PageRank penalties, stay away from these SEO tactics:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Keyword stuffing - if you embed too many keywords into your website's meta information HTML tags, Google will have a tougher time deciphering the signal from the noise. If you really abuse the use of keywords, Google can penalize you for intentionally trying to game the system.&lt;/li&gt;
  &lt;li&gt;Cloaking - putting scrape-able content on a page, but hiding it in from the user is a big Google 'no-no'. Google can load the CSS on your website so they know what content is visible to the user and what you're hiding from them.&lt;/li&gt;
  &lt;li&gt;Low-value pages - creating hollow pages that don't provide a lot of quality content to the user. This is also known as 'content farming'. Good for traffic, but bad for the user. If you create keyword landing pages, make sure you're providing value to the user.&lt;/li&gt;
  &lt;li&gt;Link farms - if you try to 'game' the number of backlinks your websites has by creating new websites that link back to your original website, Google will find out and it will hurt your page ranking.&lt;/li&gt;
  &lt;li&gt;Plagiarism - if you use other people's content, Google has ways of detecting who the real author is and they can issue page ranking penalties if you claim the content as your own.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SEO Summary&lt;/h3&gt;
&lt;p&gt;Users come first. Google's search engine is designed to give users the information they're looking for as fast as possible. Google doesn't care about your website, it's all about the user so make sure you're building new features for the user and not building features to attract more organic traffic. If you build a genuinely great product for your users and follow best SEO practices while building it, then you'll see results in your organic traffic. Here are some guidelines to follow why you're building your product: &lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;strong&gt;Define &amp;amp; communicate keywords&lt;/strong&gt;
    - determine what keywords perform best for your website and communicate them to your development team so they know what meta information to focus on (i.e. page titles, meta descriptions, alt text, etc.).
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;URL Naming&lt;/strong&gt;
     - take URL naming seriously! Grab a developer and bounce naming convention ideas off of them. When you change a URL at a later date, it hurts the page's SEO juice. 10,000 backlinks to one link is greater than 5,000 backlinks to two different links that end up at the same page. Think about it.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Quality content&lt;/strong&gt;
    - the copy/content on a page matters. Copy and pasting is the devil for SEO. Be creative, take your time, and make it count.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Sitemaps&lt;/strong&gt;
     - are you adding a new feature? Make sure you add the appropriate links to the HTML &amp;amp; XML sitemap. Make sure you have FAQ content in place.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Don't be lazy&lt;/strong&gt;
     - have an image? Make sure there's alt text. Have a link? Make sure there's title text. Use the right elements (h1, h2, p, etc.).
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Think hard on the meta&lt;/strong&gt;
     - when you place the alt text, make it meaningful. If you care, you'll take the time to do it right.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;JavaScript beware&lt;/strong&gt;
     - if a link requires jQuery to work, you're doing it wrong. If a bot can't get from page to page, you're doing it wrong. Disable JavaScript and load your website, the content you want indexed better still be there.
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Plan from the beginning&lt;/strong&gt;
    - before you start coding, think about SEO. SEO can dictate execution (i.e. don't bring content in via AJAX).
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Natural feature flows&lt;/strong&gt;
     - does the feature flow intuitively? Is it organized? Is there a hierarchy? Can you a build a directory page for it?
  &lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Don't be shady!&lt;/strong&gt;
    - Google doesn't like it. Developers don't like it. It feels dirty-all-over to code something that does not benefit the user and has negative, ulterior motives.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I missed anything or you disagree with my conclusions, please comment below.&lt;/p&gt;</content>
    </item>
    <item>
      <title>Upgrading Rails from 3.0 to 3.1: What You Need to Know</title>
      <link>http://dandemeyere.com/blog/upgrading-to-rails-3-1</link>
      <description>&lt;p&gt;We upgraded the &lt;a href="http://www.thredup.com" title="thredUP.com" target="_blank"&gt;thredUP&lt;/a&gt; app from Rails 3.0 to Rails 3.1 this past week. On the day we deployed the upgrade, our test suite was green and everything looked solid locally and on our staging server, but out of sheer paranoia I decided to take one of our front-end servers off of the load balancer and deploy to it so I could poke around on the Rails production environment....and then a bit of chaos ensued.&lt;/p&gt;

&lt;p&gt;There are some aspects of a production environment that can't be replicated in your test suite and can't be invoked locally. A good example of this is SSL. Did you know that `ssl_required` was deprecated in Rails 3.1? I didn't (&lt;a href="https://gist.github.com/2974579" title="Rails 3.1 SSL Requirement Gist" target="_blank"&gt;here's the solution btw&lt;/a&gt;). Then there are production-only gems to worry about (ex: monitoring services). &lt;a href="https://github.com/newrelic/rpm" title="New Relic Rails Gem" target="_blank"&gt;New Relic's gem&lt;/a&gt; required a bump for Rails 3.1. And by required a bump, I mean the gem caused the entire app to crash with a cryptic error message. Fun!&lt;/p&gt;

&lt;p&gt;You're probably thinking that this upgrade lacked preparation. Quite the contrary. Before I started the upgrade, I read &lt;a href="http://davidjrice.co.uk/2011/05/25/how-to-upgrade-a-rails-application-to-version-3-1-0.html" title="Rails 3.1 Upgrade Guide" target="_blank"&gt;guide&lt;/a&gt; after &lt;a href="http://webtempest.com/upgrade-rails-3-to-3-1/" title="Rails 3.1 Upgrade Guide" target="_blank"&gt;guide&lt;/a&gt; about upgrading to Rails 3.1. Because we wanted to upgrade in phases, I wasn't interested in the asset pipeline requirements, but it seemed as though that was the only thing every guide was focusing on. What the guides weren't focusing on were all the gems that would have to bumped (and their dependencies) and what the ramifications of those bumps would be. ActiveRecord, Cucumber, and PayPalNVP were a couple gems in particular that had noticeable changes that deserved some love in the upgrade guides. So that's what this post is, some love for the not-so-obvious deprecations that should give you clearer expectations of what you'll be running into when upgrading to Rails 3.1.&lt;/p&gt;

&lt;h3&gt;Active Record&lt;/h3&gt;
&lt;p&gt;Condition hash syntax is on it's way out. It's been fully deprecated from named scopes and the `find()` method. &lt;br /&gt;
  &lt;script src='https://gist.github.com/2975797.js'&gt;&lt;/script&gt;
  
&lt;/p&gt;
&lt;p&gt;Another big gotcha is 'include_root_in_json' being defaulted to false for every model now. Here's the difference: &lt;br /&gt;
&lt;script src='https://gist.github.com/2981186.js'&gt;&lt;/script&gt;

&lt;/p&gt;
&lt;p&gt;Small difference between the two, but if all your JSON responses previously had the root included and you have external apps (iPhone, Android, etc.) relying on your app's internal RESTful API (like we do), then it's a significant difference as it's possible all those API endpoints will have to changed or the apps will break. So how to change this? Below I'll demonstrate how to set an app-wide default and then how to override the setting in individual models. &lt;br /&gt;
&lt;script src='https://gist.github.com/2981244.js'&gt;&lt;/script&gt;

&lt;/p&gt; 

&lt;h3&gt;Gem Bumps&lt;/h3&gt;
&lt;p&gt;Almost every Rails app relies on a myriad of gems. Including our development and test environments, thredUP uses over 50 external gems and a handful of our own private gems we've created over time. When we upgraded from Rails 3.0 to Rails 3.1, there were some notable gems that required version bumps. &lt;br /&gt;
  &lt;script src='https://gist.github.com/2981372.js'&gt;&lt;/script&gt;
  
&lt;/p&gt;
&lt;p&gt;There are some big boys in there (ex: mysql2 is our MySQL adapter). If you use any of the above in your app, which I'm betting you do, make sure to take note of their version bumps&lt;/p&gt;
&lt;h3&gt;PayPalNVP&lt;/h3&gt;
&lt;p&gt;If you use the &lt;a href="https://github.com/solisoft/paypal_nvp" title="PayPal NVP Gem" target="_blank"&gt;PayPal NVP gem&lt;/a&gt;, expect to make some changes. The biggest for us was that the PayPal NVP API requires all authentication upon object instantiation. Example: &lt;br /&gt;
  &lt;script src='https://gist.github.com/2981410.js'&gt;&lt;/script&gt;
  
&lt;/p&gt;
&lt;p&gt;If you do full 3rd-party API mocking in your test coverage, you could see how this change would be problematic.&lt;/p&gt;

&lt;p&gt;Lastly, make sure to read the &lt;a href="http://guides.rubyonrails.org/3_1_release_notes.html" title="Rails 3.1 Release Notes" target="_blank"&gt;Rails 3.1 release notes&lt;/a&gt; or &lt;a href="https://gist.github.com/958283" title="Changes in Rails 3.1" target="_blank"&gt;Ryan Bate's gist of 3.1 RC4 changes&lt;/a&gt;. That's where some of the standard Rails-only deprecations will be. The biggest one to note - all forms (or any Rails view helper that results in HTML being outputted into the source) requires a `=` instead of `-`. It's a simple change, but if you use a hyphen on accident, nothing is outputted to source and it can be quite confusing to debug since no errors will occur and nothing is in the HTML.&lt;br /&gt;
&lt;script src='https://gist.github.com/2966726.js'&gt;&lt;/script&gt;
  &lt;/p&gt;
  &lt;p&gt;If you came across any unique errors when you upgraded your app to Rails 3.1, please mention them below in the comments and I'll update the post afterwards to include them.&lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/upgrading-to-rails-3-1</guid>
      <pubDate>Mon, 25 Jun 2012 06:42:00 -0700</pubDate>
      <content>&lt;p&gt;We upgraded the &lt;a href="http://www.thredup.com" title="thredUP.com" target="_blank"&gt;thredUP&lt;/a&gt; app from Rails 3.0 to Rails 3.1 this past week. On the day we deployed the upgrade, our test suite was green and everything looked solid locally and on our staging server, but out of sheer paranoia I decided to take one of our front-end servers off of the load balancer and deploy to it so I could poke around on the Rails production environment....and then a bit of chaos ensued.&lt;/p&gt;

&lt;p&gt;There are some aspects of a production environment that can't be replicated in your test suite and can't be invoked locally. A good example of this is SSL. Did you know that `ssl_required` was deprecated in Rails 3.1? I didn't (&lt;a href="https://gist.github.com/2974579" title="Rails 3.1 SSL Requirement Gist" target="_blank"&gt;here's the solution btw&lt;/a&gt;). Then there are production-only gems to worry about (ex: monitoring services). &lt;a href="https://github.com/newrelic/rpm" title="New Relic Rails Gem" target="_blank"&gt;New Relic's gem&lt;/a&gt; required a bump for Rails 3.1. And by required a bump, I mean the gem caused the entire app to crash with a cryptic error message. Fun!&lt;/p&gt;

&lt;p&gt;You're probably thinking that this upgrade lacked preparation. Quite the contrary. Before I started the upgrade, I read &lt;a href="http://davidjrice.co.uk/2011/05/25/how-to-upgrade-a-rails-application-to-version-3-1-0.html" title="Rails 3.1 Upgrade Guide" target="_blank"&gt;guide&lt;/a&gt; after &lt;a href="http://webtempest.com/upgrade-rails-3-to-3-1/" title="Rails 3.1 Upgrade Guide" target="_blank"&gt;guide&lt;/a&gt; about upgrading to Rails 3.1. Because we wanted to upgrade in phases, I wasn't interested in the asset pipeline requirements, but it seemed as though that was the only thing every guide was focusing on. What the guides weren't focusing on were all the gems that would have to bumped (and their dependencies) and what the ramifications of those bumps would be. ActiveRecord, Cucumber, and PayPalNVP were a couple gems in particular that had noticeable changes that deserved some love in the upgrade guides. So that's what this post is, some love for the not-so-obvious deprecations that should give you clearer expectations of what you'll be running into when upgrading to Rails 3.1.&lt;/p&gt;

&lt;h3&gt;Active Record&lt;/h3&gt;
&lt;p&gt;Condition hash syntax is on it's way out. It's been fully deprecated from named scopes and the `find()` method. &lt;br /&gt;
  &lt;script src='https://gist.github.com/2975797.js'&gt;&lt;/script&gt;
  
&lt;/p&gt;
&lt;p&gt;Another big gotcha is 'include_root_in_json' being defaulted to false for every model now. Here's the difference: &lt;br /&gt;
&lt;script src='https://gist.github.com/2981186.js'&gt;&lt;/script&gt;

&lt;/p&gt;
&lt;p&gt;Small difference between the two, but if all your JSON responses previously had the root included and you have external apps (iPhone, Android, etc.) relying on your app's internal RESTful API (like we do), then it's a significant difference as it's possible all those API endpoints will have to changed or the apps will break. So how to change this? Below I'll demonstrate how to set an app-wide default and then how to override the setting in individual models. &lt;br /&gt;
&lt;script src='https://gist.github.com/2981244.js'&gt;&lt;/script&gt;

&lt;/p&gt; 

&lt;h3&gt;Gem Bumps&lt;/h3&gt;
&lt;p&gt;Almost every Rails app relies on a myriad of gems. Including our development and test environments, thredUP uses over 50 external gems and a handful of our own private gems we've created over time. When we upgraded from Rails 3.0 to Rails 3.1, there were some notable gems that required version bumps. &lt;br /&gt;
  &lt;script src='https://gist.github.com/2981372.js'&gt;&lt;/script&gt;
  
&lt;/p&gt;
&lt;p&gt;There are some big boys in there (ex: mysql2 is our MySQL adapter). If you use any of the above in your app, which I'm betting you do, make sure to take note of their version bumps&lt;/p&gt;
&lt;h3&gt;PayPalNVP&lt;/h3&gt;
&lt;p&gt;If you use the &lt;a href="https://github.com/solisoft/paypal_nvp" title="PayPal NVP Gem" target="_blank"&gt;PayPal NVP gem&lt;/a&gt;, expect to make some changes. The biggest for us was that the PayPal NVP API requires all authentication upon object instantiation. Example: &lt;br /&gt;
  &lt;script src='https://gist.github.com/2981410.js'&gt;&lt;/script&gt;
  
&lt;/p&gt;
&lt;p&gt;If you do full 3rd-party API mocking in your test coverage, you could see how this change would be problematic.&lt;/p&gt;

&lt;p&gt;Lastly, make sure to read the &lt;a href="http://guides.rubyonrails.org/3_1_release_notes.html" title="Rails 3.1 Release Notes" target="_blank"&gt;Rails 3.1 release notes&lt;/a&gt; or &lt;a href="https://gist.github.com/958283" title="Changes in Rails 3.1" target="_blank"&gt;Ryan Bate's gist of 3.1 RC4 changes&lt;/a&gt;. That's where some of the standard Rails-only deprecations will be. The biggest one to note - all forms (or any Rails view helper that results in HTML being outputted into the source) requires a `=` instead of `-`. It's a simple change, but if you use a hyphen on accident, nothing is outputted to source and it can be quite confusing to debug since no errors will occur and nothing is in the HTML.&lt;br /&gt;
&lt;script src='https://gist.github.com/2966726.js'&gt;&lt;/script&gt;
  &lt;/p&gt;
  &lt;p&gt;If you came across any unique errors when you upgraded your app to Rails 3.1, please mention them below in the comments and I'll update the post afterwards to include them.&lt;/p&gt;</content>
    </item>
    <item>
      <title>Refreshing Web Design Trends </title>
      <link>http://dandemeyere.com/blog/refreshing-web-design-trends</link>
      <description>&lt;p&gt;In the past year, the post 2.0 web design era has really come into its own. &lt;a href="http://labs.thredup.com/on-the-cusp-where-web-designui-is-headed" title="Where Web Design is Headed" target="_blank"&gt;I wrote about the start of this&lt;/a&gt; when web designers first started to embrace HTML5 and what it has to offer, but the time has finally come when over-the-top Flash websites, &lt;a href="http://jimcarrey.com/" title="Jim Carrey Website" target="_blank"&gt;such as this one&lt;/a&gt;, are no longer the standard for those that are pushing the envelope for creative web designs. &lt;/p&gt;
&lt;p&gt;Here are 4 websites who have utilized HTML/jQuery and creativity to build refreshing designs:&lt;/p&gt;


&lt;h3&gt;&lt;a href="http://slaveryfootprint.org/" title="Slavery Foot Print Informational Website" target="_blank"&gt;SlaveryFootPrint.org&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/slaveryfootprint.png" title="Slavery Foot Print Informational Website" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/slaveryfootprint_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Go to &lt;a href="http://slaveryfootprint.org/" title="Slavery Foot Print Informational Website" target="_blank"&gt;SlaveryFootPrint.org&lt;/a&gt;. It's ok, I'll wait for you to actually click the link. Once the page loads, you'll notice you have two options. Click the first one titled 'What? Slaves work for me?'. Now start scrolling. Killer, right? With a little bit of jQuery and some clever CSS, this website is re-inventing the way to deliver information to users. Lines of text are brought in at the same pace as your scrolling, allowing you to control how quickly you want to read their text. On top of this, they have different graphics pushing the text into place to make the reading experience fun. &lt;/p&gt;

&lt;h3&gt;&lt;a href="http://jamesanderson613.com/" title="James Anderson Website" target="_blank"&gt;JamesAnderson613.com&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/jamesanderson613.png" title="James Anderson's Personal Website" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/jamesanderson613_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;A lot of freedom is granted when designing a personal website. It can say anything and look as wild as you want it to look. Shockingly, one of my favorites is not a designer or a developer's website - it belongs to a cricket player. &lt;a href="http://jamesanderson613.com/" title="James Anderson Website" target="_blank"&gt;James Anderson's website&lt;/a&gt; is awesome and it's showing off one of my favorite trends: making numbers sexy on the web.&lt;/p&gt;
&lt;p&gt;HTML5, specifically the addition of &lt;a href="http://www.w3schools.com/html5/html5_canvas.asp" title="HTML Canvas" target="_blank"&gt;Canvas&lt;/a&gt; and &lt;a href="http://www.w3schools.com/html5/html5_svg.asp" title="HTML SVG" target="_blank"&gt;SVG&lt;/a&gt;, has given designers free reign to design graphs, charts, and other data visualizations without having to worry about how they will be built. Thanks to JavaScript libraries like &lt;a href="http://d3js.org/" title="D3.js Homepage" target="_blank"&gt;D3.js&lt;/a&gt; and &lt;a href="http://www.highcharts.com/" title="Highcharts.js Homepage" target="_blank"&gt;Highcharts.js&lt;/a&gt;, developers no longer have to worry about Flash or any other antiquated plug-in for interactive visuals. And while D3/Highcharts are two of my favorites, there are plenty of other emerging solutions. &lt;/p&gt;
&lt;p&gt;Tangent: if you're someone who is looking to make your own website, I strongly recommend you look over this &lt;a href="http://www.quora.com/What-is-the-best-personal-webpage-you-know-of" title="Quora - Awesome personal websites" target="_blank"&gt;Quora list of best personal websites on the web&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://diy.org/" title="DIY - A Community of Kids that Make" target="_blank"&gt;DIY.org&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/diy.png" title="DIY - A Community of Kids that Make" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/diy_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://diy.org/" title="DIY - A Community of Kids that Make" target="_blank"&gt;DIY.org&lt;/a&gt; is a very cool website. It's a kids website that highlights &lt;a href="https://diy.org/explore" title="DIY Showcase" target="_blank"&gt;really cool things that kids and parents make&lt;/a&gt; and it's also showcasing the last trend I'll mention in this post that I'm excited about - high powered web graphics. In the past, image sizes were always a huge cause for concern because of bandwidth limitations and costs. As broadband internet becomes more prevalent and static asset storage (ex: AWS S3) becomes more and more affordable, image sizes become less and less of a concern.&lt;/p&gt;
&lt;p&gt;When you go to the DIY homepage, you're presented with a stunning graphic. After a couple of seconds, the text overlays disappears and you're able to grab the graphic and move it to explore (with a nice easing effect to simulate gliding). The entire graphic is larger than 3000x3000 pixels, but through some clever coding the actual images that compromise the entire graphic are 35 387x387 image tiles. I would also bet good money that only the necessary tiles are loaded until you try and explore surrounding tiles. The reason why I think this will become a web trend is because this same high-quality graphic tiling technology could be used for a web-based video game built on top of HTML5. A 'level' in the game could be hundreds of thousands of pixels, but when the graphics are loaded only when needed, it could be realistically done with ease.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.dangersoffracking.com/" title="The Dangers of Hydraulic Fracturing" target="_blank"&gt;DangersOfFracking.com&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/dangersoffracking.png" title="DIY - The Dangers of Hydraulic Fracturing" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/dangersoffracking_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dangersoffracking.com/" title="The Dangers of Hydraulic Fracturing" target="_blank"&gt;This last website&lt;/a&gt; is a combination of all three trends I mentioned: re-inventing the way to deliver information, beautiful metric visuals, and high powered web graphics. By utilizing all three, the creator of this website was able to bring to light a very serious topic (Hydraulic Fracturing) and deliver the information on the topic to you in such a compelling way that you want to learn. You need to keep scrolling. They have gamified the process to digest information on the web. It's brilliant.&lt;/p&gt; </description>
      <guid>http://dandemeyere.com/blog/refreshing-web-design-trends</guid>
      <pubDate>Mon, 18 Jun 2012 10:49:00 -0700</pubDate>
      <content>&lt;p&gt;In the past year, the post 2.0 web design era has really come into its own. &lt;a href="http://labs.thredup.com/on-the-cusp-where-web-designui-is-headed" title="Where Web Design is Headed" target="_blank"&gt;I wrote about the start of this&lt;/a&gt; when web designers first started to embrace HTML5 and what it has to offer, but the time has finally come when over-the-top Flash websites, &lt;a href="http://jimcarrey.com/" title="Jim Carrey Website" target="_blank"&gt;such as this one&lt;/a&gt;, are no longer the standard for those that are pushing the envelope for creative web designs. &lt;/p&gt;
&lt;p&gt;Here are 4 websites who have utilized HTML/jQuery and creativity to build refreshing designs:&lt;/p&gt;


&lt;h3&gt;&lt;a href="http://slaveryfootprint.org/" title="Slavery Foot Print Informational Website" target="_blank"&gt;SlaveryFootPrint.org&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/slaveryfootprint.png" title="Slavery Foot Print Informational Website" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/slaveryfootprint_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Go to &lt;a href="http://slaveryfootprint.org/" title="Slavery Foot Print Informational Website" target="_blank"&gt;SlaveryFootPrint.org&lt;/a&gt;. It's ok, I'll wait for you to actually click the link. Once the page loads, you'll notice you have two options. Click the first one titled 'What? Slaves work for me?'. Now start scrolling. Killer, right? With a little bit of jQuery and some clever CSS, this website is re-inventing the way to deliver information to users. Lines of text are brought in at the same pace as your scrolling, allowing you to control how quickly you want to read their text. On top of this, they have different graphics pushing the text into place to make the reading experience fun. &lt;/p&gt;

&lt;h3&gt;&lt;a href="http://jamesanderson613.com/" title="James Anderson Website" target="_blank"&gt;JamesAnderson613.com&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/jamesanderson613.png" title="James Anderson's Personal Website" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/jamesanderson613_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;A lot of freedom is granted when designing a personal website. It can say anything and look as wild as you want it to look. Shockingly, one of my favorites is not a designer or a developer's website - it belongs to a cricket player. &lt;a href="http://jamesanderson613.com/" title="James Anderson Website" target="_blank"&gt;James Anderson's website&lt;/a&gt; is awesome and it's showing off one of my favorite trends: making numbers sexy on the web.&lt;/p&gt;
&lt;p&gt;HTML5, specifically the addition of &lt;a href="http://www.w3schools.com/html5/html5_canvas.asp" title="HTML Canvas" target="_blank"&gt;Canvas&lt;/a&gt; and &lt;a href="http://www.w3schools.com/html5/html5_svg.asp" title="HTML SVG" target="_blank"&gt;SVG&lt;/a&gt;, has given designers free reign to design graphs, charts, and other data visualizations without having to worry about how they will be built. Thanks to JavaScript libraries like &lt;a href="http://d3js.org/" title="D3.js Homepage" target="_blank"&gt;D3.js&lt;/a&gt; and &lt;a href="http://www.highcharts.com/" title="Highcharts.js Homepage" target="_blank"&gt;Highcharts.js&lt;/a&gt;, developers no longer have to worry about Flash or any other antiquated plug-in for interactive visuals. And while D3/Highcharts are two of my favorites, there are plenty of other emerging solutions. &lt;/p&gt;
&lt;p&gt;Tangent: if you're someone who is looking to make your own website, I strongly recommend you look over this &lt;a href="http://www.quora.com/What-is-the-best-personal-webpage-you-know-of" title="Quora - Awesome personal websites" target="_blank"&gt;Quora list of best personal websites on the web&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://diy.org/" title="DIY - A Community of Kids that Make" target="_blank"&gt;DIY.org&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/diy.png" title="DIY - A Community of Kids that Make" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/diy_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://diy.org/" title="DIY - A Community of Kids that Make" target="_blank"&gt;DIY.org&lt;/a&gt; is a very cool website. It's a kids website that highlights &lt;a href="https://diy.org/explore" title="DIY Showcase" target="_blank"&gt;really cool things that kids and parents make&lt;/a&gt; and it's also showcasing the last trend I'll mention in this post that I'm excited about - high powered web graphics. In the past, image sizes were always a huge cause for concern because of bandwidth limitations and costs. As broadband internet becomes more prevalent and static asset storage (ex: AWS S3) becomes more and more affordable, image sizes become less and less of a concern.&lt;/p&gt;
&lt;p&gt;When you go to the DIY homepage, you're presented with a stunning graphic. After a couple of seconds, the text overlays disappears and you're able to grab the graphic and move it to explore (with a nice easing effect to simulate gliding). The entire graphic is larger than 3000x3000 pixels, but through some clever coding the actual images that compromise the entire graphic are 35 387x387 image tiles. I would also bet good money that only the necessary tiles are loaded until you try and explore surrounding tiles. The reason why I think this will become a web trend is because this same high-quality graphic tiling technology could be used for a web-based video game built on top of HTML5. A 'level' in the game could be hundreds of thousands of pixels, but when the graphics are loaded only when needed, it could be realistically done with ease.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.dangersoffracking.com/" title="The Dangers of Hydraulic Fracturing" target="_blank"&gt;DangersOfFracking.com&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/dandemeyere_production/2012/blog/dangersoffracking.png" title="DIY - The Dangers of Hydraulic Fracturing" target="_blank" class="shadowbox"&gt;&lt;img class="white-border" src="https://s3.amazonaws.com/dandemeyere_production/2012/blog/dangersoffracking_small.png" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dangersoffracking.com/" title="The Dangers of Hydraulic Fracturing" target="_blank"&gt;This last website&lt;/a&gt; is a combination of all three trends I mentioned: re-inventing the way to deliver information, beautiful metric visuals, and high powered web graphics. By utilizing all three, the creator of this website was able to bring to light a very serious topic (Hydraulic Fracturing) and deliver the information on the topic to you in such a compelling way that you want to learn. You need to keep scrolling. They have gamified the process to digest information on the web. It's brilliant.&lt;/p&gt; </content>
    </item>
    <item>
      <title>How Employee Equity Works </title>
      <link>http://dandemeyere.com/blog/employee-equity</link>
      <description>&lt;p&gt;Employee equity has always been a nebulous topic for me. Every time I thought I understood how it worked, I would read or hear something that made me question my understanding. Thank goodness people like &lt;a href="http://www.avc.com/a_vc/about.html" target="_blank"&gt;Fred Wilson&lt;/a&gt; exist. He is a &lt;a href="http://www.usv.com/team/" target="_blank"&gt;venture capitalist&lt;/a&gt;, &lt;a href="http://www.avc.com/"&gt;blogger&lt;/a&gt;, and a budding professor. The video I embedded below is Fred Wilson explaining Employee Equity to a classroom full of future entrepreneurs. The video is 70 minutes long and is very thorough so if you want an expert in the field to walk you through how Employee Equity works (and some of the tax implications), I urge you to watch the entire video.&lt;/p&gt;
&lt;p&gt; If you're short on time and you're an employee with options, the first 30 minutes will suffice for a basic understanding. If you're an entrepreneur, you'll still want to watch the last 40 minutes of the talk since it's more about strategy of how to structure your company's employee equity.&lt;/p&gt;
&lt;p&gt;&lt;iframe src="http://cdn.livestream.com/hdembed/index.html?width=560&amp;amp;height=315&amp;amp;play_url=http://api.new.livestream.com/accounts/509100/events/671289/videos/490550.smil&amp;amp;qualities_bitrate=678000,1756000,198000&amp;amp;qualities_height=432,480,270&amp;amp;thumbnail_url=http://img.new.livestream.com/events/00000000000a3e39/e1918c4f-a6e4-43c1-92d5-0a3512aa3ace_2196.jpg&amp;amp;showShare=false&amp;amp;showLike=false&amp;amp;isVOD=true" width="560" height="315" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;The reason I didn't simply tweet out the link to this video is because I wanted to list some of the topics that he provided clarity to for me. Below is a brief recap of what I learned.&lt;/p&gt;

&lt;h3&gt;Restricted Stock vs. Options&lt;/h3&gt;
&lt;p&gt;Founder stock vs. restricted stock vs. option grants were a point of confusion for me in the past. Mr. Wilson does a terrific job differentiating the three as well as providing great examples for when a company would give out each of the three. I'll try to give my best summary of what he said:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Founder stock - when the company is formed, it's most likely worth nothing so it's most economical to divvy up the shares at the beginning (which is actual ownership) and pay the taxes up front for a nominal amount. &lt;/li&gt;
&lt;li&gt;Restricted stock - typically this stock is only given to early employees. Just like Founder stock, this stock is comprised of actual shares of the company and is immediately taxable. Restricted stock differs from Founder stock as it usually has the same vesting provisions as Options (i.e. 4 years, 1-year 25% cliff).  &lt;/li&gt;
&lt;li&gt;Options - what most non-founder, non-early employees receive in terms of equity. As mentioned above, Options come with vesting provisions. The biggest difference, however, is that Options aren't actual shares of the company - Options are a right issued to you to buy a certain allotment of actual shares at a set price (also known as 'strike price').&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I'll play out an example of how Options work: &lt;br /&gt;
 If a company had a valuation when it was just formed, each share would be worth next to nothing. If the company then received an Angel or Series A round, the investors would value the company to determine how much of the company they own based on the valuation divided by their investment. As a result each share would now have a value. For the sake of this example, let's say each share is worth $.50 now. If you were to join the company at that moment and were issued options (let's say 10,000 options), your strike price would be $.50 per share. If you stuck around for four years and vested all your options and your company was bought at a much higher valuation, say $5.00 a share, you could exercise your grant of 10,000 options and pay $5,000 to own those shares (10k options x $.50 strike price), which you could turn around and sell for $50k at a $45k net profit. Savvy? It's important to note that striking on your options is a taxable event, which is why most people wait until the options are valuable (i.e. your company goes public) before they exercise their right and deal with the tax implications. &lt;/p&gt;
&lt;p&gt;One last thing about Options. The quantity allotted to you in your Options grant is entirely relative. 10k options at one company could be worth less than 1k options at another. Outside of vesting, there are three variables in the Options value equation: quantity (# of options), number of outstanding shares in the company, and company valuation. If you're company is worth $50mm and there are 10 million outstanding shares in the company, each share is worth $5. When you exercise your options, the options in the employee equity pool become shares with real values. So if someone offers you Options at a company, it's very important to take into consideration the current value of each share (if the company is willing to disclose that information).&lt;/p&gt;
&lt;h3&gt;Dilution&lt;/h3&gt;
&lt;p&gt;When you start a company, you own 100% of the company. As soon as you start hiring people, you're going to need to give away equity and, as a result, your ownership of the company dilutes. If you hire a co-founder as your company is forming, your 100% would likely become 50%. After hiring your founding team, you could be down to 40%. If you receive a round of fundraising, it will dilute more and so on. Generally speaking, dilution appears as something you would try to avoid. However, that's not always the case.&lt;/p&gt; 
&lt;p&gt;The biggest takeaway I had from this video about dilution is that your ownership diluting is not a bad thing if the event that caused the dilution adds more value to your company. Quick example of breaking even with dilution: let's say you own 40% of your company and it's valued at $2.25mm before funding. Your investors put in $250k for 10% of your company at a $2.5mm post-money valuation. Your shares dilute 10%, which brings you from 40% to 36%. Before the round, your 40% is worth $900k. After the round, your 36% is worth $900k (2.5mm x .36). Same money for you, more operating money for the company. Dilution - not so bad after all. &lt;/p&gt;

&lt;p&gt;For supplemental reading, check out Fred Wilson's &lt;a href="http://www.avc.com/a_vc/2010/09/employee-equity.html" target="_blank"&gt;Employee Equity blog post&lt;/a&gt;. Also, I should disclose that I'm not a lawyer or accountant so please consult a professional about anything tax-related. &lt;/p&gt;</description>
      <guid>http://dandemeyere.com/blog/employee-equity</guid>
      <pubDate>Wed, 25 Apr 2012 07:25:00 -0700</pubDate>
      <content>&lt;p&gt;Employee equity has always been a nebulous topic for me. Every time I thought I understood how it worked, I would read or hear something that made me question my understanding. Thank goodness people like &lt;a href="http://www.avc.com/a_vc/about.html" target="_blank"&gt;Fred Wilson&lt;/a&gt; exist. He is a &lt;a href="http://www.usv.com/team/" target="_blank"&gt;venture capitalist&lt;/a&gt;, &lt;a href="http://www.avc.com/"&gt;blogger&lt;/a&gt;, and a budding professor. The video I embedded below is Fred Wilson explaining Employee Equity to a classroom full of future entrepreneurs. The video is 70 minutes long and is very thorough so if you want an expert in the field to walk you through how Employee Equity works (and some of the tax implications), I urge you to watch the entire video.&lt;/p&gt;
&lt;p&gt; If you're short on time and you're an employee with options, the first 30 minutes will suffice for a basic understanding. If you're an entrepreneur, you'll still want to watch the last 40 minutes of the talk since it's more about strategy of how to structure your company's employee equity.&lt;/p&gt;
&lt;p&gt;&lt;iframe src="http://cdn.livestream.com/hdembed/index.html?width=560&amp;amp;height=315&amp;amp;play_url=http://api.new.livestream.com/accounts/509100/events/671289/videos/490550.smil&amp;amp;qualities_bitrate=678000,1756000,198000&amp;amp;qualities_height=432,480,270&amp;amp;thumbnail_url=http://img.new.livestream.com/events/00000000000a3e39/e1918c4f-a6e4-43c1-92d5-0a3512aa3ace_2196.jpg&amp;amp;showShare=false&amp;amp;showLike=false&amp;amp;isVOD=true" width="560" height="315" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;The reason I didn't simply tweet out the link to this video is because I wanted to list some of the topics that he provided clarity to for me. Below is a brief recap of what I learned.&lt;/p&gt;

&lt;h3&gt;Restricted Stock vs. Options&lt;/h3&gt;
&lt;p&gt;Founder stock vs. restricted stock vs. option grants were a point of confusion for me in the past. Mr. Wilson does a terrific job differentiating the three as well as providing great examples for when a company would give out each of the three. I'll try to give my best summary of what he said:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Founder stock - when the company is formed, it's most likely worth nothing so it's most economical to divvy up the shares at the beginning (which is actual ownership) and pay the taxes up front for a nominal amount. &lt;/li&gt;
&lt;li&gt;Restricted stock - typically this stock is only given to early employees. Just like Founder stock, this stock is comprised of actual shares of the company and is immediately taxable. Restricted stock differs from Founder stock as it usually has the same vesting provisions as Options (i.e. 4 years, 1-year 25% cliff).  &lt;/li&gt;
&lt;li&gt;Options - what most non-founder, non-early employees receive in terms of equity. As mentioned above, Options come with vesting provisions. The biggest difference, however, is that Options aren't actual shares of the company - Options are a right issued to you to buy a certain allotment of actual shares at a set price (also known as 'strike price').&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I'll play out an example of how Options work: &lt;br /&gt;
 If a company had a valuation when it was just formed, each share would be worth next to nothing. If the company then received an Angel or Series A round, the investors would value the company to determine how much of the company they own based on the valuation divided by their investment. As a result each share would now have a value. For the sake of this example, let's say each share is worth $.50 now. If you were to join the company at that moment and were issued options (let's say 10,000 options), your strike price would be $.50 per share. If you stuck around for four years and vested all your options and your company was bought at a much higher valuation, say $5.00 a share, you could exercise your grant of 10,000 options and pay $5,000 to own those shares (10k options x $.50 strike price), which you could turn around and sell for $50k at a $45k net profit. Savvy? It's important to note that striking on your options is a taxable event, which is why most people wait until the options are valuable (i.e. your company goes public) before they exercise their right and deal with the tax implications. &lt;/p&gt;
&lt;p&gt;One last thing about Options. The quantity allotted to you in your Options grant is entirely relative. 10k options at one company could be worth less than 1k options at another. Outside of vesting, there are three variables in the Options value equation: quantity (# of options), number of outstanding shares in the company, and company valuation. If you're company is worth $50mm and there are 10 million outstanding shares in the company, each share is worth $5. When you exercise your options, the options in the employee equity pool become shares with real values. So if someone offers you Options at a company, it's very important to take into consideration the current value of each share (if the company is willing to disclose that information).&lt;/p&gt;
&lt;h3&gt;Dilution&lt;/h3&gt;
&lt;p&gt;When you start a company, you own 100% of the company. As soon as you start hiring people, you're going to need to give away equity and, as a result, your ownership of the company dilutes. If you hire a co-founder as your company is forming, your 100% would likely become 50%. After hiring your founding team, you could be down to 40%. If you receive a round of fundraising, it will dilute more and so on. Generally speaking, dilution appears as something you would try to avoid. However, that's not always the case.&lt;/p&gt; 
&lt;p&gt;The biggest takeaway I had from this video about dilution is that your ownership diluting is not a bad thing if the event that caused the dilution adds more value to your company. Quick example of breaking even with dilution: let's say you own 40% of your company and it's valued at $2.25mm before funding. Your investors put in $250k for 10% of your company at a $2.5mm post-money valuation. Your shares dilute 10%, which brings you from 40% to 36%. Before the round, your 40% is worth $900k. After the round, your 36% is worth $900k (2.5mm x .36). Same money for you, more operating money for the company. Dilution - not so bad after all. &lt;/p&gt;

&lt;p&gt;For supplemental reading, check out Fred Wilson's &lt;a href="http://www.avc.com/a_vc/2010/09/employee-equity.html" target="_blank"&gt;Employee Equity blog post&lt;/a&gt;. Also, I should disclose that I'm not a lawyer or accountant so please consult a professional about anything tax-related. &lt;/p&gt;</content>
    </item>
  </channel>
</rss>
