Calculating Content Marketing ROI

by Carlin Leung

This post comes with a spreadsheet for calculating content marketing ROI. Get it here.

Content ROI seems to be a bit of a mystery for a lot of marketers. Ask any marketer how they’re measuring the success of their content, and you’ll get a bunch of answers like social engagements, reach, or SEO. You might even hear answers for more bottom-line impact like sales or leads generated. This is actually a great start—we have metrics all throughout the funnel. Now comes the tricky follow-up question: “How do you prove that your content is a good investment?”

Quickly searching for “content marketing ROI” provides few helpful answers. The results of that search offer a few key recommendations:

  1. Determine the amount of money you’re spending on content. If you’re not spending cash, measure the value of your hours
  2. Find out how much money you’re making from that content
  3. Use the ROI formula to get your ROI

Sounds easy, right? If you’re like me, you’ll breeze through step one, get to step two, and pause: “wait, how exactly am I supposed to find out how much money I’m making from my content?” And that’s where we uncover the toughest questions when it comes to measuring content marketing ROI: the question of content marketing attribution.

Let’s face it, the rest of the ROI formula is pretty straightforward; the real tough part is figuring out the revenue your content is generating for you. This is something that’s been on my mind a lot—whether I’m developing my own content strategies, or working on a client’s, this topic inevitably comes up, so I decided to take a shot at providing a solution. In this post, I’ll provide a ways you can more accurately attribute value to your content marketing, and, in turn, calculate a more accurate ROI.

There’s a lot in this post, so here are some quick links if you want to skip ahead

Let’s start with the basics.

The Basics: What is Attribution?

Marketing attribution is the process of assigning value to user interactions/touchpoints that contribute to some desired outcome. Essentially, this boils down to figuring out what portion of your total revenue comes from each of your marketing activities.

In the case of paid channels, that’s pretty straightforward. Often, your ad campaigns will be focused on campaigns that can generate revenue, and so you can measure revenue generated from the visitors who clicked on your ad.

Looking at the above diagram, there’s really no other way to attribute the revenue. Users clicked an ad, and they purchased. That ad directly generated that revenue for you. However, it’s rarely that simple. More likely than not, visitors may visit your site a couple of times by other means before finally clicking an ad and making a purchase:

In this case, you know that the ad was likely not the only contributing factor to the customer’s purchase. Your email and search campaigns likely contributed too, so you’ll want to make sure that part of this sale counts towards the amount of revenue generated from search and email, so you can properly determine ROI.

Luckily, Google Analytics has pretty robust tools that help you calculate the portion of revenue each of these channels generated (if you’re unfamiliar, check out multi-channel funnels in your conversion reports). However, there’s no straightforward way to attribute value to specific specific pages (whether they’re blog posts, product pages, or something else).

Google Analytics has some features that can give you parts of the picture, but not quite the full deal.

  • Reverse goal path tells you which pages are most likely to precede a conversion, so you can see whether a content page may have contributed. However, this only lets you see three pages back, which doesn’t always provide insight—if you have a checkout process longer than three pages, you’re out of luck.
  • Page value is an improvement, showing you Google’s estimated value of each page on your site. However, page value only attributes value to pages if they’re viewed in the same session as a conversion. In the previous example, none of the content pages would have been attributed any value.
  • Multi channel funnels allow you to attribute value across sessions, but only to channels. So while this is an excellent tool for identifying whether email, ads or search are worth the investment, this feature doesn’t shed any more light on which pages actually contributed.

So how can we attribute value to our content to calculate content marketing ROI? Here are a few ways I’ve found to be effective. Let’s start at the top (or if you like, skip to the bottom) of the funnel.

Attributing Value of Content at the Top of the Funnel

If the goal of your content marketing efforts is to build brand awareness, improve brand visibility, or otherwise reach a wider audience, you can determine the value of your content by calculating the opportunity cost of paying for the traffic that your pages have generated. For example, if your story drew in 100 users, and you would normally have to pay $200 in ads to draw in that number of users, the value of that particular page would be $200.

To calculate this, we’re going to be using some paid metrics to measure organic performance. In this example, we’re going to measure the value of your organic search traffic. Specifically, for all content pages, we’re going to find the queries where the page was shown as a result, and actually resulted in a click. We’re going to total the value of those clicks (using suggested bid) to get the total value of that content page.

Step 1: Get click data

First, we need to determine how many clicks your content pages earned from each query. Head to search console (if you don’t have this set up, go do it! It’s an immensely useful tool) and head to search analytics.

Select “Clicks” as your metric.

Then click the drop down menu under “Pages”, and select “Filter pages…”

At the prompt, enter a URL pattern for your blog content. For example, if your stories are stored in the /blog/ subdirectory, enter “/blog/”.

From there, scroll down to the very bottom of the page and download your data. By default, this will give you the last 28 days of data. If you want more, change the date range using the date range filter on the far right of the filters bar.

This will give you a CSV file with the number of clicks and impressions for each query, as well as the click through rate and average position. What we’re interested in is the click data, but we’re not going to use that just yet.

Step 2: Get value of clicks

The next step is to find the value of each of these clicks. Conveniently, there’s lots of software out there that can provide metrics like suggested bid or average CPC, both of which are great starting points for determining the value of a click. I personally like to use keyword planner in Google Adwords and use their suggested bid metric. From the CSV file you downloaded from Search Console, copy the queries column and paste the list of queries into your selected software, and export the resulting data.

Now, for each query, you should have the number of clicks on that query from Search Console, and the suggested bid or average CPC from Keyword Planner or something similar. All that’s left is to multiply suggested bid/CPC with number of clicks for each keyword, then summing them up. Here’s what your spreadsheet might look like:

Note: If you’re having trouble consolidating your CSV files manually (Keyword Planner likes to combine your keywords sometimes), try using a Vlookup (or better yet, Index Match) formula in excel.

This gives you a dollar value of your content marketing based on the opportunity cost of having to pay for that traffic. Substitute “Revenue from content” in the formula below with the opportunity cost you just calculated to get your content marketing ROI.



Now, before you start running around the office telling your colleagues, there are some caveats you should know about (of course there’s a catch!):

  1. The example above gets you the value of all your content pages. If you want to find  out how individual pages performed, you’ll need to repeat these steps, filtering for an individual page instead of all blog pages at the beginning of this process. If you have a lot of pages, this could be tedious.
  2. The example uses suggested bid, which isn’t the most accurate measure. Using estimated CPC from a tool like SEMRush might be more accurate, but at the end of the day, we’re using estimated measures here—take the results with a grain of salt. If you’re determined to find a more accurate way, create ad campaigns and bid for each keyword you rank for to get a more accurate suggested CPC.
  3. Most importantly, these numbers don’t represent revenue generated from content. If you’re using this method to calculate ROI, remember that this isn’t an amount of money you’ve made off your content. Rather, it measures how much you would have paid to otherwise purchase this traffic through search ads, so don’t get too trigger happy just because this number is really attractive.

This is all great for getting the ROI based on opportunity cost, but what if your content is more focused on driving sales or generating leads? There’s real money involved in this scenario—so how do you accurately attribute those dollars to your content efforts to find ROI? Let’s take a look at another way.

Attributing Value of Content at the Bottom of the Funnel

This method makes use of a few features in Google Analytics that requires a bit of set up. So before you continue, make sure you:

  1. Have Google Analytics
  2. Have set up goals in Google Analytics
  3. Have goal values for all the goals you want to attribute to content marketing

If you don’t have these set up, read this handy guide on setting up goals and assigning goal value in Google Analytics. Ready? Great, let’s start.

Step 1: Create a custom segment

First, create a custom segment that includes only users that viewed a piece of content, then completed a goal.

A couple of things to note:

  • Use the sequence segment so that we’re only looking at users who viewed content then completed a conversion, and not the other way around
  • Ensure you’re filtering for users (not sessions). This allows us to measure activity across sessions—segmenting for users will include situations where someone visits a content page in one session, then converts in a later session
  • In Step 1, I have “contains /blog” as the condition, since the site I’m using as an example has all stories stored in the /blog subdirectory. Enter a pattern here that selects all your content pages; if you need to select multiple subdirectories or subdomains, use a regular expression.
  • I’m using all goal completions in step 2 for this example, but feel free to use any combination of goals that make sense for you. I’d recommend including all goals that have a goal value for highest accuracy. If you decide to exclude goals that have goal values, just remember that your calculations don’t reflect the full value of your content.

