Skip to content

Conversation

@Marc-Roig
Copy link
Contributor

@Marc-Roig Marc-Roig commented Jun 12, 2023

What does it do?

Proposes a more composable way to define file transformations, that allows:

  • Using other libraries rather than sharp for image transformations (gm, jimp, ...)
    • This is a TODO and I have a working setup using jimp.
  • Better handling of libvips and sharp memory configurations
  • Remove transformations and let providers such as cloudinary handle them.

This is still a draft and a work in progress.

I also used this opportunity to clean a bit the upload plugin, specially the main upload service https://github.com/strapi/strapi/pull/16978/files#diff-3c0f1c68e7bcad4702d7bd9600b9ca459715158a9451da2ae05454d163cada16 .

Why is it needed?

Sharp is a fast and reliable tool to transform images that we rely upon in Strapi. Unfortunately, in some Linux machines, there seems to be some sort of memory fragmentation that causes RAM spikes and memory fragmentation.

lovell/sharp#3052
lovell/sharp#1710
lovell/sharp#955

Because of the nature of this issue we decided to move this forward in an extensible way, where anyone can create it's own custom solution that works for each setup.

We are going to continue exploring this and see what tools we can provide to better handle issues like this one.

How to test it?

Provide information about the environment and the path to verify the behaviour.

Related issue(s)/PR(s)

Fixes #14417

@Marc-Roig Marc-Roig changed the title feat: add transformations fix: Sharp memory fragmentation Jun 12, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Jun 12, 2023

Size Change: -6 B (0%)

Total Size: 1.52 MB

