Banned from Google AdSense

Sudden bannings on AdSense – how it happened to me, how it can happen to you too, and how you can prepare your projects for it.

AdSense is one of Google’s flagship products and is a massive advertising network that allows online publishers to monetize their projects by serving ads on their content. AdSense can be used by website and blog maintainers, app developers (with AdMob – which sits on top of AdSense), and even YouTubers to make a living. 

Considering that in Q3 2019 Google reported nearly $34 billion in revenue from advertising even after sharing up to 68% of AdSense income with content publishers, it’s almost unfathomable how many small businesses the service enables. That also means that when those businesses come to depend on AdSense as their primary source of income, they can suddenly find themselves in hot water if they are kicked from the platform without warning.

Even before I became an AdSense publisher to monetize my Android apps roughly 5 years ago, I’d heard plenty of horror stories about publishers getting banned from AdSense seemingly out of nowhere. Some lucky publishers get a warning and a set amount of time to correct the problem. Others might receive a ban, but are fortunate enough to win the appeal process and get their account reinstated. Unfortunately for the vast majority of accounts, once you get hit with the banhammer you’re off the platform for good.

On December 16th, 2019 I woke up to an email informing me that my AdSense publisher account was non-compliant with the AdSense program policies and had thus been terminated. My entire account balance that I had accumulated since my last payout on November 21st (nearly a month of revenue spanning the busiest advertising season of the year) had been withheld and refunded to advertisers.

AdSense Termination Email - Enables Dishonest Behavior

Despite all the stories about AdSense terminations, I never my apps were at risk of suffering the same fate. 

I’m aware that the niche of my most popular apps might be a bit controversial. My biggest app (at about 100,000 cumulative downloads) is an exchange rate calculator for cryptocurrencies. The next most popular apps in my portfolio help people stay informed about state lottery scratch-off tickets before purchasing them. The scratch-off apps don’t facilitate the sale of lottery tickets or push people to buy them, they are just simple utilities for people to stay informed about the current state of the available prizes.

The policy cited in my termination email was “enabling dishonest behavior“. Even after reading through the full policy and the listed examples, like products that create fake passports or descramble satellite signals to provide free content, it’s not clear to me how my apps fall under this.

My best guess is that the scratch off guide apps resulted in my ban, but the termination didn’t cite any particular example with my content – just a link to the policy they allege I violated. I can’t prevent anybody from playing the lottery, but at the very least I can make sure people are more informed about exactly what they’re buying when they do choose to play. The data in the apps is all publicly available and provided by each state lottery organization (like Florida here). I don’t see it as dishonest or misleading to help prevent people from accidentally buying a scratch-off ticket with zero top prizes remaining, meaning they have literally a 0.0% chance of winning the jackpot. Furthermore, those apps are some of my oldest and have been monetized with AdSense for the past 4 years without any issues until now.

So Google has left me in the dark about why I was banned. To be fair, it does makes some sense that AdSense would purposely leave some ambiguity in their banning decisions. Not only does it help protect their processes from exploitation, but it also allows them to easily stop doing business with publishers whom they don’t want representing their network anymore. If that was the case with my content, then I would’ve rather just been told that. Or if it really was something about my content, then I wish they would’ve at least provided a specific example or reason so that when I move on to a different ad provider, I can be more aware about some possible content issues to avoid getting accidentally banned from the next platform too. Or better than either of those, I would’ve liked the opportunity to remove ads from the apps that they deemed against policy and leave the other apps alone.

Thinking there might be others out there experiencing a similar issue, I browsed the AdSense support forums and stumbled across this thread posted by another developer just 4 days after my ban. They received the same termination email and were similarly confused which of their apps resulted in their termination. I also found this one posted 3 days before my ban and tells a similar story (with more in the comments). AdSense is undoubtedly so large that all of these account terminations likely have no correlation, but I can’t help but find it find it curious. 

Regardless, I appealed the ban on the same day with a lengthy argument for why I feel it was a mistake. Considering my appeal has been open for more than a month without any response, I don’t expect my account will ever be reinstated. From what I can tell by browsing some archived Hacker News and Reddit threads, my account is already six feet under with a tombstone on top.

This post isn’t meant to be a sob story or public appeal to AdSense or the community about my account. It’s more to get the point across that I never expected a ban but should’ve been more prepared for it. Even if you aren’t in violation of any AdSense policies, it doesn’t matter when you suddenly find yourself on the wrong end of the banhammer. And even if you’re not in violation of any policies today, their terms are subject to change any day so you might suddenly be in trouble tomorrow.

  

Why You Should Be Prepared for An AdSense Ban

I had almost an entire month’s worth of revenue in the account withheld when I was terminated, and as a result have been without the majority of my app income for nearly 2 months. While I wasn’t relying on AdSense income to sustain myself, there are plenty of AdSense publishers out there who do.

Hopefully I’ve made the case that an AdSense ban can happen out of seemingly nowhere. But if you’re an app developer instead of a web publisher, it’s extra important to have a plan in place for when this happens. Web admins can immediately implement a new ad service and push changes to their web host so ads are resumed right away. 

App developers don’t have the same luxury because they’re at the mercy of when users decide to update their apps – which is pretty much an indeterminate amount of time. Even if you implement a new ad provider into your apps as fast as possible and publish an update across all the app stores you’ve listed on, it won’t even matter until your users actually install the update – which means your revenue may stagnate for some time even after you recover from the ban and implement something new. You could implement a forced update feature within your app to ensure users are always on the most up-to-date version, but that’s not always the best user experience if you are forcing users to download updates every time you release – especially if the release is very minor. So what’s an app developer to do?

 

 

 

How to Prepare for Termination: Have Backup Options Available

 

If I could magically rewind time, I wouldn’t have left all my eggs in a single AdSense / AdMob basket. Instead, here’s what I’d do: 

  1. Implement multiple ad providers into each app such as Appodeal, MoPub, Leadbolt, Facebook, or TapJoy.
  2. Implement a database where I can remotely configure which ads to show, how often, and when. Whenever the app first loads,it will send a request to that database to fetch the latest ad configuration. 
  3. If one of the ad providers is unexpectedly terminated, goes down, or starts performing poorly, I can adjust this configuration in the database and all clients will immediately start displaying the updated ads without requiring users to update their apps.

Another benefit of implementing multiple ad providers into your app is that most networks won’t have a 100% fill rate. So when an ad can’t be filled from one provider, you can attempt to display an ad from another and maximize revenue. 

Also, if you are in a really niche market and your app sends a lot of ad requests, then you may exhaust the higher value campaigns on one network. By having multiple ad providers, you reach a wider pool of advertisers and can swap over to a different provider when you start to detect lower CPM or CPC.

Ad Alternatives

The first step is to establish publisher accounts with multiple different ad providers. There are plenty of popular alternatives to AdSense / AdMob such as Appodeal, MoPub, Leadbolt, Facebook, and TapJoy. Note that each service might have different rules and requirements such as prohibiting serving their ads on content that’s outside of their supported languages. I personally have moved on to Twitter’s MoPub.

While you can create accounts with as many of them as you want, you realistically don’t need any more than 3-4. Also you’ll need to stay mindful of your APK / Bundle size and on Android at least be mindful of the dex methods limit. Whatever you decide, you can implement each one into your app and then write methods for each along the lines of:

showAppodealBannerAd()

showMoPubBannerAd()

showAppodealInterstitialAd()

showMoPubInterstitialAd()

Just make one for each type of ad you serve in your app from each of your providers.

 

Setting Up the Ad Config Database

There are several different options for setting up the remote ad configuration, each with their pros and cons. 

  1. An easy way would be to pay for some reliable web hosting service like Bluehost and upload an XML or JSON file to it. Simply make a request to that file when your app starts and just parse it on your app side, but just remember the file will be public.

*** Affiliate links disclaimer – Gotta try to afford coffee without AdSense somehow, right? I use Bluehost and can recommend it – especially because they have a decent intro promo price, but there are plenty of other options out there like HostGator, Hostinger, or Inmotion.

2. Alternatively, you could pay for an AWS database service such as DynamoDB or RDS depending on how much you want to over-engineer it. 

3. Another option (and the one I chose) is to use Firebase’s Cloud Firestore.Firebase does a lot more than this, but The Cloud Firestore product is a really simple cloud database service. It’s Google-owned (yes, I see the irony here) and integrates with Google Cloud so you can expect the uptime to be pretty dependable. It’s free up to the first 50,000 reads and 20,000 writes per day and is really easy to implement into your apps

