In How to launch in a month and scale to a million users, Joseph Perla, Former VP of Technology and founding team of Turntable.fm, shares techniques he used to build and quickly scale his startups. The post is very well written and a must read. Here are the essentials:
- Keep it simple. Build API's before making the website or mobile apps. Keep interfaces small and single-purpose.
- Get it right. Build in automated tests from the start. Create function tests, module level tests, and full integration tests. Run tests on every commit. No new code written while bugs exist.
- Use procedure arguments to provide flexibility in an interface. Pass functions instead of parameters to support complicated scenarios. For example, a filter function return a boolean.
- Leave it to the client. Keep the server simple and move as much functionality as possible to the client.
- Continuity. Keep interfaces stable. Version interfaces from the start.
- Keep secrets of the implementation. Keep service implementations entirely independent to provide maximum flexibility to handle requirement changes, even though it means a slight performance decrease.
- Use a good idea again instead of generalizing it. It's OK to replicate and specialize similar code instead of creating a more generalized library.
- Handle normal and worst cases separately as a rule. Code should clearly special cases rather than use a more general algorithm that would remove the special cases.
- Split resources in a fixed way if in doubt. Servers should be single purposed. For example, keep the database index and search index on separate machines. They can then be scaled independently and won't stomp on each other.
- Use static analysis if you can. On check-in run stack analysis tools on code to find bugs and performance issues.
- Dynamic translation from a convenient representation to one that can be quickly interpreted. For example, a Python domain specific language for tweet filtering was easy to program and could be directly translated to python bytecodes.
- Cache answers to expensive computations. Self explanatory, but be careful of cache invalidation issues.
- When in doubt, use brute force. It's better to complete a feature faster using a simple algorithm than it is to delay implementing a clever algorithm.
- Compute in background when possible. Do as a little work as possible in the web server, queue it to background processes.
- Use Batch Processing if possible. Loading individual data items is slow, load them in large batches.
- Shed load to control demand. It's OK to have limits. Pick limits that make your software work without having to go through heroic efforts or change stacks.
- Hints for Computer System Design by Butler W. Lampson