ℹ️ View Unchanged
Filename Size Change
packages/core/admin/build/Admin_homePage.********.chunk.js 8.48 kB 0 B
packages/core/admin/build/Admin_InternalErrorPage.********.chunk.js 496 B 0 B
packages/core/admin/build/Admin_marketplace.********.chunk.js 8.32 kB -8 B (0%)
packages/core/admin/build/Admin_pluginsPage.********.chunk.js 1.17 kB 0 B
packages/core/admin/build/Admin_profilePage.********.chunk.js 3.43 kB 0 B
packages/core/admin/build/Admin_settingsPage.********.chunk.js 9.25 kB 0 B
packages/core/admin/build/admin-app.********.chunk.js 22.8 kB 0 B
packages/core/admin/build/Admin-authenticatedApp.********.chunk.js 8.26 kB 0 B
packages/core/admin/build/admin-edit-roles-page.********.chunk.js 15.9 kB 0 B
packages/core/admin/build/admin-edit-users.********.chunk.js 4.09 kB 0 B
packages/core/admin/build/admin-roles-list.********.chunk.js 3.04 kB 0 B
packages/core/admin/build/admin-users.********.chunk.js 6.44 kB 0 B
packages/core/admin/build/api-tokens-create-page.********.chunk.js 232 B 0 B
packages/core/admin/build/api-tokens-edit-page.********.chunk.js 232 B 0 B
packages/core/admin/build/api-tokens-list-page.********.chunk.js 2.78 kB 0 B
packages/core/admin/build/ar-json.********.chunk.js 19.6 kB 0 B
packages/core/admin/build/audit-logs-settings-page.********.chunk.js 4.36 kB 0 B
packages/core/admin/build/bb3108f7fd1e6179bde1.svg 352 B 0 B
packages/core/admin/build/bb4d0d527bdfb161bc5a.svg 2.33 kB 0 B
packages/core/admin/build/ca-json.********.chunk.js 12.9 kB 0 B
packages/core/admin/build/content-manager.********.chunk.js 62.8 kB 0 B
packages/core/admin/build/content-type-builder-list-view.********.chunk.js 7.14 kB 0 B
packages/core/admin/build/content-type-builder-translation-ar-json.********.chunk.js 1.35 kB 0 B
packages/core/admin/build/content-type-builder-translation-cs-json.********.chunk.js 2.88 kB 0 B
packages/core/admin/build/content-type-builder-translation-de-json.********.chunk.js 4.19 kB 0 B
packages/core/admin/build/content-type-builder-translation-dk-json.********.chunk.js 3.75 kB 0 B
packages/core/admin/build/content-type-builder-translation-en-json.********.chunk.js 4.2 kB 0 B
packages/core/admin/build/content-type-builder-translation-es-json.********.chunk.js 3.97 kB 0 B
packages/core/admin/build/content-type-builder-translation-fr-json.********.chunk.js 1.66 kB 0 B
packages/core/admin/build/content-type-builder-translation-id-json.********.chunk.js 3.34 kB 0 B
packages/core/admin/build/content-type-builder-translation-it-json.********.chunk.js 3.47 kB 0 B
packages/core/admin/build/content-type-builder-translation-ja-json.********.chunk.js 1.23 kB 0 B
packages/core/admin/build/content-type-builder-translation-ko-json.********.chunk.js 4.37 kB 0 B
packages/core/admin/build/content-type-builder-translation-ms-json.********.chunk.js 3.28 kB 0 B
packages/core/admin/build/content-type-builder-translation-nl-json.********.chunk.js 3.3 kB 0 B
packages/core/admin/build/content-type-builder-translation-pl-json.********.chunk.js 4.16 kB 0 B
packages/core/admin/build/content-type-builder-translation-pt-BR-json.********.chunk.js 4.17 kB 0 B
packages/core/admin/build/content-type-builder-translation-pt-json.********.chunk.js 1.1 kB 0 B
packages/core/admin/build/content-type-builder-translation-ru-json.********.chunk.js 4.69 kB 0 B
packages/core/admin/build/content-type-builder-translation-sk-json.********.chunk.js 3.74 kB 0 B
packages/core/admin/build/content-type-builder-translation-sv-json.********.chunk.js 4.18 kB 0 B
packages/core/admin/build/content-type-builder-translation-th-json.********.chunk.js 4.36 kB 0 B
packages/core/admin/build/content-type-builder-translation-tr-json.********.chunk.js 3.84 kB 0 B
packages/core/admin/build/content-type-builder-translation-uk-json.********.chunk.js 4.37 kB 0 B
packages/core/admin/build/content-type-builder-translation-zh-Hans-json.********.chunk.js 3.5 kB 0 B
packages/core/admin/build/content-type-builder-translation-zh-json.********.chunk.js 4.5 kB 0 B
packages/core/admin/build/content-type-builder.********.chunk.js 27.2 kB 0 B
packages/core/admin/build/cs-json.********.chunk.js 5.88 kB 0 B
packages/core/admin/build/de-json.********.chunk.js 12.8 kB 0 B
packages/core/admin/build/dk-json.********.chunk.js 10.5 kB 0 B
packages/core/admin/build/email-settings-page.********.chunk.js 3.6 kB 0 B
packages/core/admin/build/email-translation-ar-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-cs-json.********.chunk.js 121 B 0 B
packages/core/admin/build/email-translation-de-json.********.chunk.js 120 B 0 B
packages/core/admin/build/email-translation-dk-json.********.chunk.js 616 B 0 B
packages/core/admin/build/email-translation-en-json.********.chunk.js 610 B 0 B
packages/core/admin/build/email-translation-es-json.********.chunk.js 675 B 0 B
packages/core/admin/build/email-translation-fr-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-id-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-it-json.********.chunk.js 118 B 0 B
packages/core/admin/build/email-translation-ja-json.********.chunk.js 787 B 0 B
packages/core/admin/build/email-translation-ko-json.********.chunk.js 758 B 0 B
packages/core/admin/build/email-translation-ms-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-nl-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-pl-json.********.chunk.js 660 B 0 B
packages/core/admin/build/email-translation-pt-BR-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-pt-json.********.chunk.js 668 B 0 B
packages/core/admin/build/email-translation-ru-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-sk-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-th-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-tr-json.********.chunk.js 687 B 0 B
packages/core/admin/build/email-translation-uk-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-vi-json.********.chunk.js 122 B 0 B
packages/core/admin/build/email-translation-zh-Hans-json.********.chunk.js 473 B 0 B
packages/core/admin/build/email-translation-zh-json.********.chunk.js 730 B 0 B
packages/core/admin/build/en-json.********.chunk.js 15.1 kB 0 B
packages/core/admin/build/es-json.********.chunk.js 14 kB 0 B
packages/core/admin/build/eu-json.********.chunk.js 14.1 kB 0 B
packages/core/admin/build/fr-json.********.chunk.js 12.6 kB 0 B
packages/core/admin/build/gu-json.********.chunk.js 14.2 kB 0 B
packages/core/admin/build/he-json.********.chunk.js 6.48 kB 0 B
packages/core/admin/build/hi-json.********.chunk.js 16.3 kB 0 B
packages/core/admin/build/highlight.js.********.chunk.js 842 B 0 B
packages/core/admin/build/hu-json.********.chunk.js 15.4 kB 0 B
packages/core/admin/build/i18n-settings-page.********.chunk.js 4.93 kB 0 B
packages/core/admin/build/i18n-translation-de-json.********.chunk.js 1.62 kB 0 B
packages/core/admin/build/i18n-translation-dk-json.********.chunk.js 1.62 kB 0 B
packages/core/admin/build/i18n-translation-en-json.********.chunk.js 1.57 kB 0 B
packages/core/admin/build/i18n-translation-es-json.********.chunk.js 1.68 kB 0 B
packages/core/admin/build/i18n-translation-fr-json.********.chunk.js 1.73 kB 0 B
packages/core/admin/build/i18n-translation-ko-json.********.chunk.js 1.86 kB 0 B
packages/core/admin/build/i18n-translation-pl-json.********.chunk.js 1.8 kB 0 B
packages/core/admin/build/i18n-translation-ru-json.********.chunk.js 2.3 kB 0 B
packages/core/admin/build/i18n-translation-tr-json.********.chunk.js 1.7 kB 0 B
packages/core/admin/build/i18n-translation-zh-Hans-json.********.chunk.js 1.64 kB 0 B
packages/core/admin/build/i18n-translation-zh-json.********.chunk.js 1.73 kB 0 B
packages/core/admin/build/id-json.********.chunk.js 7.46 kB 0 B
packages/core/admin/build/index.html 263 B 0 B
packages/core/admin/build/it-json.********.chunk.js 7.93 kB 0 B
packages/core/admin/build/ja-json.********.chunk.js 12.2 kB 0 B
packages/core/admin/build/ko-json.********.chunk.js 11.5 kB 0 B
packages/core/admin/build/main.********.js 587 kB 0 B
packages/core/admin/build/ml-json.********.chunk.js 17.2 kB 0 B
packages/core/admin/build/ms-json.********.chunk.js 6.16 kB 0 B
packages/core/admin/build/nl-json.********.chunk.js 14.3 kB 0 B
packages/core/admin/build/no-json.********.chunk.js 5.48 kB 0 B
packages/core/admin/build/pl-json.********.chunk.js 13.1 kB 0 B
packages/core/admin/build/pt-BR-json.********.chunk.js 13.8 kB 0 B
packages/core/admin/build/pt-json.********.chunk.js 5.71 kB 0 B
packages/core/admin/build/review-workflows-settings.********.chunk.js 4.5 kB 0 B
packages/core/admin/build/ru-json.********.chunk.js 21.6 kB 0 B
packages/core/admin/build/runtime~main.********.js 4.78 kB +2 B (0%)
packages/core/admin/build/sa-json.********.chunk.js 16.9 kB 0 B
packages/core/admin/build/sk-json.********.chunk.js 11.8 kB 0 B
packages/core/admin/build/sso-settings-page.********.chunk.js 1.71 kB 0 B
packages/core/admin/build/sv-json.********.chunk.js 14.1 kB 0 B
packages/core/admin/build/th-json.********.chunk.js 9.01 kB 0 B
packages/core/admin/build/tr-json.********.chunk.js 13.7 kB 0 B
packages/core/admin/build/transfer-tokens-create-page.********.chunk.js 237 B 0 B
packages/core/admin/build/transfer-tokens-edit-page.********.chunk.js 236 B 0 B
packages/core/admin/build/transfer-tokens-list-page.********.chunk.js 2.89 kB 0 B
packages/core/admin/build/uk-json.********.chunk.js 7.71 kB 0 B
packages/core/admin/build/Upload_ConfigureTheView.********.chunk.js 1.74 kB 0 B
packages/core/admin/build/upload-settings.********.chunk.js 3.08 kB 0 B
packages/core/admin/build/upload-translation-ca-json.********.chunk.js 2.48 kB 0 B
packages/core/admin/build/upload-translation-de-json.********.chunk.js 2.19 kB 0 B
packages/core/admin/build/upload-translation-dk-json.********.chunk.js 1.96 kB 0 B
packages/core/admin/build/upload-translation-en-json.********.chunk.js 2.58 kB 0 B
packages/core/admin/build/upload-translation-es-json.********.chunk.js 2.45 kB 0 B
packages/core/admin/build/upload-translation-fr-json.********.chunk.js 2.86 kB 0 B
packages/core/admin/build/upload-translation-he-json.********.chunk.js 1.84 kB 0 B
packages/core/admin/build/upload-translation-it-json.********.chunk.js 1.56 kB 0 B
packages/core/admin/build/upload-translation-ja-json.********.chunk.js 1.92 kB 0 B
packages/core/admin/build/upload-translation-ko-json.********.chunk.js 2.5 kB 0 B
packages/core/admin/build/upload-translation-ms-json.********.chunk.js 1.41 kB 0 B
packages/core/admin/build/upload-translation-pl-json.********.chunk.js 2.19 kB 0 B
packages/core/admin/build/upload-translation-pt-BR-json.********.chunk.js 1.61 kB 0 B
packages/core/admin/build/upload-translation-pt-json.********.chunk.js 1.61 kB 0 B
packages/core/admin/build/upload-translation-ru-json.********.chunk.js 2.02 kB 0 B
packages/core/admin/build/upload-translation-sk-json.********.chunk.js 2.58 kB 0 B
packages/core/admin/build/upload-translation-th-json.********.chunk.js 1.99 kB 0 B
packages/core/admin/build/upload-translation-tr-json.********.chunk.js 2.35 kB 0 B
packages/core/admin/build/upload-translation-uk-json.********.chunk.js 1.96 kB 0 B
packages/core/admin/build/upload-translation-zh-Hans-json.********.chunk.js 3.12 kB 0 B
packages/core/admin/build/upload-translation-zh-json.********.chunk.js 2.65 kB 0 B
packages/core/admin/build/upload.********.chunk.js 7.63 kB 0 B
packages/core/admin/build/users-advanced-settings-page.********.chunk.js 3.42 kB 0 B
packages/core/admin/build/users-email-settings-page.********.chunk.js 3.78 kB 0 B
packages/core/admin/build/users-permissions-translation-ar-json.********.chunk.js 1.51 kB 0 B
packages/core/admin/build/users-permissions-translation-cs-json.********.chunk.js 1.46 kB 0 B
packages/core/admin/build/users-permissions-translation-de-json.********.chunk.js 1.58 kB 0 B
packages/core/admin/build/users-permissions-translation-dk-json.********.chunk.js 1.92 kB 0 B
packages/core/admin/build/users-permissions-translation-en-json.********.chunk.js 1.81 kB 0 B
packages/core/admin/build/users-permissions-translation-es-json.********.chunk.js 2.05 kB 0 B
packages/core/admin/build/users-permissions-translation-fr-json.********.chunk.js 1.41 kB 0 B
packages/core/admin/build/users-permissions-translation-id-json.********.chunk.js 1.49 kB 0 B
packages/core/admin/build/users-permissions-translation-it-json.********.chunk.js 1.57 kB 0 B
packages/core/admin/build/users-permissions-translation-ja-json.********.chunk.js 1.53 kB 0 B
packages/core/admin/build/users-permissions-translation-ko-json.********.chunk.js 2.23 kB 0 B
packages/core/admin/build/users-permissions-translation-ms-json.********.chunk.js 1.27 kB 0 B
packages/core/admin/build/users-permissions-translation-nl-json.********.chunk.js 1.32 kB 0 B
packages/core/admin/build/users-permissions-translation-pl-json.********.chunk.js 2.11 kB 0 B
packages/core/admin/build/users-permissions-translation-pt-BR-json.********.chunk.js 1.21 kB 0 B
packages/core/admin/build/users-permissions-translation-pt-json.********.chunk.js 1.3 kB 0 B
packages/core/admin/build/users-permissions-translation-ru-json.********.chunk.js 2.75 kB 0 B
packages/core/admin/build/users-permissions-translation-sk-json.********.chunk.js 1.38 kB 0 B
packages/core/admin/build/users-permissions-translation-sv-json.********.chunk.js 2.01 kB 0 B
packages/core/admin/build/users-permissions-translation-th-json.********.chunk.js 2.01 kB 0 B
packages/core/admin/build/users-permissions-translation-tr-json.********.chunk.js 2.07 kB 0 B
packages/core/admin/build/users-permissions-translation-uk-json.********.chunk.js 1.75 kB 0 B
packages/core/admin/build/users-permissions-translation-vi-json.********.chunk.js 1.51 kB 0 B
packages/core/admin/build/users-permissions-translation-zh-Hans-json.********.chunk.js 2.19 kB 0 B
packages/core/admin/build/users-permissions-translation-zh-json.********.chunk.js 2.1 kB 0 B
packages/core/admin/build/users-providers-settings-page.********.chunk.js 5.73 kB 0 B
packages/core/admin/build/users-roles-settings-page.********.chunk.js 7.37 kB 0 B
packages/core/admin/build/vi-json.********.chunk.js 5.98 kB 0 B
packages/core/admin/build/webhook-edit-page.********.chunk.js 5.49 kB 0 B
packages/core/admin/build/webhook-list-page.********.chunk.js 3.11 kB 0 B
packages/core/admin/build/zh-Hans-json.********.chunk.js 17.2 kB 0 B
packages/core/admin/build/zh-json.********.chunk.js 15.1 kB 0 B
packages/core/helper-plugin/build/helper-plugin.esm.js 24.3 kB 0 B
packages/core/helper-plugin/build/helper-plugin.js 22.2 kB 0 B

compressed-size-action

@strapi-bot
Copy link

This pull request has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/upload-memory-leak-issue/20104/9

@Marc-Roig Marc-Roig self-assigned this Jul 3, 2023
@Antoine-lb
Copy link
Contributor

Hello, I'm not sure if this is the right place, but I wanted to add my two cents to "things to consider".

Adding the option to store a "Breakpoint" as a string in the database:

Dynamic Breakpoints:

  • Not all images need the same breakpoints (e.g. cover image vs favicon). Maybe at upload time, some config could be overwritten.

File Conversion on the Server:

Thanks for working on this issue 🙏. It's a massive pain point for us as we are running Sharp locally and then uploading the thumbnail and cover image for each product (over 1500 products so far).

@lovell
Copy link

lovell commented Jul 28, 2023

Hi, I'm the sharp maintainer and have been made aware of some of the discussions around Strapi and memory fragmentation. The number of "memory leak" complaints from Strapi users seems to be rather disproportionate, so I've had a quick look at the Strapi source code to see if there are possible improvements in the way sharp is being used.

Given input images appear to already exist on the filesystem, I highly recommend Strapi passes the (absolute) filesystem path to sharp; do not use Streams. This will allow libvips to mmap input and use its operation cache, resulting in significantly fewer memory allocations and therefore reducing the effects of fragmentation.

