10 common Adwords mistakes by business owners

December 10th, 2017

A few months ago I decided to get back into experimenting in Adwords advertising for both my day job and Observu website monitoring. I quickly learned that Adwords is very good at letting you pay for low value traffic and making you believe you are doing a good job.

1. Mistake clicks for success

Clicks are traffic to your site and this can only be a good thing, right? Yes, if you weren’t paying through the nose for it. If you are paying EUR 2,00 for a visitor that spends 5 seconds on your site and then hits the back button that is just throwing away money.

To start, you need to monitor conversions (pretty much everyone uses Google tag manager to set it up) such as submitting your registration form, buying a product, etc.

Make sure to add the ‘number of conversion’ column to all your adwords reports so you can see which clicks get you conversions

2. Not check actual search terms regularly

Another way to see the value of your traffic is to religiously check the actual search terms visitors used before they clicked your ad. You may think you are getting clicks for interesting keywords, but Google may be fooling you with their reports. e.g. I advertise on a broad matching keyword: website monitoring. What Adwords sends me traffic for is someone that searched for: compare monitors online. It’s highly unlikely that this is someone interested in my product.

To deal with this you can either change a broad matching keyword to a more narrow match or add it as a negative keyword.

3. Pay for irrelevant traffic

This is a refinement on point 2. If you watch it closely you will notice that Adwords will send you traffic on people search for URLs .e.g. queries like: http www somewebsite com your keyword Often it’s very unlikely to be relevant, I therefore suggest to add the following negative keywords to every campaign that is not your own brand campaign:


4. Overpaying for mobile clicks

In my experience there is far less value in mobile clicks, because on mobile Ads look even more like search results and people are very quick to (maybe accidentally) hit the first result they see. I therefore urge you too adjust your bid for mobile devices with 50% to 90%.

5. Use automated / enhanced bidding

Although these options sound great, what I’ve seen in practice is that Adwords most of the time just raises your bids to the maximum CPC you’ve set. With manual bidding you have much better control over what you are willing to pay. I suggest adding the [top of page] column to your keyword reports to select a proper price to bid.

6. Combine multiple keywords in a single ad group

An important factor in how well your ads are displayed is the Quality score. One part of this quality score is that your Ad text matches your keyword. Now when I first used Adwords I assumed that Google would match my keyword to the most fitting Ad I had in the group. This does not seem the case. Adwords converges to the best performing Ad in a group, independent of how well it matches the current keyword. Therefor the only way to force a relevant ad, is to make sure a group has a very narrow scope in keywords and use the keyword in the ad text. By doing so, the quality score will improve and the display likeliness and position of your ad will improve.

Further improvement can be made by creating a landing page for the ad group and making it highly relevant to your keyword.

7. Adding broad matching keywords

As I already mentioned at point 2. and 3. if you use broad matching keywords, Google takes a lot of liberty to show your ads. Now this has it’s advantages, such as also matching searches for competing products. But it also triggers a lot of irrelevant traffic. It is therefore strongly suggested to only use broad matching keywords to discover more specific relevant keywords. In my case, instead of just using: website monitoring I use:

+website +monitoring
“website monitoring”
[website monitoring]

Phrase match (second item) is the closest to what you would normally expect Google to do. Using all three variations allow to bid more for people searching for the exact keyword.

8. Forget checking the quality of conversions

If you followed the recommendation to track conversions, it’s easy to assume every conversion has a value. That’s not the case. e.g. if someone fills out my signup form, but never confirms their e-mail, is there any value? What if they sign up, but then contact support and you figure out they intended to do something else. (e.g. sign up for a different product with a similar name)

Ideally your signup/buy process should capture the adwords campaign it originated from (e.g. using the __utmz cookie) so you can identify which campaigns result in these bogus conversions.

9. Mixing low and high cost keywords in a single campaign

One of the struggles with Adwords is getting to a CPC that is low enough so it works for your business. Once you found some low cost, high volume keywords they can provide a steady stream of traffic. Some keywords may be more relevant and you are willing to pay more for it, that’s fine. However, if you combine these two in one campaign under a single budget, this means that that one EUR 3 click, just cost you the 10 30 cent clicks you would normally have.

