Hamann Distributed

Making mistakes at scale so you don't have to.

Dear Lucas

Yesterday, I found an E-Mail in my Inbox.

Very impressive profile, Dominik! Any advice for a relatively young programmer who would like to be someone with similar skills in the next 10 years?

Lucas W.

Now, I admit I was a little flattered. I really don’t think I’m that good, but looking back at the last six years and realizing again how I went from a broke, bipolar and triple failed university student to Lead Architect and eventually CTO and Co-Founder within this short timeframe, I can’t help to think that there must be something I did right and I could share with others. My impostor syndrome would beg to differ, but in fact there wasn’t so much magic involved – but lots of hard work, meeting the right people (among many more wrong ones) and taking opportunities that popped up along the way, even if they had some risk involved. I could totally do it and so can you.

My first intention was answering him personally back on Linked.in – but from my experience here’s one tip for starters already: If someone asks you a question that many more people might have, do yourself a favor and write it down for posterity. Put the answer into your code, wiki or blog for everyone to read for reference and you might make more than just one person’s day.

So here’s my advice to you, Lucas. I’m sorry, there is no TL;DR. There are no shortcuts. This is the real deal.

Ambition and Culture

Lucas, you asked me for a 10 year career path. I think you should be bold and shoot for what you can achieve in one year instead. Before I go into any of the numerous technical aspects of your question, I think there is one important lesson for you to take so far already – which is: Don’t stand still. The fastest way to learn ANYTHING is to learn it from people who already know what you want to know – and are great at both teaching and learning. You need to surround yourself with those people if you really mean it. These are always people who are “better than you”, and you should try to get them to mentor you.

How to do it? Simple. Approach them even if you’re not working directly with them. Be nice, interested and try to solve some of their problems on your own. Ask them good questions and come back when you’ve done your homework to ask some more. Don’t ever ask them stupid questions, which you could answer yourself by Googling. Don’t ever ask a question twice. You know you’ve found a good mentor when you get continuously harder tasks and candid feedback from them. Within your company, try to get into the fastest and most respected team. Whenever you think your learning curve has peaked and is on its way down, look around for new opportunities.

In some great companies, it’s possible to evolve into ever more challenging jobs with increasing responsibility, but unfortunately often it’s not. When you feel like you’re hitting the glass ceiling, move on and look for something else to continuously broaden your horizon and stretch outside your comfort zone.


High degrees and certificates will only take you so far in programming and often aren’t worth the hassle. I once did the Zend Certified PHP Engineer to prove I wasn’t a total failure in programming, but I skipped the expensive course and just sat down with a book and some test questions to prepare. More importantly, after years on the other side of the hiring table I’ve learned that people with the most certificates and the highest degrees are more often than not the least productive ones, because somehow, a lot of them seem to rest on their past successes and stop learning.

Remember, you’ll be hired for your papers, but you’ll be promoted for your output – so don’t spend too much time on the former.

Read Hacker News

Why Hacker News? Quite simply, it’s where some of the best people meet and share their knowledge about the whole technology ecosystem. There are other aggregators, maybe even in your native language. However, you should really start embracing English as your work language if you didn’t already and the best way to become proficient is reading and writing a lot.

Some people say Hacker News has become boring and repeating. These are usually the people who have become experts themselves by reading there for years – I still find lots of new, interesting and important information about technology and startups there.

Read about half an hour every day to stay on touch and learn something new, then get on to work on other things. Reading more won’t make you better after a certain point, only practice will.

How to learn

I’ll give you a truckload of things to learn below, and learning is the most important thing you will ever do as a developer. But remember that learning works best (some say: only) as a spiral. You’ll learn something, not quite understanding everything and move on to the next topic. Maybe you’re a little frustrated. This goes on and on until you come back to the first topic. You’ll look at the topic again and see that a lot of things explain themselves through the new connections, abstractions and transfers you made on your detours. This spiral will continue forever. If you’re not embarrassed by work you did years ago, you probably haven’t evolved or developed much.

Don’t try to learn any of the topics below “fully” before moving on. It’s simply not possible. Try to get one focus area every day and rotate.

Get used to the feeling of not understanding certain things. It’s normal. You will eventually.

Get used to the feeling of not knowing the exact paths to the goal you’re after. It’s normal. You’ll find out on the way.

The Mix

Then there’s “the learning mix”. It’s the optimium mix between reading, working, toying and communication.

Try to get the balance right, because combining all four belong to becoming a great developer.

You need to read, because there is a lot of information that you need in order to make good choices in every possible field.

You need to work because only applying your knowledge to a concrete codebase will complete the learning cycle and give you actual experience.

You need to toy and play. No, I’m not kidding. This is also work but it’s disguised in a much more undirected format, often with no clear goal at all. This is all about looking behind the curtains, trying unusual solutions, long shots which most probably wouldn’t ever work (and finding out why). Finding shortcuts or doing things with frameworks, languages or technologies that are not used at (or not even recommended for) “daily” work. Lots of people – especially women – are conditioned quite early by society not to needlessly toy around but to be “serious” – yet toying around is essential to becoming a great developer.

It’s really about expanding your horizon and it’s even appropriate to do some of these things at work: Small tools and one-off tasks are great use cases for more experimental technology. Some of the more time consuming things you should do better do in your free time.

