If you have already read why moving averages help you read GSC data more accurately and want to actually get one on your data, this is that article. Three complete methods: a spreadsheet formula, a Python script, and a one-click option inside Google Search Console. Each one works. They differ in setup time, where the output lives, and whether you can automate it.
Pick the method that fits how you already work.
Method 1: Google Sheets
The spreadsheet approach gives you a rolling average column sitting next to your raw data. You can chart it, share it, or feed it into a reporting template. It requires an export and a formula, but once set up it takes less than two minutes to apply to any new dataset.
Step 1: Export Your GSC Data
Go to Google Search Console, open the Performance report, and set a date range. 90 days is a reasonable minimum. 180 days gives the smoothed line more context and makes trends easier to read.
Under the chart, click "Export" and choose Google Sheets. GSC creates a spreadsheet with multiple tabs. Go to the Dates tab. You need two columns: Date in column A, Clicks in column B. If you want a moving average on impressions as well, you can apply the same formula to that column after.
Sort by date ascending if it is not already. The formula depends on rows being in chronological order.
Step 2: Write the Formula
Add a header in C1 — something like "MA 7d" — then put this in C2:
=IF(ROW()-ROW($B$2)+1<7,"",AVERAGE(OFFSET($B$2,ROW()-ROW($B$2)-6,0,7,1)))What it does, step by step:
OFFSET($B$2, ROW()-ROW($B$2)-6, 0, 7, 1) selects a range that ends at the current row and spans 7 rows upward. For row 8 (the 7th data row), it selects B2:B8. For row 9, it selects B3:B9. The window always covers exactly 7 consecutive rows ending at the current date.
AVERAGE(...) takes the mean of those 7 values.
IF(ROW()-ROW($B$2)+1<7,"",...) returns a blank for the first 6 rows because there are not yet 7 data points to average. Blanks are cleaner than zeros for charting — a line chart will simply not draw the line for those rows, which is correct.
Step 3: Fill the Column
Click cell C2, then drag the fill handle down to the last row of your data. The formula adjusts automatically for each row. Rows 2 through 7 will be blank. Row 8 onward will show the 7-day trailing average.
To chart it: select columns A, B, and C, insert a line chart, and choose "Date" as the x-axis. You now have raw clicks in one line and the smoothed 7-day average in another.
One note for advanced Sheets users: OFFSET is not array-compatible in Google Sheets, so wrapping this formula in ARRAYFORMULA will not work. The fill-and-drag approach is the correct method here. If you add more rows of data later, just extend the fill down to cover them.
Changing the Window Size
The formula has one variable: the window length. For a 14-day moving average:
=IF(ROW()-ROW($B$2)+1<14,"",AVERAGE(OFFSET($B$2,ROW()-ROW($B$2)-13,0,14,1)))The pattern for any window size N:
=IF(ROW()-ROW($B$2)+1<N,"",AVERAGE(OFFSET($B$2,ROW()-ROW($B$2)-(N-1),0,N,1)))Replace N with 7, 14, 21, or 28. Larger windows smooth more but respond more slowly to recent changes.
Method 2: Python with pandas
If you work across multiple properties, pull GSC data programmatically, or want a calculation that runs automatically as part of a larger workflow, pandas is the right tool. The actual code is short.
The Complete Code
import pandas as pd
# Load your exported GSC data
# Expects a CSV with at least 'Date' and 'Clicks' columns
df = pd.read_csv('gsc_data.csv', parse_dates=['Date'])
df = df.sort_values('Date').reset_index(drop=True)
# Calculate moving averages
df['clicks_ma_7d'] = df['Clicks'].rolling(window=7).mean().round()
df['clicks_ma_14d'] = df['Clicks'].rolling(window=14).mean().round()
# Preview the first 20 rows
print(df[['Date', 'Clicks', 'clicks_ma_7d', 'clicks_ma_14d']].head(20))
# Export back to CSV
df.to_csv('gsc_with_ma.csv', index=False)rolling(window=7).mean() is pandas' built-in trailing moving average. For each row, it looks back N rows including the current one and returns the mean. The first 6 rows will show NaN because there are not yet 7 data points. That is correct and expected — the same logic as the blank cells in the spreadsheet version.
.round() converts the float average to a whole number. Clicks are integers, so a rolling average of 247.14 is not meaningful to report. Remove it if you want the precise float.
To apply the same calculation to impressions, add one line.
When you export from the Dates tab in GSC (via Export > Google Sheets or Download CSV), the column headers are exactly: Date, Clicks, Impressions, CTR, Position. The code above uses these as-is. If your CSV came from a third-party tool or a different export tab, check the header row and adjust the column names in the script to match.
When Python Earns Its Setup Time
For a single site reviewed occasionally, the spreadsheet approach is faster to run once. Python makes sense when you are processing more than a handful of properties and want one script to handle all of them, when you pull GSC data via the API and want the moving average calculated before it touches any spreadsheet, or when you are building a reporting pipeline and need the MA as a calculated column that feeds into a dashboard or alerting system.
If neither of those applies to you, the spreadsheet method is fine. If either applies, Python pays back the setup time quickly.
Method 3: Advanced GSC Visualizer
The first two methods require an export. The extension skips that entirely. The moving average is calculated and drawn directly on the GSC performance chart, in the same view where you already read your data.
How to Enable the Moving Average
Open Google Search Console with the Advanced GSC Visualizer extension installed. Navigate to the performance chart and locate the extension controls. Click the More button to reveal additional visualization settings, then find the Trendline / Moving Average dropdown.
The available options depend on the current time grouping in your chart. In daily mode: standard trendline, 7-day moving average, or 14-day moving average. In weekly mode: standard trendline, 4-week moving average, or 8-week moving average. In monthly mode: standard trendline or 3-month moving average.
Select the option that fits your analysis. The overlay renders immediately as a red line on the chart. No export, no formula, no chart setup.
What the Overlay Shows You
The calculation is the same trailing simple moving average as Methods 1 and 2. The first N-1 days of the visible date range show no overlay because the window does not have enough prior data. From day N onward the smoothed red line runs continuously on top of the raw data.
The legend at the bottom of the chart confirms the active calculation, showing it as Trendline(clicks) or Trendline(impressions) depending on the metric. If multiple metrics are active, the extension applies the moving average to whichever metric you activated first. To target impressions specifically, deactivate all active metrics, click the impressions button first, then enable anything else you want visible in the background.
To make the trendline stand out more against busy raw data, use the Chart Opacity slider to reduce the visibility of the underlying chart. The smoothed line comes into sharp focus while the raw data stays visible in the background.
You can switch window sizes without refreshing or re-exporting. Changing from 7-day to 14-day updates the line immediately — useful for feeling the difference between a short and long window on your actual data before committing to one for a report.
For the technical details of how the extension calculates the moving average and handles data aggregation edge cases, see the trendlines and moving averages documentation.
Which Method Fits Your Workflow
The right choice comes down to where you work and what you do with the output.
Use Google Sheets if you already report in spreadsheets, if you want the calculation visible and auditable in your own file, or if you need to combine the moving average with other metrics you track in a sheet.
Use Python if you process multiple sites in a data pipeline, if you are already pulling GSC data via the API, or if you need the moving average as an input to an automated workflow.
Use Advanced GSC Visualizer if you primarily work inside Google Search Console, if you want to check the trend without exporting anything, or if you want to adjust the window size and see the effect on your live data in real time.
For most SEOs who check GSC regularly, the extension fits the existing workflow without any setup. The spreadsheet and Python methods are worth knowing when you need to take the data somewhere the extension cannot follow.


