Skip to content

Proposal: add brotli encoding#13196

Closed
ghost wants to merge 2 commits intodevfrom
unknown repository
Closed

Proposal: add brotli encoding#13196
ghost wants to merge 2 commits intodevfrom
unknown repository

Conversation

@ghost
Copy link
Copy Markdown

@ghost ghost commented Feb 5, 2026

What is it?

  • Feature (user facing) ⚠️ Your PR must target the refactor branch
  • Meta improvement to the project (dev facing)

Description of the changes in your PR

⚠️ DISCLAIMER: ⚠️ This is a "proposal" PR to show off the idea and ask for help with further testing and evaluating. It is not like it is draft because it is rather finished prototype. I am unable to evaluate RAM, CPU and BATTERY usage in my setup

  • Bluntly adds Accept-Encoding: brotli gzip support to every http request for every service (so maybe it needs special handling to add it only for youtube)
  • Gzip support is by default added by OkHttp so it is currently used by newpipe
  • If brotli is somehow used for thumbs, it is probably very bad because uses cpu and doesn't reduce bandwidth consumption. Though gzip also uses cpu. But it seems like thumbs and other images doesn't use brotli. How to check? ¯\_(ツ)_/¯
  • PeerTube and media.ccc.de don't support even gzip
  • All services ignore zstd so there is no sense to add it to newpipe
  • Brotli is supported only for youtube
  • If we are going to add it (or some ephemeral implementaion which adds brotli only to youtube) we probably need to update extractor mocks too
  • Descriptions are small and they are already compressed by gzip. They don't profit from brotli at all
0.28.2 brotli_test difference difference %
APK size1 12494057 bytes 12573083 bytes + 79026 bytes + 0.63%
Feed update 53 channels 4.1 MB 3.7 MB - 0.4 MB - 9.75%
Feed update 133 channels 9.3 MB 8.3 MB - 1.0 MB - 10.75%
- - - -
Feed load thumbs only 1 8.4 MB 8.3 MB - 0.1 MB - 1.19% 2
Feed load thumbs only 2 9.6 MB 9.6 MB 0 MB - 0% 2
- - - -
Opening video 106.72 KB 94.7 KB 12.02 KB - 11.26%
Opening video + description 106.96 KB 95.0 KB 11.96 - 11.18%
Opening video + comments 227.42 KB 194.56 KB 32.86 KB - 14.44%
Opening chnannel 65.48 KB 60.44 KB 5.04 KB - 7.69%
- - - -
RAM usage How to measure? How to measure? How to measure? How to measure?
CPU usage How to measure? How to measure? How to measure? How to measure?
Battery usage How to measure? How to measure? How to measure? How to measure?
Feed update speed3 How to measure? How to measure? How to measure? How to measure?

Fixes the following issue(s)

APK testing

The APK can be found by going to the "Checks" tab below the title. On the left pane, click on "CI", scroll down to "artifacts" and click "app" to download the zip file which contains the debug APK of this PR. You can find more info and a video demonstration on this wiki page.

Due diligence

Footnotes

  1. Showed numbers for clean 0.28.2 and 0.28.2 + brotli_test commit, dev branch will probably give other results especially taking into account recent messing with resource optimizations

  2. Probably it is just a measurement error and there is no difference 2

  3. because of artificial limit we have to not be rate limited they can be the same

@github-actions github-actions Bot added the size/small PRs with less than 50 changed lines label Feb 5, 2026
@TobiGr
Copy link
Copy Markdown
Contributor

TobiGr commented Feb 6, 2026

just out of iterest: could you also test how much data is saved when opening a video detail page and when loading comments? Thank you.

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 6, 2026

just out of iterest: could you also test how much data is saved when opening a video detail page and when loading comments? Thank you.

Yeah good idea. I concentrated too much on profiling/debugging that forgot I can test other things 😅

I will test it soon. Moreover it finally clicked that I can easily remove any image data noise by using Image quality -> dont load images in tests. I think I will also test playlist loading, channel loading and search

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 7, 2026

@TobiGr the table is updated! Descriptions are small and they are already compressed by gzip. They don't profit from brotli at all

@TobiGr
Copy link
Copy Markdown
Contributor

TobiGr commented Feb 8, 2026

I'd be in favor of adding brotli. I would not expect any improvements for non text-based content(images, audio, video, ...).

@TobiGr TobiGr added the performance Related to performance and optimisation; affects the speed or memory efficiency of the application label Feb 8, 2026
@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 8, 2026

I'd be in favor of adding brotli