Last but not least, you need to communicate. A lot. You need to ask, tell, understand and be understood. Also, get the mix right. You should hang out about one third within your core technology group (other devs, mentors, bosses), one third within extended technology (other teams, admins, BI guys, meetups) and one third outside of technology to understand other business functions and their needs better.

Lunch is usually your friend.

Learn 10 Programming languages over the years

Why ten? Well, I just pulled a number out of my hat that feels about just right to start to get an intuitive grasp on code. You’ll learn that all programming languages share some features that are common but all have distinctive advantages and disadvantages in different situations. It also helps you get over stupid language wars and see the other sides of the table. It’s really about developing a technology “feeling” that will help you make good decisions later. Make sure you get some diversity again.

Choose something low level like C or assembler, something high level with a framework (Rails, Django), something object-oriented (Java, Objective-C), a functional language (Haskell, Clojure), something mixed-paradigm (Go, Scala), something arcane (COBOL, BASIC) and something brand-new or experimental (Rust, Nimrod). Choose a language targeted towards certain niches (Julia, Ada, Autohotkey <– don’t laugh, it was my venture into programming), and maybe something exotic like Brainfuck or LOLCODE. Be sure to learn JavaScript and why it’s both ingenious and awful at the same time. Learn at least the basics of SQL, HTML and CSS – I don’t count them as real languages, but you’ll come across them pretty much everywhere, even if you don’t see yourself as a “web developer”.

You don’t have to learn them all to full proficiency, but you should try to get something specific done in every one of them and move along. Stay around some more time with languages you like, learning them at a deep level – and leave others behind, mentally noting why you didn’t like them. This is really subjective. I for example can’t stand Lisp dialects because I find the parentheses ugly and the syntax unreadable. You will find other programmers totally excited about its expressiveness.

I won’t tell you PHP is a bad choice, lots of others will happily do that for me. Facebook, Wikipedia and Wordpress are examples showing you that the language works. Yet not everything which is widespread is great as well. Don’t believe others, find out yourself. PHP used to make me happy, fast and productive in my early days, but it doesn’t anymore.

Your preferences will change as you get more experienced. Often, beginners start with dynamic languages and hate types in the beginning (mostly because you don’t fully understand them and they’re a hassle to work around), yet start to appreciate them when you get more experienced and work in larger teams. YMMV.

Learn about data structures and databases

Data is everything you will ever create and move around in IT. If you are a self-made programmer like me, you will have most headache but also lots of leverage with understanding data structures. This is the boring stuff of every CS class which you cram into your head and then forget – but it’s only really interesting if you come across concrete problems where you’re running into the limits of your data structures. You should definitely know what sets, maps, arrays, trees, tries and lists are, how they look in computer memory and what their complexity cost in Big-O-Notation is. I found it much easier though to learn them on the job when I actually used them.

Databases are important as well. If you don’t know anything about databases yet, don’t be a hipster and just use Postgres. You’ll be sure to learn something solid, performant and generic which will stick around. But if you’re already planning beyond Gigabytes of data, hundreds of concurrent connections, below a hundred milliseconds of latency or all of the above, you need to understand more scalable database technologies and their limitations. Read about MapReduce, DynamoDB, BigTable, sharding, elasticity, indexes, immutability, ACID and BASE, and these are only the very beginnings.

To really make good technology decisions, you need to talk to your business about the eventual requirements of the system, because you WILL have to make some tradeoffs eventually and you should be aware of them. Think of good questions before you try to find answers, i.e. “How often will data get updated?”, “How much downtime is acceptable in a day / year / minute?”, “How fresh does the data need to be?”. I can give you 20 of these questions drilling down into your real needs right now, and all of this will reflect in the architectural choice I will make.

I was once asked by a CEO why we couldn’t just “put everything into a really fast database and then get results from arbitrary queries in realtime” (note that he was talking about 500 GB a day). I told him that he could sell our company for several billions if we had that technology.

Learn about your craft

In the middle of this page, you will find a mind map about everything you should master as a Rails developer. Forget the “Rails” part for now, 80% of this map describes the neccessary skillset for every language and framework you can think of. You should spend at least a few hours for every single leaf of this tree to understand the concepts behind them. A developer who can program perfectly but can’t use VCS, Continuous Integration and Testing in an Agile Environment is pretty much useless in 2014.

Really, good craftsmanship cannot be underestimated. You should choose to (deeply) learn a powerful editor like Vim/Emacs/Sublime/IDEA and learn 10 finger typing. I bought this keyboard and learned it the hard way – within 2 weeks and at the venerable age of 26 years. Both measures roughly tripled my coding & writing performance and I didn’t ever look back.

Learn about people

Dealing with people is the single most undervalued skill in IT with the most leverage. This is both the shortest and the longest chapter of this text, because everything that needs to be said about this topic has been written 78 years ago already – and the only thing you should really do is get a copy and read it. Don’t be put off by the title, remember this book is as old as your grandparents, yet people didn’t change a single bit…

Learn about your business

Someone who can take any spec and write it down into working, readable and performant code is a great programmer.

Someone who can take any business problem and write it down into a well-modelled spec before coding it down is a great engineer.

