Sunday, August 16, 2015

DIY Call Center with Call-Forwarding

One thing most startups need, but can't afford to spend much time setting up: a hotline.

We first started with a phone lying around the office dedicated to the hotline. This is very easy to set up and is also cheap. The problem we faced: who answers the phone after office hours (a startup might want to support customers even on weekends)? No one it seems.

The solution to our problem was a DIY call center, based on Twilio: customers call a number hosted by Twilio, which forwards the call to up to 5 different phone numbers. The first one to pick up can speak to the customer immediately. This works fine for us right now, however, it also brings a few problems with it:

  • It seems the lag increases drastically (varies from call to call though) because - I think - the call always flows through Twilios datacenter first.
  • For the same reason (call constantly goes through Twilio) you have to pay although you're being called. No big deal as long as you only receive a few calls a day.
  • Nobody knows if someone else picked up eventually (nor do you know who picked up). This can be solved using a separate internal chat of course, but it should be optimized in the future.
  • If one of the phones forwarded to is offline the whole hotline is unreachable for some reason. I'm sure this could be fixed with some manual tweaking.

Setup is incredibly easy:
  1. purchase a phone number on
  2. configure the "Request URL" to be the URL generated by the Simulring Twimlet
  3. wait for calls
  4. ...
  5. hopefully PROFIT

AppEngine Datastore: Best Practices

After working with AppEngine and its Datastore for several months now (in production!) there's a few things I learned. Although I think you have to get some hands-on action first in order to fully grasp the concept and how to work with the Datastore, I think it's still useful to read a few tips first, keep them in mind and eventually implement them when you hit a wall for the first time during development.

The thing with consistency

It took me some time to fully understand "eventual consistency" vs. "strong consistency". This article describes it very well: Introduction to data models in Cloud Datastore

In a nutshell, eventual consistency does not guarantee when updates to the Datastore will be visible to your server, whereas strong consistency does. Usually eventual consistency is enough: fetching a list of products, etc. There is a very important usecase for strong consistency though: checkout / billing / everything that touches money. You don't want a transaction to disappear...

To put a long story to an end: use ancestor queries for strong consistency!

Speedy Datastore writes

Obviously, smaller entities are written faster than big entities. However, there's another thing that can slow down Datastore writes, even for the smallest entities: indexes! Imagine you have an entity with only a few properties, but index those in all variants (ascending, descending, etc): for each new and updated entity the Datastore has to update indexes accordingly resulting in - again - Datastore writes.

Here's how to calculate the cost of a write: Understanding write costs
And here's the overall process of saving an entity and updating indexes: Life of a Datastore Write (make sure to take a look at the articles linked in "Related links")

