Measure Speed in GA4
By Matthew Edgar · Last Updated: November 15, 2023
GA4 does not currently offer a built-in report for measuring website speed. This is unfortunate because it is helpful to monitor speed for your actual visitors, especially when comparing speed to engagement or conversion metrics. This data helps you determine how big of a problem speed may be on your website and this data helps you forecast a return on investment for any speed optimization projects.
There are ways to bring this data into GA4 using Google Tag Manager using templates. In this article, I will walk through how you can add Core Web Vitals metrics and other speed metrics to GA4.
These steps assume your website currently uses Google Tag Manager and GA4. As well, these steps assume you have some familiarity with GTM and GA4. However, you do not need to be a developer to configure this tracking.
Step #1: Add the Core Web Vitals Container
The first thing we want to add are the variables, triggers and tags needed to track the Core Web Vitals metrics. This is based on a template is created by Simo Ahava and you can read his post about this template for more details. The template tracks the data and sends it to Google Tag Manager but variables and a GA4 event need to be added to send that data to GA4.
You can download a container that can be added to your Google Tag Manager workspace. This will add the template along with all associated tags, triggers, and variables, following the steps outlined in Ahava’s original post.
Once downloaded, return to Google Tag Manager, and click “Admin” in the menu. On the admin screen, select “Import Container”. Upload the cwv_event_variables.json file. Under “Choose workspace” select “Existing” and then choose your Google Tag Manager workspace. In the following screenshot, my workspace is called “Default Workspace”. Then choose “Merge” and “Overwrite conflicting tags, triggers and variables”.
There should be no modified or deleted tags, triggers, or variables in this upload. This should only add new data to track the Core Web Vitals events. Once you have this uploaded, click “Confirm”.

Step #2: Add the Site Speed Report Container
There is more to website speed than Core Web Vitals. To track additional metrics, you can also add the code created by David Vallejo to track performance timing events in GA4. You can download a pre-built container that contains all the variables, triggers, and tags you need.
This will be the same as Step #1. After downloading and unzipping the container, go back to Google Tag Manager. Click “Admin” in the menu and then select “Import Container”. Upload the ga4-site-speed.json file you just downloaded. Under “Choose workspace” select “Existing” and then choose your Google Tag Manager workspace. In the following screenshot, my workspace is called “Default Workspace”. Then choose “Merge” and “Overwrite conflicting tags, triggers and variables”.
Here again, there should be no modified or deleted tags, triggers, or variables in this upload. Once you have this uploaded and confirmed no modifications or deletions, click “Confirm”.

Step #3: Adjust New Tags Added by the Site Speed Report Container
Now, go back to the Workspace area in Google Tag Manager. Select “Tags” from the sidebar. You will see three new tags, “Performance Tracking”, “Select Config Tag Before Publishing – GA4 – Event Timing”, ” Core Web Vitals Measure Handler” and “Change GA4 Measurement ID – Core Web Vitals Event”.
The “Performance Tracking” tracking tag contains the code to track the speed metrics. The “Core Web Vitals Measure Handler” sets up the Core Web Vitals template. You can leave both of these alone.
You will need to edit both the “Change GA4 Measurement ID – Core Web Vitals Event” and the “Select Config Tag Before Publishing – GA4 – Event Timing” tags. Both contain a temporary GA4 measurement ID. Click on this and replace it with your website’s GA4 measurement ID. Here is how to find your measurement ID.
Open each tag, change the measurement ID, and then save the tag. If you’d like, you can adjust the names of the tags while editing. For example, I renamed the tags in my workspace to “GA4 – Event Timing” and “Core Web Vitals Event”. After saving these tags, you can publish the Google Tag Manager (as always, I suggest previewing first to confirm everything works properly on your website).

Step #4: Add Custom Definitions in GA4
Next, custom definitions need to be created in GA4 for each of the vent parameters. Custom definitions tell GA4 to accept the parameter coming in from Google Tag Manager.
The “GA4 – Event Timing” tracks the following metrics, each of which is a parameter.
- page_load_time: Measures the total time it takes to load the entire web page, from the initiation of navigation to the page’s load event.
- content_load_time: Measures the time it takes for the DOMContentLoaded event to start, indicating when the initial HTML document has been completely loaded and parsed.
- dom_interactive_time: Measures the time it takes for the Document Object Model (DOM) to become interactive, which typically represents when the page is ready for user interaction.
- server_response_time: Measures the time it takes for the server to start sending the response to the client after the request is made.
Other metrics are available in the code. If you are interested, see the article by David Vallejo linked to above or review the code in the “Performance Tracking” tag to see what else is available. The additional metrics would need to be added as variables then added as additional parameters on the “GA4 – Event Timing” tag. New dimensions need to be created for those as well.
These four need to be added as custom metrics. In GA4, go to the “Admin” area. In the “Data display” card, click “Custom definitions”. On this page, click the “Custom metrics” tab and then click “Create custom metric”. This will open the “New custom metric” panel. I’ll show the first of these metrics and you can repeat the steps for the other three.
The “Metric name” and “Event parameter” should match the parameter added in GA4. Leave “Scope” set to “Event”. The “Description” is optional. The “Unit of measurement” will be “Milliseconds” for these four metrics.

The “Core Web Vitals Event” will track all available data from Simo Ahava’s template. Currently, this will track all six Core Web Vitals metrics: Time to First Byte (TTFB), First Contentful Paint (FCP), Largest Contentful Paint (LCP), First Input Delay (FID), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS). You can learn more about each of those metrics in my speed metrics guide.
This event uses two parameters: webvitals_name for the metric’s name and webvitals_value for the measured value. The measurement value is also sent to GA4 in the built-in value parameter, which allows for an aggregate view of each metric.
Custom dimensions will need to be created for the two custom parameters. I’ll walk through an example using webvitals_value and you can repeat these steps for webvitals_name. (Adding webvitals_value as a dimension avoids treating CLS as milliseconds incorrectly.)
In GA4, go to the Admin area. In the Data display card, click “Custom definitions”. On this page, click the “Custom dimensions” tab and then click “Create custom dimension”. This will open the “New custom dimensions” panel.
On this panel, the “Dimension name” and “Event parameter” should match the parameter name added in GA4. In this screenshot, I’ve entered “webvitals_value” in both fields. The “Scope” should be “Event”. The “Description” is optional but helpful. Once all data is entered, click save.

Once finished, all dimensions and metrics should be listed in GA4, as follows:

Step #5: Wait and View Reports
After publishing the container with the changes, wait a few days for the data to track in GA4. Then, you can create an Exploration to view these new events.
For example, to create an Exploration for the Performance Timing metrics, you would use the following configurations.

This would result in the following report showing the timing data per page per session. You could export this data and aggregate each timing data by page. These values are reported in milliseconds.

You can also create an Exploration for the Core Web Vitals event using the following configuration settings:

This would output a report that looks like this. Here again, this can be exported and the values can be aggregated by page. The webvitals_value is stated in milliseconds, so divide by 1,000 to get the total number of seconds. For CLS, webvitals_value represents the layout shift score.

Final Thoughts
If you have questions about tracking speed metrics or need further help evaluating speed on your website, contact me today.