Brotli and Gzip reduce the number of bytes transferred for compressible HTTP responses such as HTML, CSS, JavaScript, JSON, XML and SVG.
The goal is not to compress every file type at the highest possible level. The goal is to compress resources that benefit from text-oriented lossless compression, choose a sensible algorithm and compression level, avoid wasting CPU on already compressed formats, and verify that clients and caches receive the correct encoded representation.
This guide explains how Accept-Encoding, Content-Encoding and Vary: Accept-Encoding work, how Brotli compares with Gzip, when dynamic or precompressed delivery makes sense, and how to test compression on Nginx, Apache, WordPress, CDN-based sites and Blogger-managed pages.
This article is based on current MDN HTTP compression and content-encoding documentation plus official Nginx and Apache module documentation.
It does not claim that Digital Bhatti ran a controlled Brotli-vs-Gzip benchmark or measured universal transfer savings, TTFB changes or Core Web Vitals improvements.
Last verified: September 26, 2026.
Current browser navigation requests commonly advertise gzip, deflate, br and increasingly zstd. This guide stays focused on Brotli and Gzip because they remain widely deployed and directly supported by the server/CDN configurations covered here.
Compress Text-Like Responses; Avoid Recompressing Already Compressed Media
Enable Brotli or Gzip for compressible HTML, CSS, JavaScript, JSON, XML and SVG. Avoid spending CPU recompressing JPEG, WebP, AVIF, video, ZIP and similar formats that already use compression.
1. What Is HTTP Content Compression?
HTTP content compression reduces the size of a representation before it is transferred over the network. The browser advertises the encodings it understands, the server chooses an encoding it supports, and the response identifies the selected encoding.
This is lossless representation compression: after decoding, the browser receives the original content represented by the resource.
2. How Accept-Encoding Works
The browser sends an Accept-Encoding request header listing encodings it can decode.
Accept-Encoding: gzip, deflate, br, zstd
The exact list varies by browser and request context. Clients can also send quality weights such as br;q=1.0, gzip;q=0.8. The server selects a supported representation; identity means no content coding and remains acceptable unless negotiation explicitly forbids it.
3. How Content-Encoding Works
The response tells the client which representation encoding was actually used. When Content-Encoding is present, metadata such as Content-Length describes the encoded representation, not the larger decoded resource body.
Content-Encoding: br
or:
Content-Encoding: gzip
4. Why Vary: Accept-Encoding Matters
When caches may store different encoded variants of the same URL, they need to know that the response changes according to the client's supported encoding.
Vary: Accept-Encoding
This helps a shared cache keep compatible encoded representations separate so a client that does not support Brotli is not accidentally served a Brotli-coded cached object. If compression selection depends on additional request headers, those inputs may also need to be represented in Vary.
5. Content-Encoding Is Not Transfer-Encoding
| Header | Purpose |
|---|---|
| Content-Encoding | Describes how the representation body is encoded, commonly for compression. |
| Transfer-Encoding | Describes hop-by-hop transfer behavior for the message. |
6. Which Resources Usually Benefit?
- HTML
- CSS
- JavaScript
- JSON
- XML
- SVG
- Plain text
- Many text-based API responses
These formats usually contain enough repeated text patterns to compress effectively. Compression still depends on the actual payload: tiny responses or already heavily minified/generated data may produce smaller gains than larger repetitive text.
7. Which Resources Usually Should Not Be Recompressed?
- JPEG
- WebP
- AVIF
- MP4 and other compressed video
- MP3/AAC and other compressed audio
- ZIP/GZIP archives
- WOFF2 web fonts
HTTP recompression of already compressed files often saves little and adds CPU work. That includes WOFF2 fonts as well as compressed image, audio, video and archive formats.
For image-specific optimization, use the WebP & AVIF Image Optimization Guide. For font-specific delivery, preload, WOFF2 and fallback behavior, use the Web Font Performance Optimization Guide.
8. Brotli vs Gzip
| Area | Brotli | Gzip |
|---|---|---|
| Browser support | Widely supported in modern browsers. | Extremely mature and broadly supported. |
| Compression efficiency | Can produce smaller text responses at suitable settings. | Good general-purpose text compression. |
| CPU cost | Higher Brotli quality settings can be expensive; Apache documents quality 5 as its dynamic default. | Often practical for dynamic compression at moderate levels. |
| Role | Preferred where supported/configured. | Strong compatibility fallback. |
9. Do Not Promise a Fixed Compression Percentage
Compression results vary with file type, file size, minification, repeated strings and compression level. Use actual transfer measurements from your site instead of quoting a universal percentage.
10. Compression Level Is a CPU vs Size Trade-off
Higher settings usually spend more CPU looking for a smaller representation. Strong settings are easier to justify for files compressed once during deployment than for dynamic HTML or API responses compressed on every request.
Use Stronger Compression Where You Can Pay the CPU Cost Once
Precompressed static assets can justify more expensive settings than live responses compressed repeatedly during traffic.
11. Dynamic Compression
Dynamic compression happens while the response is generated or served. It is useful for HTML and changing JSON/API output, but it consumes CPU during live requests.
12. Precompressed Static Assets
app.js
app.js.gz
app.js.br
styles.css
styles.css.gz
styles.css.br
Precompression moves expensive work out of the request path and is well suited to versioned static files. The server still needs correct content negotiation so clients receive the encoded variant they actually support and the uncompressed file remains available when required.
13. Nginx Gzip Example
gzip on;
gzip_vary on;
gzip_types
text/plain
text/css
application/javascript
application/json
application/xml
image/svg+xml;
Nginx's gzip filter compresses text/html by default when gzip is enabled; gzip_types adds other MIME types. gzip_vary on can add Vary: Accept-Encoding. Nginx also exposes $gzip_ratio if you want to log achieved compression ratios instead of estimating them.
Confirm your Nginx build, MIME configuration, reverse-proxy behavior and hosting defaults before changing production settings.
Nginx's gzip documentation also warns that compressed TLS responses can be subject to BREACH-family side-channel attacks in vulnerable application designs. Treat compression of responses that mix secrets with attacker-controlled input as a security decision, not only a performance setting.
14. Nginx Precompressed Gzip
The optional ngx_http_gzip_static_module can serve existing .gz files.
gzip_static on;
This module is not built by default; Nginx documents it as requiring the --with-http_gzip_static_module build option. It checks for precompressed .gz files and uses other gzip negotiation directives when deciding whether they can be served.
15. Brotli on Nginx Requires Module or Platform Support
Do not assume Brotli directives are universally available in Nginx. The standard Nginx documentation covers gzip modules; Brotli commonly depends on an added module, managed hosting layer, reverse proxy or CDN. Verify the actual build before using copied Brotli directives.
16. Apache Compression
Apache commonly uses mod_deflate for Gzip-compatible compression and mod_brotli for Brotli. mod_brotli is available in Apache HTTP Server 2.4.26+ and exposes compression quality from 0 to 11; the documented default is 5, described as a reasonable dynamic-content balance.
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css application/javascript
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript
Do not paste both blindly and assume the desired negotiation/order. Confirm module availability, existing host/CDN behavior and the final Content-Encoding. Apache's Brotli and Deflate documentation also warns about BREACH-family risks for compressed TLS responses.
On shared hosting, verify loaded modules and host defaults before adding rules to .htaccess.
17. LiteSpeed and OpenLiteSpeed
LiteSpeed-family servers can provide compression through their own server configuration and hosting panels. Follow the actual platform controls rather than assuming Nginx or Apache directives apply.
18. CDN and Cloud Compression
A CDN can compress eligible responses at the edge or cache encoded variants produced upstream. Verify Brotli/Gzip support, MIME rules, fallback behavior and cache handling in the current provider documentation. When both origin and CDN offer compression, inspect the final response rather than assuming which layer performed the work.
19. Compression and Browser Caching Work Together
Compression reduces bytes when a response is transferred. Browser caching can avoid that transfer entirely on repeat requests. They are complementary optimizations rather than substitutes.
Use the Browser Caching, Cache-Control & ETag Guide for freshness, revalidation, immutable assets and 304 Not Modified behavior.
20. Compression Does Not Fix TTFB by Itself
Compression does not solve slow database queries, application work or server queueing. Aggressive dynamic compression can also add CPU cost.
For backend diagnosis, use the TTFB Optimization Guide.
21. Compression and HTTP/3 Solve Different Layers
HTTP/3 changes transport behavior; Brotli/Gzip change representation size. They are independent layers and can be used together. Switching transport protocols does not remove the need to negotiate a suitable content encoding.
See the HTTP/3 & QUIC Performance Guide.
22. Compression and Minification Are Different
Minification removes unnecessary source characters. HTTP compression encodes the resulting file more efficiently for transfer. Production CSS/JS can use both.
23. SVG Is a Good Compression Candidate
SVG is XML-based text, so it can often benefit from HTTP compression even though it represents graphics.
24. JSON and API Responses
JSON often compresses well because property names and syntax repeat. For latency-sensitive APIs, measure reduced transfer size against dynamic compression CPU cost.
25. Small Responses May Not Need Compression
Very small payloads can gain little from compression. Many servers therefore provide minimum-size controls. Choose thresholds based on your actual stack rather than one universal value.
26. Security Considerations
Compression over encrypted connections has known BREACH-family side-channel considerations where secrets and attacker-controlled input can influence the same compressed response. Nginx and Apache both call this out in their compression-module documentation. Treat sensitive dynamic responses as a security-design problem and follow current application/server guidance rather than enabling compression indiscriminately.
27. WordPress Compression Optimization
Compression may already be handled by the host, Nginx/Apache/LiteSpeed, a CDN or reverse proxy. Inspect actual response headers before adding another optimization layer.
28. Blogger Compression Limitations
Blogger users generally cannot configure Google's underlying origin compression directly.
- Inspect
Content-Encodingin DevTools. - Confirm what Blogger/Google already serves.
- Optimize externally hosted resources you control.
- Do not apply Nginx/Apache directives to Blogger-hosted HTML.
29. Verify Compression in Chrome DevTools
Open DevTools → Network, reload the page and select a text resource. Inspect the response headers for:
Content-Encoding: br
or:
Content-Encoding: gzip
Also compare transferred size with decoded/resource size where DevTools exposes both. A smaller transferred value plus the expected Content-Encoding is more useful evidence than relying only on a generic audit label.
30. Test With curl
curl -I \
-H "Accept-Encoding: br, gzip" \
https://example.com/
Inspect Content-Encoding and Vary. For a body-level check, curl --compressed asks curl to advertise supported compression and automatically decompress the response it receives; build capabilities still vary.
31. Compression Decision Matrix
| Resource / Situation | Consider | Verify |
|---|---|---|
| HTML, CSS, JS, JSON, XML, SVG | Brotli/Gzip | Transfer size and CPU cost. |
| Versioned static text assets | Precompressed files | Server/CDN support. |
| Dynamic HTML/API | Moderate dynamic compression | CPU and response latency. |
| Sensitive dynamic response mixes secrets and user-controlled input | Security review before compression | BREACH-style exposure and application threat model. |
| Origin and CDN both advertise compression features | Verify final negotiation | Final Content-Encoding, Vary and cache variants. |
| JPEG/WebP/AVIF/video/archive | Usually leave as-is | Whether recompression creates any real saving. |
32. Compression Specialist Guide Map
| Observed Problem | Primary Owner | This Page Owns |
|---|---|---|
| Static asset downloads again on repeat visit | Browser Caching | Whether the transferred representation is Brotli/Gzip compressed. |
| Slow origin response before body transfer | TTFB Optimization | Compression CPU and body size after the response begins. |
| Large JPEG/WebP/AVIF | Image Optimization | Do not treat image-format compression as HTTP text compression. |
| WOFF2/font issue | Web Font Performance | Avoid pointless recompression and verify negotiated encoding only where relevant. |
| Transport/protocol behavior | HTTP/3 & QUIC | Representation compression independent of transport protocol. |
33. Prevent Compression Regressions
Compression can regress when MIME types change, CDN settings are altered, a server module is removed, precompressed files stop being generated, or a proxy begins serving uncompressed variants.
Track representative HTML, CSS, JavaScript, JSON and SVG responses and verify their negotiated Content-Encoding after infrastructure changes. The Web Performance Budgets & Regression Monitoring Guide covers ongoing release checks.
34. Safe Compression Optimization Workflow
- Inventory large text responses.
- Inspect current
Content-Encoding. - Confirm origin/CDN support and which layer should own compression.
- Enable one compression layer intentionally.
- Choose appropriate MIME types.
- Avoid already-compressed formats.
- Measure transferred bytes.
- Measure CPU/latency for dynamic compression and review sensitive endpoints for compression side-channel risk.
- Verify
Vary: Accept-Encoding. - Retest under realistic conditions.
35. Before-and-After Verification Checklist
- Record URL and date.
- Record original transfer size.
- Check request
Accept-Encoding. - Check response
Content-Encoding. - Check
Vary: Accept-Encoding. - Confirm
Content-Lengthis interpreted as encoded bytes whenContent-Encodingis present. - Confirm origin/CDN are not creating unexpected double-compression or cache-variant behavior.
- Check sensitive dynamic endpoints before enabling compression broadly.
- Test HTML, CSS, JavaScript, JSON and SVG.
- Confirm image/video/archive formats are not pointlessly recompressed.
- Check CPU usage for dynamic compression.
- Check TTFB under realistic load.
- Test CDN and origin behavior separately.
36. Common Brotli and Gzip Mistakes
- Compressing everything: already compressed media often gains little.
- Using maximum dynamic compression blindly: CPU cost can outweigh marginal savings.
- Forgetting Vary: shared caches can mishandle encoded variants.
- Confusing Content-Encoding and Transfer-Encoding: they solve different protocol concerns.
- Assuming Brotli exists in every Nginx build: module availability varies.
- Stacking duplicate host/CDN/plugin compression: inspect actual response headers first.
- Using server directives on Blogger: Blogger does not expose Nginx/Apache configuration.
- Forcing one encoding regardless of Accept-Encoding: representation negotiation must still respect client capability.
- Reading Content-Length as the decoded size: with Content-Encoding it describes the encoded representation.
- Ignoring BREACH-style risk on sensitive dynamic responses: compression is not purely a transfer-size decision.
- Assuming every Nginx build has Brotli: standard Nginx docs cover gzip; Brotli commonly comes from an added module or platform layer.
Frequently Asked Questions
Is Brotli better than Gzip?
Brotli can produce smaller text representations at suitable settings, while Gzip remains extremely mature and broadly compatible. The better choice depends on your delivery stack, resource type and CPU budget.
What if the browser also advertises Zstandard?
Modern browsers can advertise zstd alongside Brotli and Gzip. The server chooses a mutually supported encoding according to its configuration and negotiation rules. This guide stays focused on Brotli/Gzip because they remain widely deployed.
Is Brotli always faster than Gzip?
No. Brotli can produce smaller text representations, but higher compression settings can require more CPU. Gzip can be a practical dynamic-compression fallback when CPU cost matters.
Should I enable both Brotli and Gzip?
Many deployments use Brotli for compatible clients and retain Gzip as a fallback. The server or CDN negotiates an encoding based on client support.
Should images be compressed with Brotli or Gzip?
Usually not when they are already in compressed formats such as JPEG, WebP or AVIF. Optimize those with image-specific tools instead.
Does compression improve Core Web Vitals?
Smaller text responses can reduce transfer time when bandwidth is a bottleneck, but compression alone does not guarantee good LCP, INP or CLS. Use the Core Web Vitals Optimization Guide for metric-level diagnosis.
Does compression reduce TTFB?
Not necessarily. Dynamic compression consumes CPU and can add work to the response path. Its primary purpose is reducing response-body transfer size.
What does Vary: Accept-Encoding do?
It tells caches that a response can differ according to the client's supported content encodings.
Should CSS and JavaScript still be minified?
Yes. Minification and HTTP compression solve different problems and can be used together.
Can Blogger users enable Brotli manually?
Not on Google's underlying Blogger infrastructure. Blogger users can inspect what Google serves and optimize only resources hosted on infrastructure they control.
Final Takeaway
Brotli and Gzip are most useful when they reduce transfer size for text-like responses without adding unreasonable server work.
Compress HTML, CSS, JavaScript, JSON, XML and SVG; avoid wasting CPU recompressing already compressed images, audio, video and archives; and use precompression for static assets where your delivery stack supports it.
The strongest configuration is the one that delivers smaller compatible representations, correct cache variants and sensible CPU cost across the origin, CDN and browser.
Compress What Benefits, Measure What It Costs
Use Brotli or Gzip for text-like responses, avoid recompressing already-compressed formats, and verify both transfer size and dynamic CPU cost. Compression should reduce bytes without creating a new server bottleneck.
Abdul Shakoor
Founder of Digital Bhatti, focused on web hosting and infrastructure, WordPress performance, Linux VPS environments, web servers and technical SEO.
This guide is documentation-led. It does not claim a Digital Bhatti compression ratio, byte saving, CPU improvement, TTFB reduction, Lighthouse gain or field Core Web Vitals result without controlled before/after evidence.