You’re free to stop at being a good programmer, but good engineers are paid double the price. Really, the top three skills you can learn if you want to progress your career are

  • Taking a business problem and turn it into a working software model

There are lots of good ideas out there, yet execution of all of them depend on your technical transfer skills. Nothing is quite as important as learning to read the language of business people, form them into a domain model and explain and reevaluate the model together with the business people before even writing the first line of code. A great intro to this topic are the first chapters of Eric Evans’ “Domain Driven Design”. This also means that you should get familiar with the business itself that you’re currently in. Learning which KPIs are important and have the most impact to your business will help you find much better technical solutions.

  • Explaining technical dependencies and challenges to non-technical people

It’s easy to underestimate how hard this really is. Yet, the ability to explain everything to a 5-year-old and negotiating features in order to keep down complexity are incredibly important for you to learn. A great example I had: Product Managment specified that they wanted a user that had seen a banner not to see it more than five times within the following 24 hours. I asked if it would be okay to only show the banner to them five times per 24-hour-interval. They said “but that’s almost the same!”.

Yes. From a product side this was almost equal, but of course technically, the latter was much less complex, saving lots of programming hours and computing complexity by simply rethinking the specs and providing an alternative. Learn how to teach the concepts of technical debt, technical investment and software rot and incorporate them into your estimates. Speaking of which…

  • Making good estimations

Estimating is usually one of the things even great programmers learn last. Yet it is crucially important to know for the business how long things will take. Learn to express yourself in terms of complexity and uncertainty. It’s helpful to continuously practice the estimate-observe loop with your own tasks and also learn about how large and complex projects are fundamentally different to a one-man-show. A great rule of thumb for larger projects from “The mythical man-month” which I often use is: 1/3 of the time is spent on design, ¼ on early testing and debugging, ¼ on late integration and acceptance testing and only 1/6 (!) on actual coding.

Take this into account and multiply the resulting time by 1.2 for every team member before dividing through the team to account for communication losses. If you have time, read the whole book for some great insights on planning software projects. Same thing here: You won’t believe how accurate most parts of a 40 year old book on software development still are today…

Learn to glue

30 years ago, if you wanted to write an app, you wrote everything yourself, from the device driver routines to the graphics buffer. Fortunately, thanks to the Github revolution, nowadays you can find an open source package for just about anything. And systems are so much more complex now that you’d be stupid not to. Not just that – most of the times, these libraries are written by people smarter or more experienced than you are.

On the other hand, with great power comes great responsibility. These packages often will not exactly do what you want or what you need and you’ll have to make important decisions. Do you commit back to the project and hope for a pull request? Do you integrate parts of it as an API? Sometimes it’s a good choice to go for a full stack framework. Other times it’s better to hand-pick and compose some smaller packages to achieve success.

On top of that, you will have to manage the dependencies as well. They will get out of date, glitches and security bugs will pop up and often they might have changed their interface inbetween so you have to change all your code in order to upgrade. Some code will rot and get abandoned. If it’s a small library, that might be okay, but if it’s your CMS or the fancy bleeding-edge framework you built your website on back then, you might be screwed.

If on the other hand you choose to build everything yourself and end up with a huge stack that’s reinventing the wheel instead of using standard components, it’s getting continuously harder to onboard people, up to the point where I’ve seen this literally killing companies.

All these problems require a completely new skill, which is searching, composing and glueing software components to your own stack the right way. There’s even a conference solely dedicated to this topic, that’s how hard this is in itself. If you have several repositories doing what you want, you need to be able to estimate their traction by evaluating the number of stars and forks, frequency of pull requests, number of open issues, commit frequency and date of last commit and if it is maintained by a company (yet not too much to cripple it), just to mention a few.

Get good at this stuff and if you really decide that you write a component yourself, you should already know the three best repositories closest to solving your problem and how they are not cutting it quite yet for your use case.

Learn DevOps

In the days of Infrastructure as a Service, it’s become so easy to start up your own server / cluster / database, that there is simply no excuse not to try it yourself. The entry barrier is so low through services like AWS or Heroku, that you need to be proficient in provisioning a prototyping environment yourself. Some people “admire” my Hadoop skills and complain they never “had the opportunity to work with it” before. I call BS. For just a few dollars, you can run your own map-reduce jobs on Amazon EMR and experiment with huge freely available open-data test sets if you were really interested in it. Get an account NOW and understand which problems the dozens of AWS services solve before you try to roll your own.

Learning how to properly operate, monitor, deploy, secure and maintenance real server systems – even superficially – will get you a much deeper understanding on how your code will actually run and perform when in the wild.

Also, you’ll get some humility for Admins who do this stuff full time.

Learn about technologies like Vagrant, Docker and Fig and their underlying concepts of immutable infrastructure to get into the modern mindset of 12factor apps.

Yes, all of this didn’t even exist in 2011.

Yes, it’s hard to continuously follow these important trends and keep up with the pace. You signed up for the ride.

Go on from here

Lots of what I wanted to say as well has been already said – for some more good stuff that I didn’t cover, go over here:


I couldn’t have said these things any better myself, thanks Peter.

Thanks for reading and I’m looking forward to see what your career has to offer.



