Friday, February 22, 2013

A Schedule that Changes with You

I was 20 when I worked at my first startup during my sophomore year. It was 1999 and I felt lucky to be working with a group of people my age (and younger) at a hot tech startup. I regularly slept on the floor of my office to be there more in case something needed attention; some people upped the ante and bought futons; most of the time we spent around the office in whatever clothes happened to be there. I once worked a 46 hour stretch to solve a blocking problem for the team, and that was only just above average. It was a valuable experience that taught me a lot about myself and what I was capable of.

Fast forward 13 years and now I'm in my early 30's, a veteran of several startups in the Bay Area (including one of my own), in serious relationship, and have a cat (living the dream). I have a great group of friends and am often the pivot for bringing everyone together. The idea of sleeping on my office floor doesn't have that same charm as it did in my early 20's. My girlfriend works market hours (EST), which means she's out of the house by 5:00 every morning and asleep by 9:30 pm. I still love working with small teams, mostly at startups, still spend nights researching technology and software development or trying to understand business markets and how to spot opportunities at the intersection of technology and un-met demand.

I think many of us who work in technology eventually start to feel the pull of conflicting responsibilities. As we get older we build our network of friends, commit to more serious relationships, and take on more and more responsibilities in our community. We start to think about our health, deeper motivations, evaluating our legacy, looking forward to the future, and wondering what larger impact we can make. How do we begin to balance all of these parts of our lives to remain productive and fulfill all of these other commitments we've made to others?

People talk a lot about "hacking" our personal lives these days, so I penciled in a few hours by myself and sat down to think about productivity, schedules, and time management. I spent a lot of time making notes not just on my own schedule, but also a cross section of people I regularly interact with; single, married, with / without children, employed / unemployed, etc. I came up with a list of all the things that I know about how they manage their personal and professional lives and fed it back through the lens of my own. I identified the times when I'm most productive (mornings) when I'm the least (afternoon, post lunch), and when I need time to socialize and recharge (evenings). I also factor in my alone time, which for me often means more work (by choice). What I came up with is my schedule for sanity, listed below.

  • 8:00am - 9:00am: Coffee, breakfast, reading blogs/articles/email, starting to explore work that needs to get done for the day
  • 9:00am - 12:00pm: At the office, circling up with the team, starting to get work done for the day
  • 12:00pm - 1:00pm: To the gym for a workout. My afternoons are when I slump the most, and this almost guarantees short-circuiting that unproductive block
  • 1:00pm - 6:00pm: Afternoon work, sometimes meetings, sometimes going heads down, sometimes fleeing the office
  • 6:00pm - 9:30pm: Recharging time. This can mean dinner with the friends, going climbing, finding something fun going on in the city, or just being domestic. I try to put aside all thoughts of work here to really get the most out of it and be ready for my time later on
  • 9:30pm - 10:00pm: Futzing around, maybe just reading the internet, maybe playing a game, etc.
  • 10:00pm - 1:00am: Back to work. Here's where I'm starting to dig deep into bigger problems. I'm often at the whiteboard in my home office during the time sketching ideas, or turning those into something tangible. Last night, for instance, I spent fixing someone else's library so I could make progress on a project that needed it.
  • 1:00am - 7:00am: Sleep time. Sometimes I go to bed earlier depending on my mood and energy levels, but this is a good average

BTW, this isn't a prescriptive formula, it's just what works for me. I want it to be a call for you to think deeply about how you can are really productive and to spend some time re-evaluating an almost 200-year old idea of labor.

Tuesday, January 15, 2013

Practical Talk: Between Product & Engineering

Something important to me as an engineer when working with product managers is that he or she can really wrap their head around what they want to build and clearly explain it using as much detail as is sufficient and necessary to start delivering functionality. Ambiguity is a major driver of frustration and resentment between these two key players within an organization and contributes to a lot of wasted time, money, and creativity. It's a skill to think through what features are key to a deliverable, capturing the details, and sticking to that list when working with engineers. It takes commitment to wanting to deliver the product with quality and good time while maintaining a positive team atmosphere. A common pitfall that I have seen over and over on teams is a product manager who comes up with an idea, throws it over the fence to engineering, and upon receiving a schedule proceeds to move on to other tasks for a month without regular engagement with the team to talk about how they can contribute to quality or timeliness. I have observed a direct logarithmic relationship between the engagement between these two parties and the success of most software projects. The key for the product manager is to find the point where the graph of interaction levels off and work with the team at that level and no more. Unfortunately it is all too common that this point is never reached.

