Skip to content

perf!: reduce default brotli compression factor to 4, was before 11 (maximum)#278

Merged
mcollina merged 2 commits into
fastify:masterfrom
kahlstrm:perf/use-sensible-brotli-value
Jan 29, 2024
Merged

perf!: reduce default brotli compression factor to 4, was before 11 (maximum)#278
mcollina merged 2 commits into
fastify:masterfrom
kahlstrm:perf/use-sensible-brotli-value

Conversation

@kahlstrm

@kahlstrm kahlstrm commented Jan 28, 2024

Copy link
Copy Markdown
Contributor

BREAKING CHANGE: The default brotli quality value currently is 11, which is not meant to be used in an on the fly compression context. Change this to a more reasonable default value of 4.

Checklist

Comment thread index.js Outdated
@gurgunday

Copy link
Copy Markdown
Member

This looks like a pretty good change

Choosing anything higher than 6 has significant impact on the performance for little benefit

Ref: dotnet/runtime#26097 (comment)

@kahlstrm kahlstrm force-pushed the perf/use-sensible-brotli-value branch 2 times, most recently from 6beb4b6 to 6278077 Compare January 28, 2024 13:33
@kahlstrm kahlstrm requested a review from Uzlopak January 28, 2024 13:33
@kahlstrm

Copy link
Copy Markdown
Contributor Author

This looks like a pretty good change

Choosing anything higher than 6 has significant impact on the performance for little benefit

Ref: dotnet/runtime#26097 (comment)

In this case 4 was chosen as it's apparently a default used by Cloudflare. Related. Here level 5 provides some advantages at files above 64KB so that would also be an alternative.

@Uzlopak

Uzlopak commented Jan 28, 2024

Copy link
Copy Markdown
Contributor

Yeah, makes sense. I also was avoiding brotli for the same reason, and preferred gzip as it has higher throughput. But maybe with brotli compression factor of 4 this drawback does not exist anymore.

@Uzlopak

Uzlopak commented Jan 28, 2024

Copy link
Copy Markdown
Contributor

what does the title mean? sensible brotli value? Maybe some more distinctive title is good, so that reading the release notes it can be determined what changed.

perf: reduce default brotli compression factor to 4, was before 11 (maximum)

@gurgunday gurgunday left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will lgtm after the title change :)

@kahlstrm kahlstrm force-pushed the perf/use-sensible-brotli-value branch from 6278077 to c9bb734 Compare January 28, 2024 13:50
@kahlstrm kahlstrm changed the title perf(index): use sensible brotli value as default perf: reduce default brotli compression factor to 4, was before 11 (maximum) Jan 28, 2024

@Uzlopak Uzlopak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Fdawgs Fdawgs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put an inline comment referencing why we've set the default to 4?

@kahlstrm kahlstrm force-pushed the perf/use-sensible-brotli-value branch 2 times, most recently from fddece4 to 707ddc4 Compare January 29, 2024 00:35
@kahlstrm kahlstrm requested a review from Fdawgs January 29, 2024 00:36
Comment thread index.js Outdated
const params = {
global: (typeof opts.global === 'boolean') ? opts.global : true
global: (typeof opts.global === 'boolean') ? opts.global : true,
// Default of zlib is 11 which is way too heavy for on-the-fly, instead default to 4 as it's used by Cloudflare for on-the-fly compression https://blog.cloudflare.com/this-is-brotli-from-origin#testing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Default of zlib is 11 which is way too heavy for on-the-fly, instead default to 4 as it's used by Cloudflare for on-the-fly compression https://blog.cloudflare.com/this-is-brotli-from-origin#testing
/**
* Default of 4 as 11 has a heavy impact on performance.
* @see {@link https://blog.cloudflare.com/this-is-brotli-from-origin#testing}
*/

@kahlstrm kahlstrm force-pushed the perf/use-sensible-brotli-value branch from 707ddc4 to d476623 Compare January 29, 2024 08:09
@kahlstrm kahlstrm requested a review from Fdawgs January 29, 2024 08:10
@SimenB

SimenB commented Jan 29, 2024

Copy link
Copy Markdown
Member

I'd argue changing the default is a breaking change, and not a "performance improvement". I agree it's a better default, but the behaviour shouldn't change without the consumer having the chance to decide if they value throughput over compression

@climba03003

climba03003 commented Jan 29, 2024

Copy link
Copy Markdown
Member

I'd argue changing the default is a breaking change

Yes, it is.

the behaviour shouldn't change without the consumer having the chance to decide if they value throughput over compression

@SimenB Maybe you overlook the code, it still allow to change the value in brotliOptions. The predefined one is before the spread operator which means it is not non-configurable.

@Uzlopak

Uzlopak commented Jan 29, 2024

Copy link
Copy Markdown
Contributor

As it is breaking the api contract i also concur , that it is a semver-major.

@mcollina

Copy link
Copy Markdown
Member

I'd argue changing the default is a breaking change, and not a "performance improvement".

I'm ok in bumping a major for this.


I agree it's a better default, but the behaviour shouldn't change without the consumer having the chance to decide if they value throughput over compression

Is this implemented already? https://github.com/fastify/fastify-compress?tab=readme-ov-file#brotlioptions-and-zliboptions

@Uzlopak

Uzlopak commented Jan 29, 2024

Copy link
Copy Markdown
Contributor

@mcollina

Yes:

br: () => ((opts.zlib || zlib).createBrotliCompress || zlib.createBrotliCompress)(params.brotliOptions),

@SimenB

SimenB commented Jan 29, 2024

Copy link
Copy Markdown
Member

Yes, the user can set it (IIRC we did lower it at my previous workplace) - I'm just pointing out changing the default (even if configurable) is breaking 🙂 When I said "user should have the chance to decide" I merely meant a major version will "force" the user to make a conscious choice (as it'll be out of semver ranges for people setting that (most, if not all)), rather than a perf version, which is usually a patch release which I assume most people don't comb through changelogs for

