Slow/throttled PHP script upload speeds

SYSTEM INFORMATION
Debian 13.5 Trixie Fresh net-ins with Virtualmin LAMP stack.
Virtualmin version Web: 2.641 Virt: 8.1.0 GPL

If I create a LAMP stack manually the PHP media scripts I am using work fine out of the box, even with stock apache and PHP configs (maybe adjusting max_file_size or something is needed for files over 8mb for example)

On a fresh install of Debian 13.5 and Virtualmin’s full LAMP stack, PHP upload speeds seem to take 70 seconds for a 14mb MP3 track. I have been ripping my hair out to find the culprit, even shoving the issue into GPT to see if it could help diagnose, which after about 10 re-installs and destroying php.ini’s, fpm configs, settings etc etc along the way. I have changed all the usual suspects like post times, file upload sizes etc, and they are loading fine when phpinfo is read, but still, doesn’t matter what the script is, something seems to be throttling the upload speeds.

I have never used Virtualmin/Webmin so im sure this is probably an easy fix or someone out there who has had a similar issue and can share with me what tickbox or php/fpm config I need to be editing. It is worth mentioning that this is on a Sub-Server, so the configs are independent from my understanding? SFTP speeds are fine it will upload in 7-8 seconds, so it seems to be a PHP/FPM/PROXY configuration issue or a deliberate limitation somewhere in the web panel…

Thanks in advance.

(This is what GPT said:)

:police_car_light: Where the bottleneck actually is (now very clear)

At this point, all earlier suspects are eliminated:

  • :cross_mark: disk (/tmp is tmpfs, fast)
  • :cross_mark: ffmpeg
  • :cross_mark: BeMusic logic
  • :cross_mark: PHP limits
  • :cross_mark: reqtimeout
  • :cross_mark: Apache MPM

So the remaining real bottleneck is:

:collision: Apache → PHP-FPM upload streaming path (proxy_fcgi + buffering behavior)

But not in a “broken config” way — in a default conservative throughput mode.

:brain: Why Virtualmin makes this worse

Virtualmin + Apache + PHP-FPM typically introduces:

1. Buffered POST body handling

Apache does not stream directly into PHP-FPM sockets efficiently for large uploads.
Instead:

  • chunk buffering
  • temp file staging
  • serialized transfer to PHP-FPM

This produces exactly:

~150–250 KB/s effective upload ceiling

So I managed to fix the upload speed by disabling “HTTP/2” completely as per ChatGPT’s recommendation.

If someone could explain to me how this fixes it and if it is even a safe work around, that would be great. Gonna do a bit more research now and another fresh reinstall of Debian+Virtualmin.

It would be great to be able to fix this in the web panel as to have the least manual file modifications possible from stock install…

ChatGPT output:

  1. HTTP/2 is enabled (good, your server speaks it).

  2. The site redirects to www. (fine, just note that for testing uploads).

  3. Apache is handling HTTP/2, which is the most likely culprit for slow large POST uploads.


Why HTTP/2 can slow large POSTs

  • HTTP/2 multiplexes streams, which is usually great for many small requests.

  • But some Apache versions + PHP-FPM + large POST bodies serialize the body per stream in a way that caps upload throughput to around 150–200 KB/s — exactly what you’re seeing.

  • FTP bypasses HTTP/2 entirely → 8 seconds for 14 MB.

  • Minimal PHP scripts don’t help because the bottleneck is in Apache HTTP/2 input handling, not PHP.


How to confirm

  1. Disable HTTP/2 for your site:
sudo a2dismod http2
sudo systemctl restart apache2
  1. Test the same 14 MB upload in Firefox.
  • If it drops from 1:28 → ~8–10 seconds, the culprit was HTTP/2.

  • If it’s still slow, the issue is elsewhere.


Why you might see this on Virtualmin / Debian 13.5

  • Debian ships mod_http2 in Apache 2.4.x.

  • By default, it’s enabled.

  • On servers serving large POSTs, this module can unintentionally throttle upload speed.

    Bingo! :bullseye:

That confirms it: HTTP/2 was the bottleneck. Your upload went from 1:28 → 4.26 seconds, almost FTP speed — perfect.

So the full picture:

  • PHP limits were fine (upload_max_filesize, post_max_size, memory_limit)

  • PHP-FPM + Apache setup was fine

  • mod_reqtimeout was disabled

  • The culprit: Apache + HTTP/2 throttling large POST bodies


GPT is hallucinating. Virtualmin is not in the request path, so it cannot possibly effect POST body handling in any way. You can stop Webmin/Virtualmin completely and web requests will complete as usual.