On the other side, engineers (like myself) often have a way of looking at a problem, reducing it to a simple solution that handles the case put directly in front of them, and then offering a timeline with some padding duly added based on previous experience. We go on implementing our well designed systems, everything plays together well, perhaps we've beaten our timeline by 10% - 15%, and we are happy. What usually happens next is the product manager comes back and says "This is all great, but our users need to do X, Y, and Z with the product, and can we also add this feature before the deadline because it would be great". Welcome to the brick wall at the end of the road to elegant system design. Suddenly design decisions you thought made sense are a roadblock to delivering features and you're scrambling to rethink ideas you threw away previously.

Is there anyone here to blame? I don't think so. I think both sides laid out their plans, and then went off to work on them in isolation from each other, not considering that there was a deeper story to be told on the other side. Product managers don't often capture all the use cases because they haven't gotten their hands on anything to close their feedback loop. Engineers are implementing what they were told to, without any notion that it may not be delivering any actual value to customers because they only had a narrow, temporal view of the product.

This isn't an uncommon scenario, so does that mean it merely reflects a core tenet of software development? I don't think so. It's not difficult to come up with a reasonable solution after thinking about it a bit, but like learning to solve a Rubik's cube not everyone is willing to put in the time and effort to start climbing the learning curve.

To start, I suggest we start to turn stories (requirements) into a living contract between product managers and engineers. Contractually, they ask the product manager to commit to a specific slice of functionality. Alive because both sides accept that as deliverables are evaluated by the product manager, new functionality may emerge that displaces less important functionality. For their part, engineers should commit to two practices: edge-to-edge development and delivering entire slices of functionality.

Edge-to-edge development means when delivering a feature, how and where it's deployed, necessary infrastructure such as logging, monitoring, and instrumentation, and a way for it to be tested from the perspective of the customer are all in place. This requires more up-front effort before delivering the first feature, but the marginal cost of adding new ones falls quickly. Developing entire slices of functionality thinking about the system less as discrete parts and more as a vertical profile of all the parts working together to develop a feature to the customer. Instead of working on any particular piece (such as a backend system) in isolation and then trying to layer other clients on top of it (such as a web UI or a data feed generation system), each with their own functional requirements, survey the system as a whole and then pick a whole slice from the bottom up to a customer deliverable and build that. In doing so many of the assumptions from both the product and engineering sides can be validated or challenged as appropriate, and the deliverables can begin to converge on a the product your customers need.

Tuesday, November 20, 2012

Cool Tools: Foreman


The process of building web apps these days has become exponentially easier with all of the open source projects out there to provide data persistance, messaging, job scheduling, etc... you name it and someone has probably built it and open sourced it.  This is great for both the software community and entrepreneuers who need to build a product quickly to get in front of potential customers. Now with some research you can create very powerful applications with only marginal effort by leverage and connecting these services using good client libraries and some application logic you fill in.  Unfortunately then your app needs to have these services running for you to boot it up and start development, testing, and deployments. 

The problem is that you don't want to necessarily run everything all the time on your laptop to be able to sit down and crank out some features.  Modern laptops pack a lot of power and computing resources, but if you are an ultra-light kind of person with a Macbook Air, you still want to be a little choosy about what's running and what contextually makes sense for the current tasks you want to accomplish.  I personally detest the idea of running something like MySQL server all the time just so that I don't have to remember to kick off the server daemon (mysqld, fyi) when I want ot write a little code.  Enter Foreman by David Dollar.

Foreman is a tool that allows you to declaratively write out the list of services you need to run for your application and capture them in a simple file called Procfile.  For instance, stick this in the root of your Rails app, fill it in with the services you need, and when you want to start working open a terminal to the root directory of your Rails app and type foreman start.  This will start up all the services listed in your Procfile and connect stdout and stderr to the terminal window.  Each service is color-coded to make it easy to visually inspect the output, and when you're done developing just send hit ctrl-c in the foreman terminal and all the running services will be gracefully shut down.

Here is a sample Procfile for starting mysql, redis, and resque.  The format is very simple.  Each line is the name you would like to refer to the service as in the foreman output followed by a colon and then the shell command to start the service:



To get Foreman installed, just do gem install foreman, create the Procfile in your project, fill it in with your services, and start the service with foreman start.  You're now ready to start working.  Pretty awesome.

A few other noteworthy features of foreman include an ability to export your Procfile as an upstart or Unix init control script for your production environments, and the ability to run multiple concurrent processes for any of your services.  Check the documentation on the Foreman page to take advantage of these awesome features.