I notice from this PR that you're refactoring much of this code right now, but after this is complete I'd be happy to offer a review or attempt a PR to help address the underlying issues.

@Marc-Roig
Copy link
Contributor Author

wow! thank you for coming by and reviewing our work!!
Absolutely, we plan to continue with this work and it already improves the memory issues we had. On uploads, we were applying different resizes and optimizations to images, and in each transformation we stored the result in the filesystem again, to then create another stream, ....

This PR pipes all the transformations into a single stream, and greatly reduces the issue.

Your proposal makes total sense, to not use streams for images. I think that could be something we can do for images with relatively small weight, and would reduce the number of mem allocations. That is totally doable.

And on a side topic, do you know the status of sharp being compiled to webassembly? That could help some installation issues for some users 🚀

Again, thank you for your time and we will keep you updated <3

@longd3
Copy link

longd3 commented Aug 24, 2023

Really can't wait for this to be merged!!

@Marc-Roig
Copy link
Contributor Author

@longd3 trying to get around it, but at the moment this introduces breaking changes, if we can not sort them out this will target the next major release v5.
Will do our best <3

@SvenWesterlaken
Copy link

Any updates on this? @Marc-Roig

@Marc-Roig
Copy link
Contributor Author

Marc-Roig commented Mar 19, 2024

@SvenWesterlaken sorry for the delayed response :) we are atm focused on the stabilizing the new V5 major, after that we do plan on retaking this work, it might take a bit more time than expected.

"react-query": "3.39.3",
"react-redux": "8.0.5",
"react-select": "5.7.0",
"sharp": "0.32.0",
Copy link
Contributor

@markkaylor markkaylor Mar 21, 2024

Choose a reason for hiding this comment

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

Do you think we could bump sharp to 0.33.2? I'm thinking of this PR #19311 and the attached issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes! lets do that

@Marc-Roig
Copy link
Contributor Author

closing it in favor of #20080 :)

@Marc-Roig Marc-Roig closed this Apr 10, 2024
@Marc-Roig Marc-Roig deleted the poc/media-builder branch April 25, 2024 09:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sharp - Media Upload Memory Leak

8 participants