The Day My Cable Provider Killed Me

or: Eight lessons in avoiding customer service disasters

Last Sunday, my internet suddenly stopped working. I didn’t think too much of it, but when I reset my router as usual and it still wasn’t working, I was getting curious. Turned out, my TV and my phone didn’t work as well. Now, I was definitely angry. I called up the tech support of Kabel Deutschland, my cable provider. After 10 minutes in the line, I gave up and went to bed.

Lesson 1)

Try to stay accessible for your customers. Of course, this isn’t always possible or economical – but it might be helpful to separate urgent technical issues from contract support and prioritize the former. Especially if you are in a position to have significant impact on your customers’ daily life.

Monday morning, I called tech support again. I asked why none of my devices were working anymore and the agent looked into my case. She mumbled something about a “horrible mistake” but she’s sorry and everything should be working again within 24 hours. I sighed and left for work, leaving my wife at home alone with our daughter – and no internet or phone whatsoever.

Lesson 2)

If you let your customer service agents promise something to the client, make sure to keep it. If you can’t keep it, don’t let them promise anything specific.

24 Hours later, there was still no internet. When I got to work, my wife sent me a message. Kabel Deutschland had sent a letter, offering their condolences to my death (!) and cancelling all my contracts. Now it was finally getting obvious what the “horrible mistake” was: I had sent a marriage certificate to them because I had changed my family name – and someone obviously mistook it for a death certificate.

Lesson 3)

If your customer support is able to make high impact decisions, make sure there are basic protections against accidental or malicious misuse. It doesn’t even have to be a four-eye principle, sometimes a checkbox “are you sure” can do the trick. When you’re taking potentially harmful actions against your customers, be transparent and try to inform them early on, preferably on real-time channels.

I was a little irritated and slightly bemused, but I wasn’t too that mad about the mistake yet. I started my career in customer support and know how little people are paid in this industry and how much they have to do. I was mad though about how they dealt with it.

Lesson 4)

If you are dealing with customers and make mistakes, listen to the late Dale Carnegie: Admit mistakes on the spot if you do them and apologize – it will make you much more human and believable. Don’t try to put things under the rug.

My amusement passed when my wife had to send important documents from home, rushing to neighbors with a sick kid just to plug her computer in. She called tech support from her phone, this time escalating to second level support. The agent couldn’t see any of the other calls made the days before, but was “shocked”, apologized and promised again that everything would be working soon, but it would take some time. By now we were writing down names just in case.

Lesson 5)

Get a CRM. If you have one, use it. If you’re using it in first level support, share it with second level support and tech support. Get these basic things straight, before you start to get into the business of dealing with end customers.

One more day passed. At that time, worried messages started to come in from all over our family because our phone line was still dead. My wife called tech support again, escalating again. They kept asking for more “patience”, because they would have to restart the contract and reprovision all our devices from anew. We kept waiting. Both our monthly mobile internet limits were exhausted.

Lesson 6)

As an engineer running high-availability platforms, we always have a rollback plan when we deploy new software. So, when things go wrong (and they do go wrong), we can have the old state of the platform back within minutes. My cable provider was obviously completely unprepared. Switching everything off was done within minutes, reinstating the contract made them struggle.

The next day was Friday. I had some work to finish on the weekend as well and was hellbent to get the company to get its act together. I called tech support, directly escalated to second level and told the lady: “Look, you guys pronounced me dead on Monday and cancelled my contract. My wife is at home with a sick kid, completely cut off from the outer world since Monday. If you don’t reprovision my modem within the very next 2 hours, I’m going to clear the situation with your head of PR.” – “Yeah, well, you can do that, but first, give me your contract number.”

In fact, I had entered the number before starting the call. (see lesson 5 for helpful remedies)

I gave her the number and she kept me in the line for 5 minutes. After that, she told me that “they are sorry and they are doing everything they can”. I should have some more patience, because she could not “accelerate anything”. I told her my patience was completely over and that she had exactly one hour and fifty five minutes to reinstate my contract – and if she did it in person. I hung up.

Lesson 7)

Have a priority line in order to deal with urgent requests in your technical support queue. Some requests might be too important to wait in line together with all the others.

In contrast to Kabel Deutschland, I keep my promises. Three and a half hours later, after confirming our wi-fi at home was still dead, I wrote a quick personal message to their Head of PR, telling him that I will go public with this story if he didn’t answer that very day.

He didn’t.

Lesson 8)

Take your customers serious. Enough said.

I still have no internet. Let’s see what Monday brings.

Will Darkmail Be Secure? Probably, but It Doesn’t Matter.

So there’s currently all the rage about the Dark Mail Alliance, re-inventing electronic mail in an easy to use, fully decentralized and cryptographically secure fashion. I think there are some brilliant minds on the project and I personally wish them the very best.

A few months ago, there was the first true spiritual successor of the original Skype called Tox in the making, and I can’t even pretend all of this this isn’t great news. Finally the FOSS community wraps up DHT’s, strong crypto, hole punching and even video – just like the original Skype – and puts it into a nice zero-configuration package. The project is getting well deserved publicity, crypto expertise and UX love, and is predestined to take off soon in times of PRISM-raised consumer awareness.