Tip: use indexes wisely (I usually don't create any until I really need them) and use unindexed properties for things you'll never have to query anyway!

Default values for all properties

Of course it seems convenient to use null-values for properties where there is nothing to save (yet). However, null-values are not queryable in the Datastore! Such entities simply won't show up in any query based on the property that's null. The only way to find properties with null-values is iterating all entities of a kind. Nothing you want to do repeatedly!

Upgrading your model and cleaning up your data

Chances are high you won't stay with your schema forever (sorry!). Whenever I need to adapt our schema I use the Remote API to iterate all entities and change them accordingly. Same goes for cleaning up a mess or setting "Default values for all properties" ;)

Easy refactoring and maintenance for Datastore-related code

There's two more things I'd like to mention, although they're not specific to AppEngine but good code in general:
  1. Keep all code related to the Datastore in a class (in the best case one class per kind) and do not scatter different queries across your whole code.
  2. In those classes per kind, store names of each property and the name of the kind as constants. This allows you to rename a property in a breeze!

I hope to be back with more tips as my journey with AppEngine continues...

Monday, July 14, 2014

Docker? Vagrant? What is everyone talking about?

Everyone has been talking about Docker a lot in the last few months - at least everyone at Hacker News (which is half of all geeks on the world I guess). I ignored the hype about Docker at first, because I didn't really get what the benefit is, but recently I got to play with it. I want to share my experience with you, so you don't have to spend a few hours tinkering with it but still know what it is about - and more importantly, what it is for. And while we're at it, I'll explain what Vagrant is, because it's really similar and what I ended up with using for my experiment.

What I was working on recently on a trip to France, was moving the development environment I use at into a "container". So if I ever got a new machine to work on, I just download this container and everything is automatically configured. "Everything" in this case means things like bash configuration (aliases, etc), dependencies (mvn, git, etc) and also downloading all the projects I need to start working efficiently. Within 15 minutes (depending on bandwidth available) I'm able to work like nothing has changed! Now think a little further: not only I can download this container, but all my colleagues can do it too! Instead of reading through our very scattered development environment setup-guides, they only have to download my container and wait for the magic to finish.

My experiment started as a Docker container, but later I decided to use Vagrant because it fits my needs better. Here's how I understand Docker and Vagrant.


With docker you can easily configure and run images of a Linux system. Think of it as a virtual machine, but a lot more lightweight - similar to chroot ("chroot on steroids").


Vagrant is very similar to Docker on a first glance. I'm sure there's a lot more to it if you use it extensively, but I see it as a layer above docker, because it actually allows you to use existing docker images - but that's only optional!

Docker vs. Vagrant

So while Docker only looks like a virtual machine, Vagrant actually is one. Vagrant spins up a new virtual machine for every image you start!
Why use a virtual machine like Vagrant does if you can have a lightweight container like Docker? Because Docker only works on a Linux host. There is boot2docker (for Mac and Windows) but for my usecase this didn't work, because you can't mount directories from the host to the container (Docker). That's because boot2docker actually starts a VM in order to run Docker. Already confused?

TLDR; for cross-platform images there's no way around at least one VM.

Use cases

What can you do with those two then? Docker is heavily used for servers in the cloud, because having lightweight images of your system is a good thing if you want to dynamically scale instances up and down. It's also used for making everyone's life easier by offering images with preconfigured common setups of some software: e.g. an image of a webserver which you can start using in a matter of a few minutes.
Vagrant seems to be less targeted at deploying production systems (webservers, etc) but for development systems (your development environment!). I assume it's used for more than that though because it supports  deployment to AWS and others out of the box...

By the way, you can also use vagrant boxes with a GUI. I don't plan to add things like eclipse to my box though, because I don't think that'd please everyone. People usually have their own, weird little eclipse setups which I don't want to overrule...

More on the status of my development box / container in another blog post!

Saturday, July 12, 2014

AppEngine Managed VMs hands-on

Google finally released documentation for a feature they publicly announced a few weeks ago already: Managed VMs for AppEngine. I knew from the first time I heard about it that this is going to be a great new addition to the Google Cloud Platform.

In case you haven't heard of Managed VMs before: it's pretty much exactly the same like Heroku. Google allows you to deploy your server on preconfigured VMs for easy setup, but you also have the freedom to do... pretty much everything with this VM. Compared to AppEngine, this is completely different: AppEngine has several restrictions in order to "enforce scalability" of your code (e.g. no local files, no threads, etc), but sometimes you simply need those things - even if it's only that you can't afford the time to modify your existing server code base so that it works in such a restricted environment. In that case, you want to use Managed VMs. You don't have as much restrictions, but you can still take advantage of some of the AppEngine-only features, like Datastore.

Another usecase of Managed VMs is if you want to use some exotic language / framework which AppEngine doesn't support. One example: Dart - although support for Dart on AppEngine is coming pretty soon I'm sure. With Managed VMs you are able to (automatically) configure VMs in such a way that it is able to host your Dart server.

One thing that I was really disappointed about when I read the documentation for Managed VMs is that currently only manual scaling of instances is supported. This means you don't have the advantage of a "real" AppEngine server, which scales infinitely if need be. However, this feature is "coming soon" according to Google engineers...

Minor annoyance: you configure VMs using XML. Yikes! So for example if you want to install git on all your VMs for some reason, you would have a config like this:
I'd have preferred to write a bash script or something, but okay...

From what I understand it seems that we will be able to use Docker-containers in the future to configure our VMs. That would be awesome indeed! (blogpost explaining Docker coming soon hopefully)

Google AppEngine Managed VMs are invite-only right now, but I think you can expect an invite within a few weeks or so if you sign up. When this eventually goes public it would make the question Google AppEngine vs. Heroku more of a question of pricing and which ecosystem you prefer, rather than a question of features.
And with automatic scaling of Managed VMs "supported in a future release" I can only recommend giving AppEngine a try!

If you want to find out more about Managed VMs I recommend you to take a look at the documentation first, followed by a glance at the Java sample.

Oh, and while we're at it: Google is giving away credits worth 500$ for its Cloud Platform. Simply go to and enter the code "GoogleIO"!

QuickTip: private GitHub repositories for free

Here's a quicktip for bargainers: if you want to host some code (or binary files, even) on a private GitHub repository but don't want to afford a paid plan, you can simply create a secret gist at and use that as a full-blown git repository. It is not a full-blown GitHub repository as you know it though. No pull requests, no issues, etc - but commits, diffs, branches, ...!

You can find the clone URL in the lower right corner of a gist-page. You can use that like you always do with "git clone URL" to get started pushing your code to GitHub. Make sure to use the SSH clone URL if you don't want to enter a password for every commit.

Edit: as pointed out by +Michael Haubenwallner in the comments, gists do not have access control like real GitHub repositories. This means that even if you create a "secret gist", everyone who knows the clone URL has access to your code! This is great for sharing code, but bad if you store sensitive data in your gist...

Edit edit: Oh well, turns out gists do not support directories. I was told BitBucket offers free private repositories though - directories supported! ;)