So there comes mainly two questions:

  1. Should I start working on implementation which adds brotli to youtube only? (It probably will be messy because I already somewhat tried). I am not sure but other services can use it as fingerprinting if we tell the brotli is available?
  2. I we should create some new setting (yeah it is bad but as I know brotli consumes more resources which I can't check because can't test physical devices now...)

I would not expect any improvements for non text-based content(images, audio, video, ...).

I agree.

@jpds
Copy link
Copy Markdown
Contributor

jpds commented Feb 8, 2026

PeerTube and media.ccc.de don't support even gzip

Where do you see this? Both of these return content-encoding: gzip in Firefox's inspect window for me.

I also do not expect a well-configured webserver to ever compress non-text content, this is what Caddy does out of the box: https://caddyserver.com/docs/caddyfile/directives/encode

@Stypox
Copy link
Copy Markdown
Member

Stypox commented Feb 8, 2026

Thanks for your research! Given your findings, I'd also be ok with merging this PR as is. If problems come up, it will be very easy to revert.

Should I start working on implementation which adds brotli to youtube only?

Since all browsers since quite some time already support brotli, and they include 'br' in 'Accept-Encoding', we become less fingerprintable if we also support brotli. So I think this is not needed.

I we should create some new setting

No. If it actually is a problem on some phones, I wouldn't add brotli at all, rather than add a new setting that noone will ever find out about.

Bluntly adds Acept-Encoding: brotli gzip support to every http request for every service

I guess you meant 'br' right? https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Encoding

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 8, 2026

Thanks for your research! Given your findings, I'd also be ok with merging this PR as is. If problems come up, it will be very easy to revert.

Wait a bit, I finally got an opportunity to test/profile on real device. I hope api 26 is enough because google isn't certain by itself if I need api 26 or 29.

Should I start working on implementation which adds brotli to youtube only?

Since all browsers since quite some time already support brotli, and they include 'br' in 'Accept-Encoding', we become less fingerprintable if we also support brotli. So I think this is not needed.

I mean that gzip is common br zstd gzip and zstd b gzip too. zstd gzip is also "widely" supported. But br gzip is the less common from all possible...

I we should create some new setting

No. If it actually is a problem on some phones, I wouldn't add brotli at all, rather than add a new setting that noone will ever find out about.

We support old devices (android 5.0) too. Just imagine how additional 20MB of ram would look for 3-4GB device with android 10 vs 20MB of ram for device with android 5.0 and only 1GB of ram. And you know newer androids have better ART compilation strategies which improves performance (if it uses native .so library it isn't very applicable but I didn't check) so android 5.0 devices can suffer while all new feel normal. But I hope I will be able to profile it with device I got access to and give some results

I guess you meant 'br' right? https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Encoding

Yeah

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 8, 2026

Where do you see this? Both of these return content-encoding: gzip in Firefox's inspect window for me.

By doing something like

OkHttpClient client = new OkHttpClient.Builder()
    .addNetworkInterceptor(new SomeDefaultNetworkInterceptor(SHOW_HEADERS))
    .build();