So why am I still not excited?

Because we’ve progressed to far. Laws worldwide have been hollowed out from steady lobbying since 9/11 – and it helps to look into the past to predict what will happen next.

Tox and Darkmail are already on the shortlist of every TLA (three letter agency) worldwide. What happens if you use it? Guess what – you’re officially making yourself a preferred target.

A great read on this topic is PHK’s “More encryption is not the solution” that goes much more in depth than this article and I admit I couldn’t have written it any better.

But to phrase my concern in my very own words: You can still trust the math behind cryptography – but it doesn’t matter at all. What you can’t trust on in 2013 is your device manufacturer, your carrier, your operating system and your e-mail provider.

And especially if you’re a second-class citizen of the world (or you are from the US, and your traffic somehow gets routed outside US jurisdiction), the NSA won’t give a shit on breaking all international laws to get to the messages you are sending and receiving. Not only did they self-excempt themselves from international jurisdiction like just a few other states like Cuba or North Corea – they are not even liable to any of their actions to their own people.

So who will use the new strong cryptography tools? Here’s my prediction: 20% curious minds and technologists, 40% who have something to hide for good reason, 40% who have something to hide for bad reason. The big masses won’t care. And as long as you’re not using a more exotic device, carrier and operating system – preferably not even from your own IP as to not have blown your cover by the mere fact that you are using encrypted traffic – you can bet your ass they will go after you to have you lynched in the public.

So what’s coming up next? Voice processors. After Facebook helped indexing anything that you expose to the public and Dropbox went along with implicit “free photo sharing” to the NSA, their next target will be everything you didn’t even want to expose. Uploading hours and hours of voice communication is still too obvious by looking at your phone bills, but 24h of your verbal communication in an encrypted zipped text file after your device’s built-in speech recognition (of course together with GPS location info) will just disappear in the data noise of always-connected “factory” and carrier daemons and is easier to process for real-time analysis anyway.

Make no mistakes – the on-demand “roving bug” is already a reality since 2006 – this will only take it to the next level. Even switching your phone off will not protect you, but rather make you a hard target again.

Privacy in the near future will be at places where you don’t have a smartphone – and nobody around you does either. It will be as hard to find as diamond and impossible to stop if we don’t start acting on a political level soon. And to quote my favourite political satirist, Volker Pispers: “Politicians in Germany always say: Why not collect all the fingerprints and save them in a database? The Spaniards do it as well! – Do you actually know why? It was done by a dictatorship (Franco) and fell into the hands into a democracy. No problem – except if it happens the other way around…”

If you’re not scared yet, do yourself a favor and watch the ingenious “The lives of the others” to get a grip about what a real dictatorship managed to do with 1980’s technology already. Put more than thirty years of technology evolution on top and you’ll be scared shitless. If you want to know why the Germans are always at the forefront of privacy protest, that’s why.

What’s going to stop all of this? Not Tox. Not Darkmail. Simply people standing up all over the world to stop the madness.

And honestly – I don’t see that coming.

The Horrifying State of eGovernment in Germany

Working and living in Berlin, one of the current major hubs for startups and innovation in Europe, I’m used to teams of a handful of people building globally scaling platforms in just a handful of weeks with a user experience so great that I’m almost taking it for granted.

A few weeks ago, I took a forced detour from the bubble.

Backstory: I used to freelance for smaller IT and media design gigs with my own company, but since starting to work full time in a startup, there wasn’t much more time to do so. Because I knew German bureaucracy is quite strict on freelancers not generating profit for years in a row, I just wanted to officially dismantle my company.

I already knew I didn’t want to show up in person anymore, as the respective administrative office is far away and the opening hours are plain hostile to any working person. So I googled my way around and saw that there’s a standard form you can download, fill out and send by snail mail, together with some copies of your documents. But hey – they were also offering the “online treatment of the service”!

Being a little too curious and naïve, I clicked on the link and followed down the rabbit hole…

2013-05-26, 23:10 CET:

After finding the well-hidden registration link after five paragraphs of legalese and stilted introduction, I’m able to register my first eGovernment account at EU-DLR. Yay. At least they’re confirming my mail address, so I’m continuing by clicking the link in the mail.

I’m greeted by a notification that tells me I’m “accessing the site out of business hours”.

Wait. What!?

They’re serious. Basically everything out of standard business hours is defined by them as a “(possible) maintenance window”. If the server crashes, it means basically waiting till someone fixes it only the next day. (How often it actually crashed, I found out over the next days and weeks)

I’m giving up for today.

2013-05-27, 19:30 CET:

Trying to log in again. The system immediately logs me out. Did I do a mistake? I’m trying again, with the same result. Switching from Firefox to Chrome. Same thing. Maybe I should really “try Internet Explorer” as suggested? If only it wasn’t for the fact that it’s 2013, I’m on OS X and Microsoft made the world a better place in 2005 already by discontinuing IE for Mac.

Before considering to use my girlfriend’s Windows computer, I’m trying Safari. It seems to work now.

I’m “opening my first case”.

Think of everything you know about usability and user flow – and then try to imagine a site that has been specifically crafted to ignore every single best practice in the field.