10. Not using a dedicated campaign for your brand name

If you need to advertise on your own brand name (e.g. a competitor is stealing your clicks by advertising on it). You need to do so in a separate campaign. First, someone searching for your brand has very different characteristics, this will skew your conversion metrics. Second, this is easy, highly relevant traffic, you don’t want to miss out on this because you ran out of budget due to other keywords.

I’m by no means an expert, but just checking your account regularly for these mistakes can drastically increase the value you get from your Adwords budget.

Testing User Sessions with Flask Elegantly

August 17th, 2017

There is excellent information available on testing Flask e.g. http://flask.pocoo.org/docs/0.12/testing/

One thing I ran into was the need to set up a user session for most of my test cases.
The documentation suggests something like:

with app.test_client() as c:
    with c.session_transaction() as sess:
        sess['a_key'] = 'a value'

but repeating that in every test case (especially with a bit more code to set up the session) is not really DRY.

Now the same documentation suggests a very elegant trick using context managers for setting up users on the global object:

from contextlib import contextmanager
from flask import appcontext_pushed, g

def user_set(app, user):
    def handler(sender, **kwargs):
        g.user = user
    with appcontext_pushed.connected_to(handler, app):

Inspired by this, I figured that they can be combined into:

def user_set(app, user):
   with app.test_client() as c:
       with c.session_transaction() as sess:
           start_user_session(sess, user)
       yield c

and then use it in a test like:

user = ...
with user_set(app, user) as client:

Getting Yourself Unstuck When Programming

July 17th, 2017

Everyone who has ever coded anything significant  (and probably everyone who has ever done anything that requires creativity) will recognise the problem of getting stuck. Most of the time it is caused by lack of information or confidence to move forward. Over time I’ve identified a number of reasons I get stuck and also strategies to deal with this.

Perceived Dependencies

In larger systems, components often have to interact. If none of these components are properly defined or all need changes, it can be hard to get started.
Strategy: Fake a little, build a little.
It’s tempting to start things from the beginning and just write the code sequentially, however if things are not entirely clear it can work very well to start at a very very high level.
I usually just outline everything in 3 to four steps, each being a commented line. For example if I need to classify emails into categories, I might write something like:

// get e-mails
// get defined categories
// classify e-mails

Then write each step as code. This is the time you will need to start thinking about how data is passed around. Whether you will need objects or just lists of strings, etc.

// get e-mails
emails = get_emails()
// get defined categories
categories = get_categories()
// classify e-mails
classifier = new Classifier(categories)
for email in emails:
    scores = classifier.get_score(email)
    category = get_top_category(scores)
    print email.title, category

To test these assumptions you will need to actually implement the functions/components you’ve used. However, key to this strategy is to now fake these functions/components as much as possible.
e.g. I may implement get_top_category as:

def get_top_category(scores):
    return scores.keys()[0]

The reason to do this is not because I don’t know yet how to implement this, but because I don’t want to get stuck in details. (e.g. what happens if there is a tie, what if all are zero, etc etc) Things become so much easier when you have an end-to-end solution that just compiles.

Can’t wrap your head around it

You all know this feeling, but the cause is less clear. Ill defined tasks,  generic approaches,  feeling tired,  they all can lead to this.
Strategy: Second Pair of Eyes
Not everything needs to be solved on your own. If you are not clear on the ‘what’, just talk to a coworker, manager or customer. If you are not clear on the ‘how’ just start explaining to a coworker why you can’t move forward on this.
A very important part of this strategy is the need to explain and define your problem. Even the act of just explaining it may resolve the issue. In that case it’s called Rubber duck debugging: the act of explaining your problem to a rubber duck.