@Uzlopak

Uzlopak commented Jan 29, 2024

Copy link
Copy Markdown
Contributor

@SimenB
And to what value did you reduce it?

@SimenB

SimenB commented Jan 29, 2024

Copy link
Copy Markdown
Member

I haven't worked there for 5 months, but I asked a former colleague, and he sent this snippet

// fastify-compress by default uses brotli quality at 11 (max), which is really
// slow. This sets it at 5 instead which is better for on-the-fly compression,
// based on https://blog.cloudflare.com/results-experimenting-brotli/
// Based on the same blog post, it sets zlib quality to 8.
// It also sets the operation to flush to work with streaming responses.
// Otherwise it will buffer everything (i.e. streaming won't work) which will
// impact TTFB.
const compressPlugin: FastifyPluginAsync = async instance => {
  instance.register(fastifyCompress, {
    zlibOptions: {
      flush: zlib.constants.Z_SYNC_FLUSH,
      level: 8,
    },
    brotliOptions: {
      flush: zlib.constants.BROTLI_OPERATION_FLUSH,
      params: {
        [zlib.constants.BROTLI_PARAM_QUALITY]: 5,
      },
    },
  });
};

(credit to @hzr)

@kahlstrm

kahlstrm commented Jan 29, 2024

Copy link
Copy Markdown
Contributor Author

I haven't worked there for 5 months, but I asked a former colleague, and he sent this snippet

// fastify-compress by default uses brotli quality at 11 (max), which is really
// slow. This sets it at 5 instead which is better for on-the-fly compression,
// based on https://blog.cloudflare.com/results-experimenting-brotli/
// Based on the same blog post, it sets zlib quality to 8.
// It also sets the operation to flush to work with streaming responses.
// Otherwise it will buffer everything (i.e. streaming won't work) which will
// impact TTFB.
const compressPlugin: FastifyPluginAsync = async instance => {
  instance.register(fastifyCompress, {
    zlibOptions: {
      flush: zlib.constants.Z_SYNC_FLUSH,
      level: 8,
    },
    brotliOptions: {
      flush: zlib.constants.BROTLI_OPERATION_FLUSH,
      params: {
        [zlib.constants.BROTLI_PARAM_QUALITY]: 5,
      },
    },
  });
};

(credit to @hzr)

I've set mine to 5 as well in the project I'm using this in, so for me that's fine as well 👍 . The improvement of quality level 5 over 4 is seemingly more signifant with filesizes above 64 KB according to the Cloudflare article posted previously. Here is some analysis from 2015

@gurgunday

Copy link
Copy Markdown
Member

8 seems too much 😅, but I fully get that it is much better than the current default

64kb is significant for text data, I don't believe the average size of an HTML page or a CSS file is up there

I think 4 is a good default

@kahlstrm

Copy link
Copy Markdown
Contributor Author

8 seems too much 😅, but I fully get that it is much better than the current default

64kb is significant for text data, I don't believe the average size of an HTML page or a CSS file is up there

I think 4 is a good default

Note that in the snippet zlib is set at 8, which is comparable to brotli quality 4 IIRC. The brotli level inthe snippet is below to level 5.

@Fdawgs Fdawgs changed the title perf: reduce default brotli compression factor to 4, was before 11 (maximum) perf!: reduce default brotli compression factor to 4, was before 11 (maximum) Jan 29, 2024
@mcollina mcollina merged commit aa3079a into fastify:master Jan 29, 2024
@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Apr 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants