How to Segment Branded vs Non-Branded Traffic for SEO
How to Segment Branded vs Non-Branded Traffic for SEO
Cosmin Negrescu
February 26th, 2025
This guide explains how to separate branded from non-branded traffic and optimise your SEO strategy accordingly. It provides concrete, step-by-step instructions for both using SEOmonitor and, in case you’re stuck using other tools, handling the process manually.
Understanding Branded and Non-Branded Keywords
Branded Keywords
These include your company name, product names, or common variations. For instance, terms like “Nike shoes” or “iPhone 17” directly reference a brand, but they might not be considered a ‘brand’ term. If you’re Apple, then “iPhone 17” is undoubtedly a branded term. However, if you merely happen to sell iPhones, then generally, we wouldn’t consider it a branded term for you because users don’t behave differently when interacting with you or searching for that term compared to any other company. There are certain instances where you might want to rank for other companies’ brand terms—for example, if we wanted to rank for ahrefs terms. These are what we’d consider ‘brands of others.’ True branded terms are navigational. They’re ones where the user intends to end up on your site. They usually generate higher conversion rates and indicate users who are already familiar with your brand.
Non-Branded Keywords
These are generic search terms related to your products or services, such as “running shoes” or “smartphone reviews.” They usually have higher search volumes and can be found all through the purchase funnel though less often, as the user refines their searches, at the bottom of it.
Why Segmentation Matters
Brand and non-brand traffic behaves very differently from each other. Branded traffic is heavily affected by other advertising activities in a way that non-brand traffic typically isn’t. Branded traffic’s click-through-rate tends not to be affected by brand scandals, whilst we’d expect non-branded CTR to reduce for unloved brands. More than that, the branded traffic obscures the traffic that you’re able to optimise, control and improve. Accurate segmentation leads to:
- Accurate Performance Measurement: Separating these metrics ensures you report growth from your own SEO efforts—not external factors like TV ads or PR.
- Better Resource Allocation: Understand which keywords are driving conversions and adjust your strategy accordingly.
- Improved Competitor Analysis: Compare your non-branded search market share against competitors and identify opportunities to capture branded traffic from industry peers.
- Clear Customer Journey Mapping: Track users as they move from generic queries to brand-specific searches, refining your funnel at every stage.
You’d be surprised how many SEO agencies, and practitioners more generally, aren’t bucketing organic traffic this way. That’s because it can be a pain to do, but it doesn’t have to be.
How to Segment Brand & Non-Brand Traffic with SEOmonitor
SEOmonitor makes it really easy to segment organic traffic into brand and non-brand buckets; it’s built into the fabric of the tool. Here’s how to get to a slide-ready visualisation in less than 10 minutes:
- Create a new campaign: start a free trial.
- Connect GA and GSC: Navigate to Organic Traffic.
- Define Your Brand Terms: Input your brand name(s), common misspellings, and related variations into SEOmonitor. You can change these later.
- Make some tea:
- Coffee is also acceptable, but it’s difficult to review data without some sort of drink.
- In the background, SEOmonitor’s automatically mapping data and preparing your visualisation.
- Come back into the organic traffic module: You’re done!
[Organic Traffic](/content/organic-traffic/ "Organic Traffic"/index.html) module in SEOmonitor.
How to Segment Without SEOmonitor
Manual segmentation is possible but requires multiple steps and careful handling of data. Here’s an outline of the process:
1. Data Export: Brand traffic typically changes slowly and so having a long-term way to store changes is important to fully understanding trends. Google Search Console only stores 18 months of data though, so you’ll want to export data for long-term storage to BigQuery. This is a multi-stage process, which is more completely covered in Google’s documentation here, but the basics are:
- Sign up for Google Cloud
- Create a new project
- Enable BigQuery in that project
- Within IAM and Admin add serach-console-data-export@system.gserviceaccount.com as a new principal with BigQuery Job User and BigQuery Data Editor roles.
- In Search Console go to settings > Bulk data export.
- Enter the Google Cloud project ID, a dataset name and a location for the data to be held.
- Wait 48 hours for the first export to occur. There’s a small chance that there’ll be a small cost attached to this. If other teams are maxing out the otherwise very generous BigQuery credits Google Cloud provides by default, then you may need to pay for these extracts. Check in on who else, within your organisation, is using BigQuery.
2. Import the data into Google Sheets: Whilst you could use the data from BigQuery directly in Looker Studio via the BigQuery connector, this will increasingly lag and timeout as your dataset grows over time. As such, the most performant solution is to have a Google Sheet update with the statistics you need once a day and then pull from that. Whilst you could use what Google calls ‘Connected Sheets‘ for this, it’s prone to issues and so you’re usually better off adding in a quick script.
- Click on ‘tools’, then ‘script editor’ within Google Sheets
- Paste in the following script:
function updateSheetFromBigQuery() {
// --- CONFIGURATION (CHANGE THESE) ---
const projectId = 'your-gcp-project-id'; // Your Google Cloud Project ID.
const datasetId = 'your_gsc_dataset'; // Your BigQuery dataset (GSC export).
const sheetName = 'Sheet1'; // Sheet name to append to.
const regexPattern = '.*your_brand_term.*'; // *** YOUR REGEX HERE *** (e.g., '.*Nike.*').
// --- END CONFIGURATION ---
try {
// 1. Find the latest table (GSC exports have date-suffixed tables).
const tables = BigQuery.Tables.list(projectId, datasetId).tables;
if (!tables || tables.length === 0) {
throw new Error(`No tables found in dataset ${datasetId}.`);
}
tables.sort((a, b) => Number(b.creationTime) - Number(a.creationTime));
const latestTableId = tables[0].tableReference.tableId;
Logger.log('Using table: ' + latestTableId);
// 2. Construct the query.
const query = `
WITH
LatestDateData AS (
SELECT
MAX(date) as latest_date
FROM
\\`${projectId}.${datasetId}.${latestTableId}\
),
DailyData AS (
SELECT
SUM(impressions) AS total_traffic,
SUM(CASE WHEN REGEXP_CONTAINS(query, r\