Issues with large file (media) transfers.
Your use case
This article is a rewrite of #3613 with some new content.
Test environment:
- Self-hosted Synapse instance, version 1.123.0
- Client: Element X Android 0.7.6 (F-Droid)
- Tested with a file of 1.49 GB, which is neither audio nor video.
- Synapse configuration file
homeserver.yamlspecifies a maximum media upload size of 1536 MB. - nginx configuration
client_max_body_sizehas a value of 1536 MB; - Test environment has 1000 Mbps Wi-Fi bandwidth (802.11ax), of course, the speed during upload or download is usually not close to the upper limit, but this is the maximum bandwidth I can provide.
- Device: OnePlus MT2110, Pixel OS (Android 14)
The following issues were found during upload and download tests respectively: Download:
- Due to factors such as file size and download speed, EXA will immediately interrupt¹ some download tasks once they last for 30 seconds (that is, no matter how large the file is, EXA will only allow the download to be completed within 30 seconds). The reason is unclear to users, and I can't figure out why the team would deliberately limit EXA from downloading large files. Here is a note: the forced interruption occurs 30 seconds after receiving the file (media) data from the server, not when requesting it from the server, which means that my reverse proxy configuration is basically fine;
- There is no properly designed progress bar, and I can't know the download progress;
Upload:
- The above file cannot be uploaded, and a white banner will be displayed at the bottom of the screen after about 30 seconds²: "Media upload failed, please try again". Smaller files (such as 500 MB) can be uploaded;
- There is a waiting time before the upload officially starts. I guess it is reading the file into memory or copying a copy to a directory controlled by the app during this period. The specific time depends on the file size;
- There is no properly designed progress bar, and I can't know the upload progress.
Have you considered any alternatives?
I replaced the hard disk for the hardware running Synapse not long ago, which has greatly improved the write performance. However, such files still cannot be transferred smoothly in EXA, So I temporarily chose external services as a substitute.
Additional context
¹ If the file is a video, then I need to wait for it to be fully downloaded before I can start watching it. But because of that strange limitation, EXA cannot meet this requirement; ² I'm not sure if it's the same logic as the limit during downloading;
To further rule out the network problem, I repeated the above test using Element Android (1.6.24); Element Web (1.11.84) and desktop client, and the results were all successful in uploading/downloading.
Are you willing to provide a PR?
No
happens the same for me but for watching a large video (200MB or more)
happens the same for me but for watching a large video (200MB or more)
Unless your large files are outside the Matrix ecosystem, there is currently no satisfactory solution. I have been paying attention to related issues for a long time and found that almost every link from database to Synapse to Element is not friendly to large files.
happens the same for me but for watching a large video (200MB or more)
Unless your large files are outside the Matrix ecosystem, there is currently no satisfactory solution. I have been paying attention to related issues for a long time and found that almost every link from database to Synapse to Element is not friendly to large files.
no way :(
I have same problem on different setup. Upload speed from my Synapse server is slow, about 4-5Mbps. I try investigate problem on server side. I run curl command on the video file and it complete downloading without problem. When ElementX download the video file the request was finished too much quickly.
Here is anonymized log from server:
2025-04-08 10:59:52,170 - synapse.access.https.2020 - 508 - INFO - GET-244053 - 2001:0db8:85a3:0000:0000:8a2e:0370:7334 - 2020 - {@user:domain.tld} Processed request: 2.594sec/-0.000sec (0.048sec, 0.056sec) (0.000sec/0.002sec/1) 48710400B 200 "GET /_matrix/client/v1/media/download/domain.tld/ZcUfPUThdpVHkrYqnFrWduod HTTP/1.1" "Element X/25.03.4 (motorola moto g32; Android 15; lineage_devon-userdebug 15 AP4A.250205.002 1bed208f45; Sdk dcd0e078f)" [0 dbevts]
2025-04-08 11:02:55,100 - synapse.access.https.2020 - 508 - INFO - GET-244076 - 2001:0db8:85a3:0000:0000:8a2e:0370:7334 - 2020 - {@user:domain.tld} Processed request: 102.918sec/-0.000sec (0.086sec, 0.041sec) (0.000sec/0.001sec/1) 48793245B 200 "GET /_matrix/client/v1/media/download/domain.tld/ZcUfPUThdpVHkrYqnFrWduod HTTP/1.1" "curl/8.9.1" [0 dbevts]
Curl output:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 46.5M 100 46.5M 0 0 434k 0 0:01:49 0:01:49 --:--:-- 430k
The difference is in request complete time. Curl download the file after 102.918sec. Element X end request after 2.594sec! No proxy at all.
Element X on UI look same as above. Wait 30s than error. Shorter video from same source works normally. Playable and seekable.
Info: Appstore: F-Droid Version as above in log: Element X/25.03.4 (motorola moto g32; Android 15; lineage_devon-userdebug 15 AP4A.250205.002 1bed208f45; Sdk dcd0e078f) Server: matrix-synapse-py3_1.127.1+bookworm1_amd64
I think it is bug, no enhancement. If enhanced code fix bug okay 😃
it is a critical issue for me too.
i have converted my friends to use elementx from whatsapp but timeout is an issue. in my case my friends are in southeast asia with limited internet speed. even for smaller video files the connection timeout and no video.
This is also an issue with attachments which takes more than 30seconds to download.
Rather than making a timeout maybe worthwhile to prompt for user input if they want to cancel or continue.
I am not sure if this is also relevant 2974
There a plenty things which impact eg nginx, any of those:
proxy_connect_timeout
proxy_send_timeout
proxy_read_timeout
send_timeout
Even https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering is relevant when uploading large files.
The 30s issue for upload mentioned above is weird, because looking at the SDK code that generates the timeout value by estimating it based on the upload size, it should be the maximum value between:
- 'How long would it take to upload this file at 1Mbps'.
- 5 minutes.
So either this isn't applied or it's a server configuration setting this 30s limit. Do you also see this with other clients or does it only happen on Element X?
EDIT: I can confirm the timeout is applied on the client side:
matrix_sdk::media: Provided request config: Some(RequestConfig { timeout: 300s, retry_limit: 3 })
matrix_sdk::media: Uploading file with timeout: Some(300s) | crates/matrix-sdk/src/media.rs:216 |
As for the download one, I think it's just using the 30s default value for http requests in the SDK, which isn't overridden. This should be fairly easy to improve.
The 30s issue for upload mentioned above is weird, because looking at the SDK code that generates the timeout value by estimating it based on the upload size, it should be the maximum value between:
- 'How long would it take to upload this file at 1Mbps'.
- 5 minutes.
So either this isn't applied or it's a server configuration setting this 30s limit. Do you also see this with other clients or does it only happen on Element X?
EDIT: I can confirm the timeout is applied on the client side:
matrix_sdk::media: Provided request config: Some(RequestConfig { timeout: 300s, retry_limit: 3 }) matrix_sdk::media: Uploading file with timeout: Some(300s) | crates/matrix-sdk/src/media.rs:216 |As for the download one, I think it's just using the 30s default value for http requests in the SDK, which isn't overridden. This should be fairly easy to improve.
This only affects Element X (Android / iOS)
The above are the test results at that time. Since it has been a long time, I retested it.
Test preparation:
EXA version: 25.7.1-nightly (202507010, 0fc3c4fe) Device: OnePlus MT2111 (Oxygen OS 15, Android 15)
Upload
Attempt #1 (unlimited speed, "upload media via send queue" enabled by default): Use a file of size 1024 MB, binary data instead of media type. After clicking the green send button (the timer starts at this time), there is no change in the UI, and even the upstream network traffic does not change. After waiting for 5 minutes, the above indicators still did not change, so the timer stopped. Therefore, I regarded it as this upload attempt being blocked by the app.
Try to upload a larger file (such as 1536MB), in addition to the above phenomenon, it will also cause the app to crash.
Attempt #2 (unlimited speed, "upload media via send queue" enabled by default): Use a file of size 557 MB, binary data instead of media type. After clicking the green send button (the timer starts at this time), There was no UI change or network traffic for about 35 seconds; from 36 seconds on, a bubble message about the file appeared in the timeline; from 68 seconds on, the upstream network traffic began to change; at 95 seconds, the upload was complete.
It seems that the upload will no longer have that problem.
- After clicking the green send button, the app immediately returned to the timeline. I could not see any progress bar at this time.
- From the time the app was installed to the time of the test upload, "Upload media via send queue" was always enabled (I only saw it checked in the developer options, and I did not manually change it during testing, including disabling and then enabling it again).
Download
Attempt #1 (unlimited speed): Downloaded a 1024 MB file, binary data instead of media type. Click the "paper clip" button and wait (timer starts at this time). At this time, there was no UI progress bar to clearly show the download progress, just an infinitely looping progress bar at the top of the screen. After 30 seconds, the download was interrupted by the app and the app returned an unknown error.
Attempt #2 (download speed is limited to 4 Mbps): Download a 158 MB file, binary data instead of media type. Click the "paper clip" button and wait (timer starts). At this time, the UI does not have a progress bar that clearly shows the progress of the download, just an infinitely looping progress bar at the top of the screen. After 30 seconds, the download is interrupted by the app and the app returns an unknown error.
This problem still exists during the download.
Tested on my end too. Upload has no problem now, only when the file is to big (>2GB), the app crash for some reason, and on download, it says an unknown error occurred after 30 seconds, the same when trying to play a video after 30 seconds.
SDK PR to handle the cancelled downloads scenario: https://github.com/matrix-org/matrix-rust-sdk/pull/5437