System Design

The Right Way

There is no right or wrong way to develop software. This is a controversial, but key concept to grasp.

What matters is that everyone working on developing a single piece of software agrees to use the same methods. They must pull together rather than pulling apart.

No methodology or practice works the best across all products, teams or systems. You need to find what works for you and yours, and then push to maintain that successful process over time.

Many people have written and talked about what worked for them, whether it is Scrum, XP or waterfall for delivering projects, or smaller and more syntactic decisions such as OO programming, functional programming, or even a particular coding style.

Don’t fall into a trap of a one true way. What is true for one person in one situation may not hold true for your team in your situation.

Once you find a method you can make use of, then you must by all means strive to implement the best practices and recommendations of others. There is little point in choosing to do something badly when you can choose to do it well.

Find something that fits, do it as best you possibly can, and good quality software will follow without fail.

Performance Basics System Design

Connections Per Hostname

There are lots of ways to improve the performance of your website, some are easier than others to implement, and some will have a greater or lesser effect.

One potentially easy win is to limit the requests made from a single hostname. Most modern browsers will create up to six requests to a single host. If you are serving all of your resources from the same domain, e.g. then the browser will request the first six, wait for them to load, then start requesting the next six.

If you split your resources across multiple domains then this queuing will not occur. As a simple improvement, load your static content from (or similar). This means that your dynamic pages will load, and start pulling your static content very quickly, rather than waiting for all the requests to the dynamic pages to complete.

This splitting out also leads to other possible benefits. You can put your static resources onto a CDN, so the performance of your will be drastically better than if served from your own servers. It also allows for further tweaks, this domain can be configured to be cookieless (you’d use in this case). That would save sending cookies for static requests, which you should never need.

This is a quick improvement that should be simple to setup. The major effort is in configuring the domains correctly, and planning your system to allow for these split domains. Once you’ve done that, you’ll increase performance for everyone using your site, without having to improve the code that drives the system.



System Design

Breaking Changes

Making a breaking change is just about the most destructive thing you can do in a software system. Doing something that means everything that went before is outdated means you are going to severely limit your options for the future.

A breaking change is one where the system has changed in such a way to mean you cannot go back to the old version.

If you can’t go back to the old version, then you need to be certain that your new version will work. That may sound pretty simple, but it’s always harder in practice.

You should design your system to reduce the number of breaking changes, and to allow for the simplest methods of coping with a breaking change.

When you have the choice of a little extra work to make a smooth transition, give enough weight to the prospect of your change failing to estimate correctly. Don’t just assume that everything will work and you can always roll forwards.

If you can isolate your breaking change to a single layer then you can split your deployment to several pools. You need a way to send users to the new or old code in a reliable way, otherwise this will not work.

If you design ahead of time to take account for the breaking changes, then when you finally need to make one it won’t be as painful as it may have been.

System Design

Performance Tradeoffs

Performance is often a key concern in designing systems. Every time we consider performance we are making some kind of trade off in the wider system, and this needs to be understood or the system will fail.

Generally a performance requirement is phrased in a vague manner, indicating the system should be fast, responsive or otherwise quick. This is going to be very hard to design well for.

A good requirement will let us start making the tradeoffs we need. It will request that a key page is loaded in less than a second, or that calls to external services complete in less than 100 milliseconds. The requirement here is measurable, so we know if we have achieved it or not.

With the measurable requirement in hand, we can decide how to achieve the required performance. It might be easy, and just be met as the system is designed. We might need to cache data, or use more powerful hardware (trading cost for performance). We may find we need to use a lower level language or code module (trading maintainability for performance). We might have to use new or unproven technologies (trading risk for performance).

Once the requirement is understood we can look at the key performance tradeoffs, make the system design with these in mind and ensure that the stakeholders in the system are aware of the choices and options available to them. If we don’t have measurable performance requirements, we can’t make these informed decisions, and the system will suffer.

System Design

Tiered Applications

We design systems in tiers to enable us to simplify complex problems and to give us greater understanding of the solutions we are attempting to create.

The most common separation is to split Data, Display and the methods to convert one to the other (generally known as Business Logic). This three tier structure can be seen across many different applications, and extends throughout the entire software industry. Often developers will be hired to only work on a single tier, the skills for working at each level can be very different.

If we achieve a good separation into tiers, we can replace the implementation of one tier with another. The commonest replacement is to implement new Display modes, adding a mobile display to an existing website, switching a windows display to the web.

Changing the data source is almost always more problematic, as you must move your data as well, but it is still possible.

We give up the possibility of the most efficient system when we create a tiered system, but in exchange we gain simplicity and understanding. As technology gets ever more powerful the systems we ever more afford this trade-off in the interest of creating maintainable and extendable systems.