Give the segment a descriptive name like “read blog post then converted”, then hit save, and the segment should be applied automatically, in addition to the default “All Users” segment. Remove the “All Users” segment so that we’re only looking at data in the “read blog post then converted” segment.

Step 2: Get total goal value

Next, head to your conversion reports and get your total goal value. This goal value is effectively the total value of conversions where content played a role. In other words, this would be similar to finding the assisted conversion value of content, if content were a channel.

Write this down somewhere, we’re going to come back to this in a minute.

While this number might seem like we’ve found found the amount of money generated by your content, it’s not quite showing you the full picture. This is the full value of all the conversions where content played a role, no matter how small. A user could have viewed one blog post in their first session, then visited several product pages over many other sessions, before finally making a purchase a month later. If we just use this number, we’re saying that content should be attributed the full value of the conversion, which doesn’t seem fair.

A look at your behavior reports highlights this problem. I’ve blocked off the actual URLs to protect client information, but you can see that it’s not just blog posts that contributed in this scenario. We have product pages, resources, and even the homepage. It would be unfair (and inaccurate)  to discount the impact of all those other pages. To get around this, we’re going to need to do some quick maths, and to help with that, I’ve created a handy spreadsheet template.

Step 3: Get page data

Make a copy of the spreadsheet template, then export the data from your behavior reports.

In the template, paste the pages from your export into column A (under “Pages”), and the unique pageviews in column B (under “Unique Pageviews”).

Next, enter your goal value into cell J3, which is under the “Settings” box. Don’t worry about content URL string for now, we’ll get to that later.

Step 4: Calculate page value

Once you enter the total goal value, your spreadsheet will automatically calculate the page value for each page you’ve entered:

The sheet uses this formula to get each of the page values

It takes the total goal value, divides it by the total number of unique pageviews from the data in the dataset. This gives us the amount of value (in dollars) that each unique pageview generated. We then multiply that by the number of unique pageviews of each page to get a page value. Essentially, we’re saying that the more unique pageviews a page has that contributed to a conversion, the more value it deserves.

In this example, the total goal value is $2,000. We sum all the values in the “Unique Pageviews” column (which ends up being 542). Next, we multiply that by each page’s number of unique pageviews (61, for the page “/blog/post1”), to get its page value. Viola!

(Optional) Step 5: Weight your data

“Wait!” you might say, “Why does the homepage get so much page value, that doesn’t make sense!” and I would agree with you. The data we exported from Google Analytics includes all pages visited by users who visited a content page, then converted. This includes pages that might not have noteworthy impact, like home pages, privacy policies, terms and conditions, etc. Conversely, there may be pages that you might feel are more influential in the sales process, like product or testimonial pages. Of course, the influence of the specific pages depends on your site, but the sentiment is the same: Not all pages are created equal, and some pages should hold greater (or lesser) value than others, regardless of how many people viewed those pages.

This is where the “Weight” column in the spreadsheet comes in. This column modifies the page value of a specific page. A weight of 0 would remove all the value from one page, and evenly distribute that page’s value among other pages, while weights greater than 1 would increase the value of that page, while evenly lowering the value of all other pages.

In this example, we’ve completely removed the value of the “/home” and “/blog” pages, but kept all other weights the same. The formula remains largely the same, but the values are now adjusted by a weight. Notice the total number of unique pageviews has decreased (since we’re removing two pages), meaning that the value of a single pageview is higher. Now, when we multiply each page’s number unique pageviews by the value of a single pageview, you’ll see an higher value for all other pages.

Step 6: Enter costs and calculate ROI

Finally, enter the dollar amount that you spent on producing a specific piece of content (don’t forget to include intangibles like hours spent!), and the sheet will calculate your content ROI.

The sheet will also automatically calculate some summary metrics, such as average ROI, total value, total costs, etc., which could come in handy.

Congratulations, you’ve just determined your content marketing ROI!

(Optional) Step 7: Filter just for content