This is probably the biggest show stopper:  as soon as you are aware that there are multiple options with various tradeoffs, it’s hard to proceed.   I’ve seen bad programmers finish things quicker, just because they were happy with any solution that worked, in their universe there were no trade-offs to be weighed.
Strategy: Writing
If choice and tradeoffs are involved, you need to start writing. Just create a document with bullet lists of:

  • Everything that is already given (e.g. API urls, relevant documentation)
  • Requirements
  • Important conditions (e.g. needs to work when device is offline)
  • Potential issues (e.g. there may be too many items to fetch in a single API request)

Then for each of them come up with at least two approaches. Then for each of them also add potential advantages and downsides. And then again for each downside, figure out how to solve it.
For me this usually becomes a nested list of four or five levels.

One of the big advantages is that you can leave this for the next day to refine, without having to start all over again in your mind. Furthermore, you can easily refine this into documentation after the decisions are made.


The idea of heaving to spend days to do some boring, semi-repeatable task that could have been avoided when better choices have been made in the past  can certainly demotivate you.
Strategy 1: Embrace it
Sometimes you’ve got plenty of energy, but can’t really move forward on an issue (e.g. due to one of the reasons mentioned above) this is the perfect time to do this boring task you’ve been putting off. It is 100% clear and every minute you spend on it will actually move you forward.
Strategy 2: Make it interesting
Boring things are also often the things that are easy to automate. This might be the right time to learn more about:

  • advanced find/replace features in your IDE
  • find/grep/sed on the commandline
  • UI automation

Strategy 3: Delegate
What is boring to you, may be a nice task for someone else to learn a new skill. e.g. writing UI tests might be boring, but it can be a valuable and marketable skill for your intern.


Lots of people get stuck on finding and fixing bugs.  But remember, in debugging there is always a next step to take.
Strategy: Identify and check your assumptions
At the root of every bug is a bad assumption. This can be an assumption on what your code will do, the contents of a variable or the correctness of an external dependency. Debugging is just identifying your assumptions,
I’ll write a follow up post on debugging strategies soon.

Why developers should do customer support

March 31st, 2016

As a developer, I don’t particularly enjoy customer support. Questions are either about things that are obvious (or should have been) or about things that I don’t have a clue about either and need a lot of investigation. Some customers are just plain rude with “it’s not working” in the subject and nothing else.

At first sight it seems to be a huge waste of your expensive developer time to spend time on this. However, I strongly believe you should. Not only do developers bring value to the customer by providing more knowledge and understanding about the product. Providing accurate support is a guaranteed way to turn dissatisfied users into your most loyal customers. It also helps improving the product thus reducing support requests and increasing customer satisfaction.

Read all 5 reasons why in the full article

Fix your PayPal PHP IPN script

January 23rd, 2014

In October 2013  PayPal changed a bit of their server infrastructure. They announced it well, with multiple warnings about requiring the Host: header to be sent with verification requests.

Now suddenly my PHP IPN scripts did not work anymore, data was coming in but nothing got verified.

Checking the response quickly points out that PayPal is now redirecting requests to use HTTPS, but our old scripts are still based on years old example code using fsockopen on port 80.  fsockopen doesn’t know about HTTP redirects.

So, to get your PHP PayPal IPN notifications working again, you should replace the fsockopen line with:

$fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30);

Update: A few days later things stopped working again… it seems PayPal now adds a newline character behind the VERIFIED response, messing up the sample script. This can be resolved by replacing:

$res = fgets ($fp, 1024);


$res = trim(fgets ($fp, 1024));

Obsessed about monitoring

February 10th, 2013

For the past two years, I’ve been working on one of our products: Observu,  a site and server monitoring platform.   The last year we’ve applied it to our existing sites and customers and now we feel it’s ready for others to see and use as well. It took a bit longer than anticipated, due to other projects and responsibilities taking up time, but we’ve always kept determined to get Observu ready to launch.

If you are interested in improving your availability, response times and quality of service in general, check it out at http://observu.com/

I definitely do not feel like we are done now, having it out in the open now is just the start to find out which direction we should go.  We’ve got so many ideas, but we can’t execute all of them right away. Your feedback will be greatly appreciated and help us guide further development.