And then looking in the logcat output. It shows what our app actually sends and receives not what is shown in browser. I also just tried to look on it via firefox.

  1. Peertube really compresses with gzip but only site part not api part peertube.instance/api/*. We parse api part. In general it probably should be regulated by instance settings
  2. media.ccc.de doesn't compress at all, firefox showed no compression ¯\_(ツ)_/¯

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 9, 2026

Thanks for your research! Given your findings, I'd also be ok with merging this PR as is. If problems come up, it will be very easy to revert.
Wait a bit, I finally got an opportunity to test/profile on real device. I hope api 26 is enough because google isn't certain by itself if I need api 26 or 29.

I was wrong. The device I got access to can't be used for profiling so everything returns to start position. I can't really do any further testing so it can be merged if you want

@Stypox
Copy link
Copy Markdown
Member

Stypox commented Feb 9, 2026

I mean that gzip is common br zstd gzip and zstd b gzip too. zstd gzip is also "widely" supported. But br gzip is the less common from all possible...

I don't understand. Firefox desktop, Chromium desktop, Firefox mobile all send Accept-Encoding: gzip, deflate, br, zstd for me. So not sending br is actually more fingerprintable.

We support old devices (android 5.0) too

Yeah, that's why I'm saying, if it turns out to be too slow on those devices, let's not add brotli at all. Adding an option for a technical detail nobody knows about would not make sense.

I was wrong. The device I got access to can't be used for profiling so everything returns to start position. I can't really do any further testing so it can be merged if you want

I have a Fairphone 3 which is a pretty slow device. If you share some instructions I can test myself.

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 9, 2026

I don't understand. Firefox desktop, Chromium desktop, Firefox mobile all send Accept-Encoding: gzip, deflate, br, zstd for me. So not sending br is actually more fingerprintable.

You look on it from perspective of separate independent bool toggles? I look on them from perspective of whole coupled string as identifier because even order matters here

Yeah, that's why I'm saying, if it turns out to be too slow on those devices, let's not add brotli at all. Adding an option for a technical detail nobody knows about would not make sense.

There is plan B. Refactor branch which now targets minimum api 23 (android 6). Not big difference but who is going to use refactor on android 6? Taking into account it was unavailable for downloads for a very long time

I have a Fairphone 3 which is a pretty slow device. If you share some instructions I can test myself.

I've never did by myself except castrated experience with waydroid so expect my instruction to be a dead end

Requirements:

  • You probably need google play. I am not quite sure probably it will work without... They say that you need api 26 and then say you need api 29 and then again 26. And I could run very castrated and not functional version of profiling with waydroid which doesn't have google play so there is no other way then check ¯\_(ツ)_/¯
  • Some hardwork for your phone. You need to export backup with lots of subscription 50+ ideally. But the more the best
  • Enthusiasm

Setup:

Steps:

  • Stop other apps as much as possible to reduce noise
  • Run dev build on your device.
  • You probably need only this https://developer.android.com/studio/profile/inspect-app-live or first option from the menu (but on your place I would play with other too)
  • Import the dataset with subscriptions
  • Go to the tab of subscriptions feed update
  • Wait till app gives you something like flatline on cpu/ram usage (not sure if it is possible but I hope you understood what I mean). If you don't disable in settings image loading, I would scroll the feed to preload all the images (after import they aren't in cache)
  • Run subscription update
  • See values on the chart, save values (I don't know how, I was going to just use pen and max/min/average values 🤪)
  • Repeat all above for brotli version
  • Compare...

Offtopic: my xiaomi redmi 8 (which seems to belong to the same performance category) was really slow but after installing lineage os 23 (android 16) it is quite fast. Though when I firstly installed lineage 20/21 it was a downgrade in at least half of use cases but now it is like new.

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 17, 2026

Samsung Galaxy A02S

  • OS: vanilla android 12
  • RAM: 3GB
  • CPU: Qualcomm Snapdragon 450
    • Cores: Cortex A53 x8
    • Cache:
      • L1d: 32KB x8
      • L1i: 32KB x8
      • L2: 512KB + 1MB

Benchmark action: update of 167 subscriptions

Screenshots:

20260217_16h36m50s_grim 20260217_16h37m01s_grim

Don't ask me which one is brotli. I don't remeber... They both show peak usage as 155MB. Both have roughly 60% (of the app) peak CPU usage

RAM decryption color keys:
20260217_16h53m08s_grim

Why I said roughly about CPU usage? There is no exact numbers. Thanks android studio. And that's what I got for profiling: android studio which lags and can't even show exact numbers. And even shows visual lags like on first screenshot in ram section (grey color) :/ Android settings tell that peak usage of the ram of the app is 780MB :/

About the gaps. They happened in both runs at the same numbers of already updated channels. But the PR about shuffling subscriptions is already merged so it is not specific channels. Is it throttling? Maybe but it wouldn't be so synchronous? Idk doesn't look like artificial channel limit update we have ¯\_(ツ)_/¯

Oh and one more thing. For these benches I was for some reason forced for tests increase minSdk from 21 to 29 which could probably allow for some better compile time optimization ¯\_(ツ)_/¯

My conclusion: These benches are crap. Maybe they even show that brotli version doesn't have difference from normal but I don't believe these benches at all and android studio too so you can think these benches don't exist

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 18, 2026

Huawei MediaPad AGS2

  • OS: vanilla android 8
  • RAM: 4GB
  • CPU: HiSiliconKirin 650
    • Cores:
      • Cortex A53 2Gz x4
      • Cortex A53 1.7Gz x4
    • Cache:
      • L1d: 32KB x8
      • L1i: 32KB x8
      • L2: 512KB

Benchmark action: update of 119 subscriptions

Screenshots:

Dev:
20260218_23h24m28s_grim

Brotli:
20260218_23h32m03s_grim

Peak RAM usage is roughly 256MB on both. CPU peaks roughly 50-60% on both without much difference between them

@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 18, 2026

Conclusion:

RAM is generally not affected at all
CPU: well it is hard to say especially because it is in percentage values which would be much higher on low end devices with arm32 and two cores.

But do we need to be so stupid to lock (all) users from this feature? Especially if benches are correct and impact on modern devices is negligible? We can just add check if api >= 26 (or whatever) and enable it for those who certainly won't be impacted?

Yevhen Babiichuk (DustDFG) added 2 commits February 26, 2026 10:40
For us it doesn't really matter amount of cores available for us.
We need only physical cores count as we use it for filtering weak
devices.

_SC_NPROCESSORS_CONF - amount of physical cores (android devices
doesn't have extrnal cpu cores hotplug). **Used**

_SC_NPROCESSORS_ONLN - amount of cores available for OS right now.
Often smaller than _SC_NPROCESSORS_CONF because OS can deactivate cores
for powersave

Runtime.getRuntime().availableProcessors() - a core count available to
jvm. Has the same limitations as _SC_NPROCESSORS_ONLN but also can be
decreased because some cores are allocated to other more priority
processes (?)
@ghost ghost force-pushed the brotli_test branch from a267c03 to facf576 Compare February 26, 2026 09:03
@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 26, 2026

I added check based on how many cores processor have (>2) to filter out very weak devices (I am not sure if they are really gonna struggle with brotli but just want to play safely)

(Only) Checking if arch is arm32 is wrong solution because "Samsung Galaxy A02S" (on which I did one of the benchmarks) is arm32 and it didn't struggle

@ghost
Copy link
Copy Markdown
Author

ghost commented Mar 19, 2026

So...?

@uuytlen
Copy link
Copy Markdown

uuytlen commented Mar 30, 2026

Peak RAM usage is roughly 256MB on both.

Im not really that proficient in android development, but wouldnt peak memory always be equal just because its a threshold when gc runs? Wouldnt it be more accurate to compare memory usage right after gc instead of global maximum?

check based on how many cores processor have (>2)

I had an old lenovo tablet that i think had only one core, but it couldnt even play yt in 360p, so i dont think its reasonable to care about such devices.
Also I tried to benchmark gzip vs brotli decompression on single core in termux (so its native code which isnt exactly representative of java performance). On A55 brotli was consistently faster by around 6%, but on A53 (Snapdragon 660) it was around 20% faster than gzip in decompression!
So it seems to me like itll actually improve performance on old devices.

(The command i used for benchmark: taskset -c 2 hyperfine -r 500 -N 'brotli -dc yt-channel.html.br' 'gzip -dkc yt-channel.html.gz' --warmup 150)

@TobiGr
Copy link
Copy Markdown
Contributor

TobiGr commented Mar 30, 2026

I also don't think that we need to make an exception for devices with low specs. The impact on decompression for brotli should be minimal compared to gzip.

@ale5000-git
Copy link
Copy Markdown

Why not just check the RAM?
Low specs devices (with an old CPU) also have low RAM.

@ale5000-git
Copy link
Copy Markdown

ale5000-git commented Mar 30, 2026

This is what the AI say for my device => The Galaxy S2 features a 1.2 GHz dual-core Exynos 4210 processor. While Brotli decompression is designed to be fast, it is roughly 2x slower than Gzip on similar legacy ARM hardware..

And also: Risk of Lag; Brotli can use up to 16MB of window memory, which is tight for a device with only 1GB of total RAM.

@ghost
Copy link
Copy Markdown
Author

ghost commented Mar 30, 2026

Peak RAM usage is roughly 256MB on both.

Im not really that proficient in android development, but wouldnt peak memory always be equal just because its a threshold when gc runs?

There was only one measure. Memory consumption in overall...

Wouldnt it be more accurate to compare memory usage right after gc instead of global maximum?

Because it was first time I was benchmarking anything with Android studio and it is quite laggy by itself and other methods didn't normally run so it was the only measure I could get...

@ghost
Copy link
Copy Markdown
Author

ghost commented Mar 30, 2026

Why not just check the RAM? Low specs devices (with an old CPU) also have low RAM.

Didn't thought about it. Btw main restrain is cpu imo. Don't know if android or linux have api for finding how many ram is available at all but I think it can be added easily if it is necessary...

@ale5000-git
Copy link
Copy Markdown

ale5000-git commented Mar 30, 2026

AI say this:

ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
long totalMemory = memInfo.totalMem; // Value in bytes

Maybe disable it for devices with total RAM < 3GB (this is just my suggestion).

@ghost
Copy link
Copy Markdown
Author

ghost commented Mar 30, 2026

just finally connect the ai and make the PR

@ghost ghost closed this Mar 30, 2026
@ale5000-git
Copy link
Copy Markdown

I was just saying an opinion, not meant to offend anyone.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Related to performance and optimisation; affects the speed or memory efficiency of the application size/small PRs with less than 50 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants