Posted by Gigi Sayfan
on October 6, 2016
Agile practices grew out of challenges in software development and have been extended to many related activities such as database design, modeling and product management. Many budding startup companies embraced agile practices. The nimble and feedback-based approach works superbly for a couple of guys burning the midnight oil in a room or garage. But, founding an actual company has always been a formal and tedious process that can take the founders' focus off the main activities that evolve the product. Stripe decided to change that. The Atlas initiative aims to take a lot of the burden off your shoulders--including incorporating in Delaware, opening a business bank account, registering the new company with the IRS, opening a Stripe account for accepting payments, tax consulting and even more of tools and services. Atlas can also be used by non-US founders that believe incorporating in the US is the best route for their business.
Atlas is still in Beta, but already has an impressive network of partners. During the beta, there is a one-time fee of $500. Once you send in your application, you should have your company up and running within a week! This is quite amazing.
How many potential new startup companies never make it out of the side project stage because of the friction and difficulty of actually starting a company? How many companies waste a lot of time and resources at the critical early stage to get their company off the ground? Atlas is an ambitious proposition and I'm very curious to see how it pans out. If you're an aspiring entrepreneur who has considered starting your own company, Alas may be just the right thing for you.
Posted by Gigi Sayfan
on September 15, 2016
Agile practices help you develop software that meets the user needs faster and safer — and that responds quickly to changes in the requirements, environment or technological advances. But, there is one "secret" practice that is not often mentioned in the context of Agile development. This is really an "un-practice". The idea is to flat out not do something. It could be a requirement (this will require negotiating with the customer), a refactoring or a bug fix. Just because something is on the backlog doesn't mean it always needs to be done. Extreme Programming calls it YAGNI (You ain't gonna need it) where you postpone doing things that are not needed immediately.
Being minimalist by design is often neglected. Everybody wants to eventually conquer the world, right? Another aspect of this mindset is over-engineering. A lot of effort is expended towards building infrastructure, scalability and automation that isn't necessarily needed. Why is it so important and why is it often ignored? It is important because Agile is all about delivering real value, really quickly. If you work on something that's not really needed, you just wasted time and effort.
The reason it's often ignored or not practiced fully is that it's difficult to be disciplined. You start working on a cool feature or capability and want to keep evolving and improving it even if it's not providing immediate business value. On the infrastructure/implementation side, developers are often worried about technical debt. I'm often guilty of trying to get the project "right" from the beginning. If you want to really deliver the maximum business value in each iteration, you have to be very aware and explicit about what you plan and how you go about it. Just paying lip service to the idea is not good enough.
Posted by Gigi Sayfan
on August 23, 2016
Building software used to be simple. You worked on one system with one executable. You compiled the executable and if the compilation passed, you could run your executable and play with it. Not anymore--and trying to follow Agile principles can make it even more complex. Today systems are made of many loosely-coupled programs and services. Some (maybe most) of these services are third-party. Both your code and the other services (in-house and third-party) depend on a large number of libraries, which require constant upgrades to keep up-to-date (security patches are almost always mandatory). In addition, these days, a lot more systems are heavily data-driven, which means you don't deal with just code anymore. You have to make sure your persistent stores contain the data for decision making. In addition, many systems are implemented using multiple programming languages, each with their own build tool-chain. This situation is becoming more and more common.
To follow Agile principles and allow an individual developer to have a quick build cycle of edit-built-test requires significant effort. In most cases it is worth it. There are two representative cases: small and large:
In the small case, the organization is relatively small and young. The entire system (not including third-party services) can fit on a single machine (even if in a very degraded form). In the large case, the organization is larger, it's been around for longer and there are multiple independent systems developed by independent teams.
The big case can often be broken down into multiple small cases. So, let's focus on the small case. The recommended solution is to invest the time and effort required to allow each developer to run everything on their own machine. That may mean supporting cross-platform development even though the production environment is very carefully specified. It might mean creating a lot of tooling and test databases that can be quickly created and populated.
It is important to cleanly separate that functionality from production functionality. I call this capability system in a box. You can run your entire system on a laptop. You may need to mock some services, but overall each developer should be able to test their code locally and be pretty confident it is solid before pushing it to other developers. This buys you a tremendous amount of confidence to move quickly and try things without worrying about breaking the build or development for other people.
Posted by Gigi Sayfan
on June 24, 2016
The traditional view of productivity and how to improve it is completely backwards. Most people think of productivity as a personal attribute of themselves (or their subordinates). X does twice as much as Y, or yesterday I had a really good day and accomplished much more than usual. This is a very limited view and it doesn't touch on the real issue.
The real issue is organizational productivity. The bottom line. The level of unproductively increases with scale. This is nothing new. It is one of the reasons that miniature startups can beat multi-billion corporations. But, most organizations look at the inefficiencies introduced with scale as a process or a communication problem, "If you improve the process or the communication between groups, then you'll improve your situation." There is some merit to this idea, but in the end, larger organizations still have a much greater amount of unproductivity compared to smaller organizations.
The individual employees at the bottom of an organizational hierarchy work approximately as hard as individual startup employees. The middle management does its thing, but is unable to eliminate or significantly minimize this large-organization unproductively tax. In some cases, there is a business justification for the larger organization to go more slowly. For example, if you have a mature product used by a large, and mostly happy, user base then you don't want to change the UI every three months and frustrate your existing users with weird design experiments. You might want to do A-B testing on a small percentage, however. The current thinking is that this unavoidable. Large companies just can't innovate quickly. Large companies either create internal autonomous "startups" or acquire startups and try to integrate them. But, both approaches miss out on important benefits.
I don't have an answer, just nagging feeling that we shouldn't accept this unproductively tax as an axiom. I look forward to some creative approaches that will let big companies innovate at startup-like speeds, while maintaining the advantages of scale.
Posted by Gigi Sayfan
on June 9, 2016
In Rational Tech Adoption, I discussed how to decide about whether or not to adopt new technologies. But that decision is not context-free. There is always a switching cost. If the switching cost is too high, you might forgo potentially beneficial upgrades whose benefits are less than the switching cost.
In order to benefit from new technologies, you need to build agility right into your stack. Can you easily switch your relational database from MySQL to PostgreSQL? How about from MySQL to MongoDB? Can you move from Python 2 to Python 3? How about from Python to Go? Are you running your servers on AWS? Can you move them to the Google cloud platform? How about switching to a bare metal virtual service provider? Those are not theoretical questions. If you build successful systems that accumulate a lot of users who stay around for many years, those questions will come up.
Traditionally, the answer was always, "Nope. Can't switch," and you got stuck with your initial choices or, alternatively, a super complicated project was launched to upgrade some aspect of the system. The good news is that similar to testability, performance and security, if you follow best practices such as modularity, information hiding, interaction via interfaces and build loosely coupled systems, then it will be relatively simple to replace any particular component or technology.
The stumbling block may often be your DevOps infrastructure and not the code itself. The whole notion of DevOps is still new to many organizations and there isn't much awareness regarding the need to quickly switch fundamental parts of your DevOps infrastructure. If you consider these aspects when you build your system, you'll have the chance to reap enormous benefits as your system scales and evolves.
Posted by Gigi Sayfan
on May 25, 2016
My favorite Agile methodology, Extreme Programming, has five main values: Simplicity, Communication, Feedback, Respect and Courage. The first four are relatively uncontested — everybody agrees on these four. Courage is different. Courage ostensibly flies in the face of safety, security, stability and risk mitigation. But, this is not what courage is about. Courage is actually about trust. Trust yourself, trust your team, trust your methods and trust your tools. But, trusting doesn't mean being gullible or blindly trusting things will somehow work out. Your trust must be based on solid facts, knowledge and experience. If you have never done something you can't just trust that you'll succeed. If you join a new team you can't trust them to pull through in difficult times. Once you gain trust, you can then be courageous and push the envelope knowing that if anything goes wrong you have a safety net.
When trying something new, always make sure you have plan B or a fallback. Start by asking "what if it fails?" This is not being pessimistic. This is being realistic. Sometimes, the downside is so minimal that there is no need to take any measures. If it fails, it fails and no harm done. Let's consider a concrete example: suppose you decide with your team that you need to switch to a new NoSQL database with a different API. What can go wrong? Plenty.
The new DB may have some serious problems you only detect after migration. The migration may take longer than anticipated. Major query logic may turn out to depend on special properties of the original DB. How can even think of something like that? Well, if your data access is localized to a small number of modules and if you can test the new DB side-by-side and you have a pretty good understanding of how the new DB works, then you should be confident enough to give it a go. To summarize — being courageous is not taking unacceptable risks and being impervious to failure. It is taking well-measured risks based on sound analysis of the situation and full trust that you know what to do if things go south.
Posted by Gigi Sayfan
on May 12, 2016
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian Kernighan (co-inventor of the C programming language).
You shouldn't take it literally of course, but there is a grain of true to both parts: debugging is harder than programming and also, if you write your code too cleverly, you'll have trouble debugging it. One lesson to take away is that you should write clear and simple code that is easy to understand and troubleshoot when something goes wrong.
Another way to look at it is that when something does go wrong you want all the help you can get to fix it. One of the main the Agile practices is pair programming, where two programmers collaborate in front of a single screen and keyboard — probably the least popular in the Agile arsenal. However, pair debugging is taking all the goodness of pair programming into the debugging experience. You don't have to feel you're all alone against the inscrutable code. Your partner will help you through tight spots and see things you don't notice. Sometimes just explaining the problem to your partner may shed a light on what's going on. I've had a very good track record where the combined efforts of the pair found the root cause after a single programmer was stuck for a long time banging their head against the metaphorical wall.
My recommendation would be that when you face a difficult problem, try to solve it on your own, but as soon as you run out of ideas or feel overwhelmed call in the cavalry. Describe what you know and what you have done so far and you'll be surprised that often that alone will get you unstuck. If not, your partner will probably have some ideas regarding how to move forward. Happy pair debugging.
Posted by Gigi Sayfan
on May 2, 2016
The ability to hire excellent software developers is a limiting factor. There is a real shortage, and as a result there is serious competition for every qualified candidate. As a manager on the lookout for talented developer I experience it personally. There are two very clear trends here. Candidates who put themselves on the market will get queries from more companies than they can handle. In one hiring platform that I use shows competing offers and it is common to see a well-qualified candidate receiving 20+ invitations for initial interviews. The other trend is that the big companies out there: Google, Facebook, Uber, etc., use their war chests to offer unheard of levels of compensation. An engineer decides which company to join based on many factors. But, if a big company offers $50K - $100K more than competing offers (in total compensation) then it's very likely the engineer will pick the big company. How can a small startup compete? By using its relative strengths - speed. This is where Agile hiring methods can give you the advantage.
What if you compress the entire hiring process so that you can get an actual job offer out to a candidate, before they have even had a chance to set up phone interviews with most of the other companies who might be interested in them? In the best case scenario, maybe your competitors are so slow that they didn't get around to even sending to initial invitation. I will not discuss here how to find those candidates.
Let's start from the assumption that you have some source of candidates. With Agile hiring your focus is to minimize the time from zero to offer (or rejection). The typical hiring process consists of:
- Review of resume/application/cover letter
- Phone interview[s]
- Coding challenge
- Face-to-face interviews
- Reference checks
- Background check
- Offer letter
The goal is to avoid wasting valuable time by rejecting inadequate candidates early in the process. Let's see what we can get rid of. The phone interview can go away. I very rarely reject a person based on the phone interview. If the original application is solid, the candidate will make it to the next phase. The coding challenge can go away if the candidate has a decent GitHub account. The reference checks can go away. I never got any useful information whatsoever from a reference the candidate provided. So, here is the Agile process:
- Applications are processed by an experienced technical person who can look beyond buzzwords and evaluate coding competency based on public code.
- Immediate invitation to face-to-face interviews, or if problematic, video conference interviews (easier to schedule).
- Until the interview exchange information with the candidate for expected compensation and role. (This may be a phone conversation, but not a gating review to delay the face-to-face interview that was already scheduled.)
- At the end of the face-to-face interview the candidate should have an offer in hand.
Negotiation may take place and background checks can be conducted later. That's it. You could have a new engineer within 2-3 days since first contact vs. 2-3 months. Think about it. If you're worried about wasting people's time with too many interviews, consider having fewer people interview each candidate. It is not a rule of nature that every team member must meet and approve every candidate. If you are confident in your filtering abilities, then maybe just the hiring manager and two other people need to speak with the candidate.