The workflow is a seemingly never ending series of small forms that each have a “next” button. Every click on next lets me wait almost one minute before continuing. Somewhere in the middle of the 5th form, after 2 minutes I’m getting back a raw, unfiltered, unstyled “500 Internal Server Error”. In English, that is. Fortunately I’m only half as confused as the average German business owner using this “service”.

I can’t reenter the site. Giving up again for today.


I’m discovering that there is no way to access “my cases” by logging into the site normally. After the standard login, there’s no way for me to do anything else but read the FAQ. Only by clicking the link in the activation mail or typing in the correct URL, I’m able to enter “my case”.

Insert coin and try again.

This time, it’s only taking 10 seconds after each next. In one huge form, I need to enter all my data. Address, Phone number and so on. Finally, the last step in the workflow appears:

I’m able to download the very form I should have sent by snail mail from the beginning – and of course, it’s NOT even prefilled with all the information that I just entered.

Exhausted, I’m following the instruction, printing it out, signing it, scanning it into a PDF with the standard OS X Preview app and uploading it to the “my case” page.

It’s a pattern that’s constantly reoccuring: Instead of taking the opportunity and simplifying online access for citizens and business owners, the process has been designed to resemble the Government’s paper workflow as closely as possible, with all the bells and whistles on top that they think they need for “secure” interaction. Hell, they’re even still writing all about mailings, forms and documents.


I’m getting a ticket number manually assigned. Whew – something’s moving.


I’m getting a message by the system: “There’s a problem with your case”. After only 10 tries, I’m successfully logged back in again and see that apparently they can’t read my document. Weird. I’m reuploading the PDF.


Same thing: They can’t read my form. Again. Apparently ISO standardized and validated PDF files are way too unstandard to be read by government agencies. To top it off, when I’m clicking the link to my uploaded and signed form in the interface, I’m actually seeing the correct PDF document in my browser. How can’t they not see or access it? This is just frustrating. Dumb actually. I’m done here.


“Your case was closed by not answering our request”. Yeah, whatever. Total time clocked so far: way more than 3 business hours. I wish this was billable.


I’ve had enough. I’m doing what I should have been doing all along. Printing out the business dismantling form from the very first page and a copy of my ID, signing and stamping it and sending it by snail mail. Total time clocked: 10 minutes, 55 cent postage.

Sidenote: This could have been for free with signed e-mail as well. I even have the new German “electronic” ID with signature chip and a reader (introduced in 2010), uniquely identifing me as a German citizen with full cryptographic proof.

However, there’s nobody to send it to: The government agency still can’t receive signed mails “for technical reasons”.

Never would have thought I’d ever think of sending snail mail as easier than handling my business online.


Having long forgotten about this major disappointment, that day I’m coming home and there’s registered mail in my postbox: An “Androhungsbescheid” (literally: “Threatening Notification”), telling me that if I don’t re-upload the PDF, I’m subject to a penalty payment of 500€.


You can’t read the most standardized document format on the planet, you provide me an interface whose only purpose is to steal my time, I’m sending you everything by mail, you can’t even find it and put the files on my case – and now you’re even threatening me?

I’ve lost it. Okay, so what to do now? The two times that companies actually made me lose my composure by extreme amounts of insolence, I immediately dealt with their press department by issuing a credible threat of massive public shaming, leveraging my former media agency. Up to now, I’ve always won – and more.

This time it’s hopeless. Researching half a night, I’m realizing that there’s simply nobody to complain to. There’s a single method of complaint against people or actions of the German government, called “Dienstaufsichtsbeschwerde” (disciplinary complaint) that’s commonly taught to law practitioners as “formlos, fristlos, fruchtlos” (informally, without notice and pointless). Everyone can write one and exactly nothing will happen. There’s just a giant moloch that’s refusing to move.

This time I’ll just play along, reopening my case and reuploading the PDF in every image format that has ever been invented from BMP to DICOM in the hope of being accepted – and only leave this blog post as an exhausted note of protest to someone.

I’m an IT guy with some pride and attitude left. Whoever designed this system’s UX, technical base and business processes would immediately have been fired from any of the companies I’ve ever worked for due to total incompetence. Who does things like this to humanity? How much do they get paid? Where’s the accountability and common sense gone in projects like this?

I’m a loss of words. There’s only so much for me to say:

“Dear German government. The best way to grow and keep the economy is to not utterly frustrate and stand in the way of the people who actually grow and keep the economy.”

You Probably Have Too Much Code.

There’s a recent trend in the software industry that I’m watching with a little concern. Countless new tools for static code analysis and “automated software review” are popping up on the market and being in a technology leadership position at a successful startup myself, I’m now getting pitched for this stuff on a regular basis. Even though I’m absolutely dedicated to code quality, I’m very skeptical at these tools – because, in my humble opinion, they are trying to solve the wrong problem. There’s an uncomfortable truth that I’d love to tell all companies seriously seeking to relieve their code quality pains by using these methodologies:

You probably have too much code.

The problem at the root of this issue is a decades-old industry focus and incentivization on producing code, not on taking it away. If you give a problem to a developer, there’s a usual and deeply embedded Pavlov reflex of solving it by writing or adding code. It’s what a software developer is paid for anyway, right?

Less is more