If you cache the config file after fetching it from Firebase and give it a shelf life on the device of one day, you’d be able to support up to roughly 50,000 daily users without having to pay a cent. Once you surpass the free limit your costs would just scale with your usage. Their SDK also handles a bunch of the network logic for you, meaning less boilerplate code for you to write. 

Firestore is a NoSQL database that’s based on collections of documents. You can create a “config” collection at the root location for your app, and create any remote configuration documents in it. One downside is that you’d need to either include all of your apps in the same Firebase project so they all have access to this one config collection, or you’d have to create and maintain separate config collections for each app you do this with.

A simple remote ad config file might just have boolean toggles indicating whether to serve ads from each provider. In the screenshot below, we would currently be showing ads from MoPub. If later I wanted to start serving ads from Appodeal in my apps, I’d simply set Appodeal to true while setting MoPub to false.

Firebase Ad Config Boolean Toggles 

You’d also probably want to add a bit of safety logic here. If the request to fetch the configuration document fails for some reason, how would you decide which type of ad to serve? What if you accidentally leave all of them false? Another possible way all the toggles could be false is if you’re in the middle of changing the values around. If you set MoPub to false first and in between the time it takes you to change Appodeal to true someone requests the config file, it would mean all 3 toggles would appear false for that User. What if you accidentally leave more than one toggle to true? You’ll want to implement some sort of default priority to fall back on if one of these edge cases occur. 

Another idea would be to use double values instead of booleans, representing the probability a user gets served an ad from that provider or another. So in the below example, a user would have a 75% chance of seeing an ad from AdSense, and a 25% chance to be served an ad from MoPub.

Firebase Ad Config Percentages

One benefit of this is that you could use it to compare the performance of each network in real time. So if you set AdSense to 50% and Appodeal to 50%, it would be like an A/B test to see which one is performing better this month. Maybe Appodeal is earning you $1.75 CPM whereas AdSense is only performing around $1.00 CPM. If you saw this, you could bump up your Appodeal allocation to 75% and reduce AdSense to 25% to try and increase revenue.

Like the boolean example, you’d also want to implement some sort of default logic on the app side to get around some edge cases such as accidentally having the sum of probabilities being not equal to 1. 

These are all just very basic ideas, but there are all kinds of ways to expand on this. You might decide to get more granular with it and serve your interstitial ads from Appodeal, but your banner ads from MoPub. It all depends on how much you’d like to configure remotely, and how complicated your advertisement structure is in your app. It extends beyond just remote advertisement configuration, but you could also use a system like this to A/B test different features or layouts in your app.

It’s probably worth adding a “config_version” field in each of your documents and match it against the client side. As your advertising needs change down the road and you find yourself needing to completely alter your config file structure, you’ll likely need to update the app client side as well. Versioning the config file ensures that updated clients use the newer ad config file while older app versions can remain functional with the older config file. Remember, you’re at the mercy of when users decide to update their apps! 

If you’d like a more in depth tutorial about implementing this on Android, drop a comment and let me know so I can create a dedicated post and example project for it.

 

  

Final Thoughts About Preparing for an AdSense Ban

Because bannings can be swift and unexpected with little hope of a successful appeal, it’s best to be cautious and read through each ad platform’s policies thoroughly. In this case it’s probably better to check for permission than ask forgiveness to avoid unknowingly violating a policy. Do some research about the mistakes that can get you banned and make sure you’ve done your due diligence. I found this article by Harsh Agrawal pretty informative.

Another thing you can do to protect yourself is to ensure your AdSense account settings are up to date. When you’re banned from Adsense, you’re likely to lose your entire unpaid account balance. Ideally you’d want to move money from your AdSense account into your bank account as quickly as possible. It would be great if you could change your payment frequency to a weekly schedule instead of monthly, but right now that option doesn’t exist. The best you can do is double-check that your payment threshold is set to the minimum value – which is currently $100 USD. Anything more than that sitting in your AdSense account is a liability.

 

If you have any questions, comments, or suggestions on this post, leave a comment below or contact me.

You might also be interested in some of my other blog posts. I don’t write as often as I’d like, but you can also enter your email below to be notified by email whenever I publish a new post.

 

Subscribe to receive future posts straight to your inbox.

* indicates required