Skip to content

v2026.09.21

Latest

Choose a tag to compare

@github-actions github-actions released this 21 Sep 00:50
9dc6c14

Security

  • The web server no longer serves files outside the frontend build directory. All earlier versions are affected; update to this release.

Highlights

  • Demand-aware allocation between download clients: a client that isn't using its share lends the unused part to clients that are, download and upload. On by default; toggle in Settings > Bandwidth. (#85)
  • Inactive clients are promoted once they reach 80% of their safety-net cap; in two-client setups they previously had to exceed it. (#85)
  • Dashboard panels can be reordered from a per-panel menu and minimised into one-line summaries; the layout is saved per browser. The stream-count graph is now its own panel. (#86)
  • Throttling can be switched off from the dashboard, optionally for a set duration, and the control lives in General settings; the state persists across restarts and clients are set to unlimited while it is off. (#78)
  • Threshold notifications have a configurable cooldown in Notification settings. (#72)
  • Bandwidth settings and the wizard carry the "set 10-20% below your real line speed" advice and per-client speed-unit notes. (#83, #84)

Fixes

  • Client speed limits are converted with each client's real byte unit. qBittorrent, NZBGet, Deluge and SABnzbd limits become 2-5% tighter than before (they were over-allocated); Transmission is unchanged.
  • SQLite now really runs in WAL journal mode with foreign-key enforcement on (both were configured but silently skipped on every release so far). Existing databases convert on the first start; speedarr.db-wal and speedarr.db-shm appear beside speedarr.db and belong in any backup taken while the container is running. The startup log reports the effective mode. (#88)
  • The setup wizard no longer returns 500 for Emby/Jellyfin servers while in setup mode. (#32, still experimental)
  • A malformed throttling-state timestamp now fails open instead of leaving throttling stuck. (#78)
  • Log noise: the per-poll "Multiple active" line is DEBUG, standby and single-active lines carry a direction prefix, and demand-aware state changes log as SATURATED/SLACK. (#85)

Dependencies

  • Backend runtime: Python 3.14.7 (slim-bookworm), up from 3.11.7. Every dependency installs from a prebuilt wheel on amd64 and arm64, and the image no longer carries gcc, so it is about 40% smaller.
  • Backend: FastAPI 0.141, starlette 1.6 (pinned directly; clears seven starlette advisories carried by the previous transitive 0.35.1), pydantic 2.13, SQLAlchemy 2.0.52, uvicorn 0.52, aiohttp 3.14.3, pyasn1 0.6.4. apscheduler removed from the image (it was never used).
  • Backend auth: passlib and python-jose replaced by bcrypt 5.0.0 and PyJWT 2.14.0; cryptography 50.0.1 pinned directly. Passwords longer than 72 bytes are rejected when set (accented letters, symbols and emoji count as 2 to 4 bytes each); existing passwords are unaffected.
  • Frontend build: Node 24.21 LTS on Alpine 3.24 (was Node 20.11), Vite 8.2 on rolldown, TypeScript 6.0, ESLint 10 with typescript-eslint 8 and a flat config, jsdom 30 and jest-dom 7 for the unit tests. No runtime dependency changed; the served bundle is about 3% smaller.
  • Frontend: React Router 7, vitest 4.1.11, plus the Dependabot frontend group and the transitive security bumps (postcss, brace-expansion, minimatch, browserslist, js-yaml, baseline-browser-mapping).
  • CI: checkout, login, metadata, qemu and gh-release actions bumped.

Notes for API users

  • API clients using an API key must send Content-Type: application/json with JSON request bodies (POST /api/control/manual-throttle, /api/control/restore-speeds, /api/control/pause-monitoring, /api/bandwidth/temporary-limits); requests without the header are rejected with 422. The examples on the API keys settings page already include it.

What's Changed

Full Changelog: v2026.07.07...v2026.09.21