All these are signs of a dangerous culture that encourages software bloat, steadily leading to slowed software development up to a state of total unmaintainability. If you don’t believe me, go take a look at the 3.5 gigabyte (!) binary of SAP BusinessObjects Explorer. I’ve seen so many companies grinding to a halt by throwing software layers on top of each other, that I’ve coined a name for it: Death by Abstraction.

Why you need less code

Less code –> less errors. Period.

There are recent studies showing once and for all that the density of software errors is most strongly correlated by the number of lines in the module, regardless of the language used. Having less code makes projects stabler, leads to better test coverage and simplifies operations. It also helps to use a language that is as terse as possible (we love Coffeescript).

Less I/O

Code doesn’t just have to be written – it has to be read as well. Reading and understanding code takes time, lots of it. (Paradoxically, large, complex and fragmented code bases tend to have a lot of large, complex and fragmented documentation to read on top.)

Time however is usually one of the most valuable and rare ressources in the software industry.

Having less code helps you onboarding new developers on a project and getting productive way faster, and in the same way also helps with turnover. Most importantly, it prevents complexity by “code fear”: If people can’t understand other peoples’ code, they tend to abstract it away. This is the exact reason monstrosities like CORBA were born in the first place, feeding the code-adding cycle once again. I’ve been in companies where projects had to be abandoned because of people being scared to touch a recently “disappeared” employee’s source code. Writing less codes helps preventing such disasters in the first place.

How to get and write less code

Incentivise and encourage a “taking away” mentality

I can’t overstate how important it is to continuously fight against the code-adding mentality itself that still resides in most developer’s heads. Put into your core values, acceptance criteria and processes that taking code away is just as important (if not even slightly more) than writing it. Every net code line and file added is a maintenance liability.

Simplify requirements

If you are designing a software component to solve all of your current and future problems at once, you’re setting yourself up for failure. Solve the problem at hand and nothing more – if in doubt, you ain’t gonna need it.

Clearly separating your problem domain and constraints enables you powerful shortcuts. If a part of your internal tools does not need to be in the customer facing dashboard, you can save yourself half the development time by getting away without pixel-perfect design mockups, OAuth authentication, less QA, less testing… you get the idea.

Generalization is usually the enemy of lean software. One of the best strategies is to force yourself to generalize “on demand”. Start with all assumptions and shortcuts neccessary to make your life easier right now and follow the old adage “One, Two, Three, Refactor”. Don’t worry too much about “later” – more often than you think, you’ll come up with an even more elegant solution anyway.

Challenge frameworks, libraries and abstraction layers

Separation of Concerns is incredibly important – but so is keeping a code base maintainable. Coming from a Java shop with nightmares of SOA done wrong, we had a grand vision of a one-page dashboard in Backbone and Chaplin.JS served by a fancy Collection+JSON API as Broadway.JS application on top of a Sequelize ORM.

In the end we saw we had so many dependencies and “magic” happening behind the scenes that displaying simple things from the database in the dashboard took ages in development – we realized we had made a 2013 version of the same mistakes in overengineering we were committed to not repeat. We threw out nearly everything and now use pure Backbone.JS on a lean, hand-built JSON API, tripling development efficiency.

Don’t believe in hypes. Believe in simplicity.

Take a step back

If you regularly look at the big picture and question the compartment and component borders inside of peoples’ heads, you’ll often find that modules do duplicated work, can be merged or could be thrown away altogether. Be bold and go for it when there’s an opportunity.

Fight complexity all the way

The sooner you realize that code is as much a part of the problem as a part of the solution, the sooner you can start coding less. If the solution to your problem can fit into a plain old class, don’t encapsulate it with the newest MVC framework or instantiate an AbstractSingletonProxyFactoryBean around it “just because”. Seriously, keep it as simple as possible – but not simpler.

I may be a heretic here, but if you look objectively at the Gang of Four patterns, you’ll realize that most of them were designed to lessen the pain of adding more code to a project involving many developers by adding more code. And that’s okay, remember they come from an era without Git, TDD and Continuous Integration. They can be powerful at times, but they often serve as fuel for the vicious and self-serving cycle of software bloat. Use them wisely, but not for their own sake just or to look professional.

Continuous Rewrite

I’m a big believer in Continuous Rewriting and it also seems to pick up adoption lately. If instead of going all the way, you start out with a prototype that’s meant to be thrown away, you achieve a lot of important goals:

  • You free your mind from having to deliver the final solution and iterate fast, casually adding tests as you go.
  • You protect yourself from abstracting too much and prevent adding “fixtures” for possible future use.
  • You will have solved (a part of) the problem with working code and have validated the technical feasability of all aspects.
  • You learn a lot about the stuff that works and scales and the stuff that doesn’t.

Now if you have separated your problem domain properly and have tests for business rules, it’s easy to take all the knowledge you’ve gained to not just refactor and extend the component but to completely rewrite it, simplifying the internal design to the maximum. This way, we have rewritten our core matching component three times already – from 3000 lines of Java to 600 lines of Python to 200 lines of Coffeescript, while still adding functionality and scalability by a factor of 200.

Pair programming and code reviews

