Web performance issue with cache

Hi everyone,

I’m looking for help with a web performance issue on a website hosted on HubSpot CMS. Our load times are very poor, and our SEO agency identified a major blocker: browser caching is almost disabled.

On our pages (HTML), the response headers show:

  • Cache-Control: s-maxage=0, max-age=5

Which means:

  • no shared caching / CDN caching (s-maxage=0)
  • only 5 seconds of browser caching (max-age=5)

As a result, every refresh forces the browser to re-request the page instead of using its local cache. In our CrUX data, we see only ~0.83% of visits using cache, which seems extremely low and likely impacts real browsing performance.

Our agency recommends targeting something like:

  • Cache-Control: public, max-age=3600 (1 hour browser cache)

My questions:

  1. In HubSpot, is it possible to configure/override Cache-Control headers for HTML pages? If yes, where/how?
  2. Are there HubSpot features that can force a very low max-age (dynamic modules, personalization, A/B tests, forms, etc.)? How can I identify what is causing it?
  3. If HubSpot doesn’t allow this natively, is the right approach to put use CDN with Cloudlfare in front to override caching rules? Any common pitfalls (tracking, consent banner behavior, dynamic content, publishing workflow)?

Goal: improve performance without breaking content updates (we publish often) and keeping a sane setup for public pages.

Thanks in advance for any guidance, best practices, or relevant docs!

1. As far as I’m aware, no. CMS-React has some new functionality for caching for modules:

2. Do you have any personalization in your CMS pages? If so, this generally causes a lot of the caching to be disabled. For CMS, this is generally what I see most often that causes Hubspot to not send a cache copy.

If you are having these caching issues and don’t have any personalization, then that would be strange. My public site hosted on Hubspot has cache-control enabled and is super speedy but my private content portal, which as a tons of personalization, is much slower due to the personalization.

3. Hubspot already uses Cloudflare so you’ll be doubling-up on CF and may not even work.

To be clear, the CDN for assets should be perfectly fine regardless of #2.

If you plan to use CF workers to cache the pages, any personalization (#2) is probably going to cause issues in caching via workers as caching via this method doesn’t work well with custom data being presented to users.

Hi,
Thanks Michael, this was the right direction.
We actually don’t use Smart Content/personalization (no dynamic content) and no adaptive tests.
We ran ?hsDebugOnly=true and confirmed the page is NOT prerenderable because our templates/modules use uncacheable server-side expressions: local_dt in header-section-v2, and request.query_dict, request.cookies, request.path_and_query in our quote-tool module. This explains why HubSpot sets x-hs-cache-config: BrowserCache-5s-EdgeCache-0s and Cache-Control: s-maxage=0,max-age=5.

Next step for us is to refactor those modules so the HTML no longer depends on request.* or server time (move UTM/cookie/path handling to client-side JS + hidden fields).

If you have any best practices for keeping HubSpot forms tracking while staying prerenderable/cacheable, I’m all ears.

Hi @SimonSA, I hope that you are well!
You’re on the right track, handling UTM, cookie, and path data with client-side JavaScript is definitely the recommended approach, as it helps you avoid uncacheable server-side expressions like request.* and local_dt.*.

For HubSpot forms tracking, you can take advantage of client-side features like addIdentityListener (which helps with cross-domain tracking) and refreshPageHandlers (great for dynamic content).
These run on the client side and won’t impact your page’s cacheability.
Hi @MichaelMa, @Anton and @sylvain_tirreau do you have best practices to share with @SimonSA, please?
Thanks so much and have a lovely day!
Bérangère
This post was created with the assistance of AI tools

Hey @SimonSA, getting back to you on this!
I found a few best practices from our documentation that can help you stay prerenderable while keeping your tracking fully functional:

For request.* variables, here are some client-side JavaScript alternatives:

- Instead of request.cookies, use document.cookie in JavaScript.
- Swap request.query_dict or request.path_and_query for window.location.search and URLSearchParams.
- For the local date-time (local_dt), you can use JavaScript’s Date on the client side.
When it comes to forms and tracking, the great news is that HubSpot forms include their own tracking scripts.
You can also populate hidden fields client-side with JavaScript, simply read UTM parameters from URLSearchParams and set your hidden field values with the forms API, especially in the onFormReady callback.

A few more helpful tips from the documentation:

- Handle dynamic content on the client side using JavaScript.
- If you need server-side logic, consider using serverless functions to maintain prerendering compatibility.
- Once you’re done refactoring, you can verify everything by using ?hsDebugOnly=true to confirm your page remains prerenderable.
Here are some resources for you:
- Optimizing your HubSpot CMS site for speed
- CDN, security, and performance overview
I hope this helps!
Have a lovely day! :sun_with_face:
Bérangère
This post was created with the assistance of AI tools

Hi @BérangèreL, thank you this is super helpful.

It matches what we saw in ?hsDebugOnly=true: request.* and local_dt are blocking prerendering, so we’ll move UTM/path/cookie/date logic to client-side JS and populate HubSpot form hidden fields in onFormReady.

We’ll also look into addIdentityListener and refreshPageHandlers for tracking without impacting cacheability.

I’m sharing all of this with our developers so they can implement the changes.

Thanks again, really appreciate your guidance and the resources!

My pleasure @SimonSA :orange_heart: I am so glad it helped!
You’re very welcome! Don’t hesitate to create a new post if you have any other questions, we are here for you!
Have a wonderful day and looking forward to seeing you around the Community @SimonSA!
Bérangère