{"id":18926068,"url":"https://github.com/getpagespeed/ngx_immutable","last_synced_at":"2025-04-15T13:32:26.688Z","repository":{"id":40783205,"uuid":"242341106","full_name":"GetPageSpeed/ngx_immutable","owner":"GetPageSpeed","description":"NGINX module for setting immutable caching on static assets","archived":false,"fork":false,"pushed_at":"2023-02-25T06:09:10.000Z","size":18,"stargazers_count":13,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T22:06:11.215Z","etag":null,"topics":["cache","cache-busting","cache-control","caching","expires","immutable","module","nginx","nginx-module"],"latest_commit_sha":null,"homepage":"https://nginx-extras.getpagespeed.com/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GetPageSpeed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"GetPageSpeed","patreon":"getpagespeed","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-02-22T12:52:02.000Z","updated_at":"2025-03-12T15:40:23.000Z","dependencies_parsed_at":"2023-01-21T16:00:27.894Z","dependency_job_id":null,"html_url":"https://github.com/GetPageSpeed/ngx_immutable","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_immutable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_immutable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_immutable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_immutable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GetPageSpeed","download_url":"https://codeload.github.com/GetPageSpeed/ngx_immutable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249080279,"owners_count":21209499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","cache-busting","cache-control","caching","expires","immutable","module","nginx","nginx-module"],"created_at":"2024-11-08T11:14:26.123Z","updated_at":"2025-04-15T13:32:26.398Z","avatar_url":"https://github.com/GetPageSpeed.png","language":"C","funding_links":["https://github.com/sponsors/GetPageSpeed","https://patreon.com/getpagespeed","https://www.buymeacoffee.com/dvershinin"],"categories":[],"sub_categories":[],"readme":"# ngx_immutable\n\n[![Build Status](https://travis-ci.org/GetPageSpeed/ngx_immutable.svg?branch=master)](https://travis-ci.org/GetPageSpeed/ngx_immutable)\n[![Coverity Scan](https://img.shields.io/coverity/scan/GetPageSpeed-ngx_immutable)](https://scan.coverity.com/projects/GetPageSpeed-ngx_immutable)\n[![Buy Me a Coffee](https://img.shields.io/badge/dynamic/json?color=blue\u0026label=Buy%20me%20a%20Coffee\u0026prefix=%23\u0026query=next_time_total\u0026url=https%3A%2F%2Fwww.getpagespeed.com%2Fbuymeacoffee.json\u0026logo=buymeacoffee)](https://www.buymeacoffee.com/dvershinin)\n\nThis tiny NGINX module can help improve caching of your public static assets, by setting far future expiration with `immutable` attribute.\n\n## Intended audience\n\nWebsites and frameworks which rely on the cache-busting pattern:\n\n* static resources include version/hashes in their URLs, while never modifying the resources\n* when necessary, updating the resources with newer versions that have new version-numbers/hashes, \nso that their URLs are different\n\nPopular frameworks which use cache-busting:\n\n* Magento 2\n* Include your own here! \n\n## Synopsis\n\n```nginx\nhttp {\n    server {\n        location /static/ {\n            immutable on;\n        }\n    }\n}\n```\n\nwill yield the following HTTP headers:\n\n```\n...\nCache-Control: public,max-age=31536000,stale-while-revalidate=31536000,stale-if-error=31536000,immutable\nExpires: Thu, 31 Dec 2037 23:55:55 GMT \n...\n```\n\nHow it's different to `expires max;`:\n\n* Sets `immutable` attribute, e.g. `Cache-Control: public,max-age=31536000,immutable` for improved caching. \nThat is 1 year and not 10 years, see why below.\n* Sends `Expires` only when it's really necessary, e.g. when a client is requesting resources over `HTTP/1.0`\n* Sets `public` attribute to ensure the assets can be cached by public caches, which is typically a desired thing.\n\nDue to the [lacking support of `immutable`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#browser_compatibility) in Chromium-based browsers, \nwe also add `stale-while-revalidate=31536000,stale-if-error=31536000` which helps to improve cache hit-ratio in edge cases. \nUse of these directives allows serving cached responses beyond their cache lifetime, which is forever in case of immutable resources.\n\nThus, in most cases, `immutable on;` can be used as a better alternative to `expires max;` to implement the cache-busting pattern.\n\n### Why 31536000 seconds (1 year?)\n\nThe [RFC](https://www.ietf.org/rfc/rfc2616.txt) defines to use one year to make a response as \"never expires\":\n\n\u003e To mark a response as “never expires,” an origin server sends an\n\u003e Expires date approximately one year from the time the response is\n\u003e sent. HTTP/1.1 servers SHOULD NOT send Expires dates more than one\n\u003e year in the future.\n\nMore details in [the article](https://ashton.codes/set-cache-control-max-age-1-year/).\n\n## Installation \n\nGetPageSpeed provides packaging of the `nginx-module-immutable` in its repositories, as part of its [NGINX Extras](https://nginx-extras.getpagespeed.com/) package collection.\n\nThe follow operating systems are supported:\n\n* RedHat Enterprise Linux 6, 7, 8, 9\n* CentOS 6, 7, 8, 9\n* AlmaLinux 8, 9\n* Rocky Linux 8, 9\n* Amazon Linux 2\n* Fedora Linux, the 2 most recent releases \n\nThe installation requires a [subscription](https://www.getpagespeed.com/repo-subscribe) for all the operating systems listed, except Fedora Linux, for which it is free.\n\n### How to install\n\nFor any OS listed above, installation steps are the same:\n\n```bash\nsudo yum -y install https://extras.getpagespeed.com/release-latest.rpm\nsudo yum -y install nginx-module-immutable\n```\n\nFollow the installation prompt to import GPG public key that is used for verifying packages.\n\nThen add the following at the top of your `/etc/nginx/nginx.conf`:\n\n```nginx\nload_module modules/ngx_http_immutable_module.so;\n```\n\n## Example: Magento 2 production configuration\n\nProvided that your store runs in production mode, you have already compiled all the assets.\nThis [sample config](https://github.com/magento/magento2/blob/2.3.4/nginx.conf.sample#L103-L134) can be optimized to:\n\n```nginx\nlocation /static/ {\n    immutable on;\n\n    # Remove signature of the static files that is used to overcome the browser cache\n    location ~ ^/static/version {\n        rewrite ^/static/(version\\d*/)?(.*)$ /static/$2 last;\n    }\n\n    location ~* \\.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ {\n        add_header X-Frame-Options \"SAMEORIGIN\";\n    }\n    location ~* \\.(zip|gz|gzip|bz2|csv|xml)$ {\n        add_header Cache-Control \"no-store\";\n        add_header X-Frame-Options \"SAMEORIGIN\";\n        immutable off;\n    }\n    add_header X-Frame-Options \"SAMEORIGIN\";\n}\n```\n\nWhen used together with [`ngx_security_headers`](https://github.com/GetPageSpeed/ngx_security_headers), it can be simplified further:\n\n```nginx\nsecurity_headers on;\n\nlocation /static/ {\n    immutable on;\n\n    \n    location ~ ^/static/version {\n        rewrite ^/static/(version\\d*/)?(.*)$ /static/$2 last;\n    }\n\n    location ~* \\.(zip|gz|gzip|bz2|csv|xml)$ {\n        add_header Cache-Control \"no-store\";\n        immutable off;\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetpagespeed%2Fngx_immutable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetpagespeed%2Fngx_immutable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetpagespeed%2Fngx_immutable/lists"}