Startup/Product Blog Inspiration

May 2nd, 2011

It has been common practice for years now for startups to blog about their new product and its development. It’s one of the key methods to keep your future customers informed. However, as soon as you find yourself in the situation to blog it can’t hurt to have some inspiration.

First, I’ve selected blogs that seem to post regularly and have some traction. The blogs I choose are: kissmetrics, pingdom, flattr and joelonsoftware. After some reading I extracted the following topics from these blogs.

  • Press coverage, if you’re product was reviewed in a paper on an important blog, this can validate your product in the eye of the reader. You are not just an anonymous product, but a serious contender.
  • Jobs, listing job openings shows that you are growing, this can be interpreted as a sign of success, people don’t want to buy from someone that is loosing.
  • Important News, besides the obvious point of informing your users, posting news on your blog will also provide reference for those interested in spreading your news even further.
  • Development Progress, especially if there is not much happening on the outside, it’s good to show that you are still committed to the product. People hate to invest effort in something that’s dieing.
  • Development process/tools, if your target audience is also in the developers arena, blogging about the process and tools can be the start of a relationship. You’re not just a company trying to sell them something, you are a colleague, with the same problems and challenges. JoelOnSoftware mainly focuses on this and is great at it.
  • Niche Related Articles, becoming a resource for your potential customers, without directly selling your product by posting articles related to your product niche is a great way to gain a bigger audience. Kissmetrics does this exceptionally well.
  • The same goes for Best practices/tutorials. Especially if they become easier by using your product, but do not require it.
  • Infographics are very effective link-bait, again Kissmetrics is very strong in this area.
  • Reports/Research based on your data or questionnaires may get you press coverage when executed correctly. Pingdom is regularly featured in mainstream newspapers as a source. A very smart form of promotion.
  • Industry News could also widen your reach, but it will probably require a very very persistent approach to become an authority in your niche.
  • Repost stuff from the internet is a very common tactic often in the form of round ups like: “the best 5 SEO tools” or “10 must visit design resources”
  • Interviews can come in a lot of different ways, you might interview your team members, important customers or an industry bigshot.  Of course the latter is more likely to get you some extra audience.

I hope this listing will inspire you to post more regularly, it certainly inspired me.

Review: Pivotal Tracker

April 16th, 2011

For Observu implementation we are using Pivotal Tracker to keep track of features and progress. I’ve posted a full review on our Observu Blog. To summarize:  the idea of having a single ordered list of features instead of just a bunch with priorities is amazing. It gives you so much more information and forces you to make decisions on what really needs to happen and what needs to happen first.

Competition Anxiety

March 16th, 2011

If you start a new product/website/service  it’s wise to know your competitors.  Find out what they offer at what price and quality. There is nothing wrong with that.

However,  it’s easy to fall in a different trap: get the feeling that you need the same features as your competitors have.  This leads to three problems:   you loose the big picture,  the grown feature set feels like a burden and you’ll get a me-too product.

Instead of focusing on features,  focus on marketing and positioning. Are there gaps?  Untargeted niches,  untried approaches? Only after that,  look for those key features that will attract those customers you want.

Idea Overload

February 10th, 2011

You’ve got so many ideas in your head that you just don’t know where to get started. As a result, you start procrastinating on stuff you do feel passionate about. At the same time, you’ve got enough energy and are motivated to get stuff done.  It’s a bit contradictory state of mind, that happens to me once in a while.

The problem is anxiety to commit to one project and  even more so: leave all those other things alone.  I believe the key to overcome this problem is to start on anything.  In the end it does matter much more that you’ve made progress and added value than it matters which choice you make.

Of course, that’s easier said than done. ‘Pick anything’  is still a choice and choices are hard. Therefore I use a very simple solution:  pick the easiest task that still adds value.   In the end you probably will have to do all those tasks anyway, so why not start with the easiest one?    Especially  in programming,  getting anything done, will give you more context to solve the next task.  Tasks that may have seemed daunting at first, become easier and better defined when the system around it takes shape.