Pair programming and code reviews are the best tools to prevent people from reinventing the wheel, continuously update each other on best practices, simplify code and reduce clutter. Both techniques directly as well as indirectly lead to less code – they guarantee that someone else will understand and have read the code and reduce “code fear” by an order of magnitude. If you find you often don’t have the time to do pair programming and code reviews, you probably should do more of it.

More tips?

I’m curious, so be sure to let me know in the comments!

Cache Invalidation Made Easy

“There are only two hard problems in Computer Science: cache invalidation and naming things.”

Phil Karlton

Full disclaimer: No, I didn’t find the perfect solution either (guess it’s an NP hard problem). For a lot of use cases, one of the generically applicable patterns I like best is explained very well by DHH – my problem with it was that it does not cover the case when entity content changes under the very same ID. I will show you another nice and generic pattern for just this purpose for you to have another trick up your sleeve.

For us, the key problem was about distributed tracking applications caching metadata about the campaigns or images we’re delivering. For example, if a campaign manager needs to change the URL, the tracking application needs to redirect to another target. As the tracking is high volume, caching was a no-brainer. For cache invalidation, we settled for a pull approach of one minute refreshes from the database first, which could unfortunately serve stale data and obviously wouldn’t scale with growing numbers of entries and servers.

Now instead of custom-building something ourselves, we thought of a more generic approach – and for us, it boiled down to a dead simple convention.

How it works

First step, set up a messaging service. If you’re on Amazon like us, SNS (+SQS maybe) fits the bill perfectly and is set up in minutes, otherwise you might consider RabbitMQ or any AMQP provider.

Second step, create one topic for every entity with the same name.

Third step, follow an easy convention:

  • Everyone who is mutating this entity (with us, it’s just the API, making things even easier) publishes the entity ID to the topic after writing to the database.
  • Everyone who is caching this entity subscribes to the topic and re-pulls the instance when a “dirty” ID comes in.
This approach is so beautiful for a lot of reasons:
  • Loose coupling. There are no hard dependencies between any apps following this pattern, but they all work together magically with no stale caches
  • Very easy to convert from a pull-based system
  • No to low security hassle. Data never goes through the queue, only IDs
  • Added plus for SNS users: You can safely leave the dirty work of monitoring and reliably keeping up a messaging system to Amazon.

Caveat lector: Obviously this approach will probably only be viable for medium- to low-volume core and master data. For caching and invalidation at several orders of magnitude higher, you’d probably be looking at specialized solutions and optimized modelling (Cassandra, S4 and the likes). Also, be careful as this eventually consistent solution still has some low but unknown amount of time where the cache will be stale. So if you’re absolutely dependent on consistency for a problem domain, there are few other ways than disabling caching altogether.

Careful With Cassandra Upserts

A nice thing about Cassandra is the easily understandable data model: There are just upserts – an insert will automatically update / overwrite old rows. This does NOT hold true however in every case when using dynamic columns, as Cassandra does not have the same concept of a “row” as a traditional database.

Essentially, a Cassandra “row” is just a double hashmap. One layer goes to the key and says exactly on which server the row is, and the column key says where on the server the column is. This very flexible concept can lead to a problem later on though when some of the columns are different.

Here’s an entry in the “Employees” ColumnFamily:

employee_id: 599 (KEY)
name: "Larry Page"
age: 46

Now for various reasons, we have to update employee 599 with another denormalized person:

employee_id: 599 (KEY)
name: "Sylvie Stone"
devices: ["MacBook Pro"]

Sylvie didn’t tell us her age (she’s a lady after all!) and for new employees, we’re also tracking the devices we handed them. When we’re upserting employee 599, a lot of people with SQL or a document-oriented database background are expecting to have the second entry in the database. That’s not true at all unfortunately – what we will find now is this:

employee_id: 599 (KEY)
name: "Sylvie Stone"
devices: ["MacBook Pro"]
age: 46

Welcome to the world of column-oriented databases – and before you think “WTF”, think about it for a moment. This is expected behaviour and part of Cassandra’s “independent columns” paradigm. Even if it looks like it in CQL, you never actually overwrite rows – you overwrite the columns behind it.

So how to avoid this? You just need to model your data properly or navigate around it. As Cassandra columns are way smarter than columns in other databases, there exists a way to correct for this effect in case it’s needed. How? Look under the hood. What Cassandra really stores is this:

"599": [
    {name:employee_id, value:599, timestamp: 1340385863990010, ttl: 0},
    {name:name, value:"Sylvie Stone", timestamp: 1340385863990010, ttl: 0},
    {name:devices, value:["MacBook Pro"], timestamp: 1340385863990010, ttl: 0},
    {name:age, value:46, timestamp: 1340133763990010, ttl: 0}

As you’ll have imagined, Sylvie is relieved she’s not really 46… the entry is simply older than the rest of them, but was neither deleted nor overwritten!

Every decent driver for Cassandra can expose the timestamps and TTL’s as well – and there’s your solution to clean up the mess in the “eventually consistent” paradigm that the database follows: If it’s not the same timestamp as the key, simply discard the column (you’re free to delete it as well).

And don’t worry, this added hassle in handling something that would be considered a no-brainer with more conventional databases is more than worth the flexibility gained with Cassandra’s independent columns. More on advanced data modelling leveraging this power will follow!