Remember the “Content URL String” field that I said we’d come back to? Well we’re coming back to it. If you enter a value into cell J4, it’ll filter the metrics in the “Results” box to only include data for pages that contains that value. If you enter “/blog” in J4, your results will only show data for pages that contain “/blog”.

For best results, I suggest using whatever filter you used when defining your segment in step 1. If you used “contains /blog” for your segment, enter “/blog” into cell J4. If you used “contains blog.”, enter “blog.”. Unfortunately, this sheet currently only supports contains logic, so if you’re using a regular expression, or some other condition, you’ll need to tweak the formula in cell J4.

Some thoughts about this method

What I really like about this method is that the sum of your page values will never exceed your total goal value. This is really important—how can you distribute more value than you’ve earned? If you’ve only made $2,000, it doesn’t make sense for your pages to have earned you $2,500, for example—where would that extra $500 come from? It’s certainly not in your bank account.

To really illustrate this concept, consider this analogy. Imagine you had $2,000 of revenue to attribute among your sales team. If you have 5 salespeople each saying they generated $1,000. You know someone (or likely, someones) is lying about how much they sold. When attributing value to your pages, the same principle holds true. The revenue generated by each page (the salesperson in our analogy) cannot exceed the total revenue generated.

Try it out! If you add all the values in the Page Value column above, you’ll get $2,000. No matter how you tweak the numbers, the sum of page value will always be equal to the total page value.


Alright, alright, you saw this coming, there’s always a catch. Here are some limitations of this method.

  1. Since we’re using user segments in Google Analytics, we’re limited to getting 90 days of data at a time. Obviously that’s not ideal, since your content typically stays on site for longer than 90 days. You could export data for each 90 day period then stitch the data together, but just know that there are likely gaps in this data. Alternatively, you could use Google Analytics’ API to retrieve this data, but look out for sampling issues.
  2. This method doesn’t take into account activities occurring offsite. Did you pay to promote your content? Did you have other ads running? Unlike attributing based on channel, this method does not take offsite activities into account. However, using this in tandem with the attribution models offered by Google Analytics (which attributes value to channels, rather than pages) could be effective.

Despite these limitations, I still think this is a great way to get a clearer idea of content performance. If you want to take it a bit further, there are a few ways you can further improve this model using this spreadsheet template.

Model improvements

No model is perfect, and you can always build on what I have here. I’ve already discussed using page weights and segmenting for specific goals, but there’s still one major area that can be improved: segmenting for interactions other than pageviews.

Savvy readers would’ve picked up on this right away: Just because someone viewed a page, doesn’t mean it influenced their purchase decision. A simple improvement could be to change your user segment in step 1 to be more stringent.

For example, filter for users who viewed a blog page for longer than a specific time, or viewed a content page and scrolled past a percentage, then converted. Both of these ideas require some knowledge of custom events, but once you’ve implemented the event, you just need to update the segment in step 1—the rest of the calculations still work.

If you do come up with improvements to this model, let me know! I’d love to add your ideas to this post and to the spreadsheet template. Contact me here or tweet me @CarlinLeung.

Final Thoughts

Whew, thanks for sticking it out with me for nearly 3,500 words! I’ll keep this conclusion quick. Remember, you don’t have to use just one method. We covered a top of funnel method, and a bottom of funnel method. For your content efforts, you can (and should) use both methods to evaluate performance at each stage of the funnel.

Don’t forget other functions of content. Here, we’re measuring the value of content in influencing sales, but your content can have other functions. Maybe it helps with post-purchase satisfaction. Maybe it speeds up your sales process. Don’t take this ROI as the end-all-be-all. Recognize the other functions of content, and keep that in mind—just because something doesn’t directly drive sales doesn’t mean it’s not valuable.

Finally, don’t be discouraged with poor initial results. Content is a long-term game, and you’ll almost always start with negative ROI due to the high up-front investment. The flip side to this is that the long term investment is typically very low. Due to this, your content ROI will naturally improve over time. Your will continue to contribute to your goals, but not requiring much more investment. That’ll directly improve your ROI.

That’s all, thanks a ton for reading. If you have questions about this post, the template, or anything marketing analytics related, don’t hesitate to give me a shout.

Want to chat data, marketing, or education?

Carlin Leung © 2020