Marta Kowalczyk Platform
Staging is on 2.4.0-rc3. Uploads over about 40 MB fail at 100% — the progress bar completes, then the document never appears in the folder.
2 2 people reacted: looking into it
Chat, threads, video calls, shared documents and an AI assistant — one application your team signs into with your own identity provider, running on hardware you control. No seats to buy, no tenant somewhere else.
2.6 MB · one file, no installer. Other platforms
Everything below is one continuous conversation: the report, the fix found in a thread, the assistant auditing the codebase with its own tools, the call that settled it, and the release note it produced.
# release-2-4
Cutting 2.4.0 — staging sign-off before Thursday
Marta Kowalczyk Platform
Staging is on 2.4.0-rc3. Uploads over about 40 MB fail at 100% — the progress bar completes, then the document never appears in the folder.
2 2 people reacted: looking into it
Kenji Tanaka QA
Same here. Nothing in the backend log at all, which is the odd part.
Layla Haddad Support
Power BI — التقارير الكبيرة تفشل منذ أمس.
Translation: Power BI — large reports have been failing since yesterday.
Daniel Okoro Backend
Found it. client_max_body_size is still 32m on the staging proxy. nginx truncates the POST, DRF sees a short body and returns 400 before our view ever runs — so the failure is in the proxy log, not ours. Production is 512m.
Sofia Ferrara
Reproduced with a 47 MB PDF. Same 400, same silence in the app log.
Daniel Okoro
Patching staging now. It only ever affected staging.
Marta Kowalczyk
Let's pin the value in the deploy compose as well, so the two environments can't drift apart again.
Marta Kowalczyk Platform
@assistant where else is an upload limit configured?
Assistant AI
Three places set an upload ceiling. deploy/nginx.conf caps the request body — 32m in the staging block, 512m in production, which is the difference you hit. DATA_UPLOAD_MAX_MEMORY_SIZE in backend/settings.py only decides when Django spools to a temp file, so it will not reject a large upload. The SDK also refuses anything over 500 MB client-side before it starts. Only the nginx value differs between environments.
deploy/nginx.conf
Release 2.4 — upload limits
Started by Daniel · 6 min · Screen share · staging nginx config
Marta Kowalczyk Platform
Agreed on the call: one limit, one place, pinned in the deploy compose. Written up in the release note below.
Seen by all 9 members
is typing…
Playing 0 of 0
Documents, pages and announcements are first-class objects in the same hub, not links to a different product. This is the release note that came out of the thread above, as a reader sees it.
A 32 MB request-body cap left on the staging proxy was silently truncating large uploads. The value is now pinned in the deploy compose file, identical across environments.
nginx cut the request body at 32 MB on staging. The browser finished sending, so the progress bar reached 100%, but Django received a short body and rejected it with a 400 before the upload view ran. Nothing reached the application log, which is why the failure looked like it came from nowhere.
The limit moved out of the per-host nginx config and into the deploy compose file, where both environments read the same value. Staging and production are now both 512m. The two other ceilings — Django spooling to disk, and the 500 MB client-side guard in the SDK — were already environment-independent and are unchanged.
Nothing, if you use the hosted upgrade path. If you run your own compose file, copy the CONTENTHUB_MAX_UPLOAD entry from the sample and rebuild the proxy container.
Calls run through a mediasoup SFU and a coturn TURN server that you deploy alongside everything else. Media is relayed by your own containers, so a call between two people in your office does not transit anyone else's cloud.
Teams do not all write in one script, and the awkward case is not a whole message in another language — it is a sentence that mixes them. Both panels below hold the identical string. Only the direction rule differs.
dir="auto" — the browser default
Power BI — التقارير الكبيرة تفشل منذ أمس.
Resolves from the first strong character — the P of “Power” — and lays the whole sentence out left-to-right. The Arabic clause ends up on the wrong side of the product name, and the full stop on the wrong end of the sentence.
Majority script — what ContentHub does
Power BI — التقارير الكبيرة تفشل منذ أمس.
Counts strong characters — 25 right-to-left against 7 left-to-right — and lays the line out the way it was written, reading from the right, with the Latin product name correctly embedded inside it.
Direction is decided per block, not per message, so a single reply can hold an English paragraph, an Arabic one and a table without any of them fighting each other.
To be clear about what this is not: the interface itself is English. This is about the text your team writes, which is where mixed scripts actually show up.
One application, one database, one login. Nothing below is a paid add-on or a third-party service you have to sign up for separately.
A Meilisearch index over every message you have access to — typo-tolerant, ranked, and scoped to your own channels and conversations.
Web push in the browser and email digests for what you missed, both handled by a background worker. The desktop client draws its own notification cards and honours Windows Focus Assist.
Folders and documents with revision history, editable pages, announcements, and structured lists you can build from a template — all in the same hub as the conversation about them.
It calls tools mid-answer — searching messages, reading a document, fetching a page through your own self-hosted metasearch — and shows each step. Attachments are read too: PDF, Word and text for any model, images for the ones that can see.
Sign-in over OpenID Connect, so accounts and group membership stay in the directory you already run. Token auth is there for anything scripted.
Typing indicators, online and away presence, and per-message read receipts arrive over the same WebSocket as the messages, backed by Redis.
Every part of ContentHub runs on your own hardware — including the parts most self-hosted chat tools hand off to a third party, like call routing and search.
Your infrastructure
Clients
Desktop client
Browser
Edge
Reverse proxy
Application
Django + Channels
Background worker
State & search
PostgreSQL
Redis
Meilisearch
Media
mediasoup SFU
coturn
Signs in against your OpenID Connect provider — accounts never leave your directory.
Search, presence, push notifications, call signalling and media relay are all services you deploy. Nothing phones home, and there is no vendor who can read your messages — because there is no vendor.
A real application rather than a browser tab, and a small one: it renders through the WebView2 runtime Windows already ships with instead of carrying its own copy of Chromium, so the whole download is 2.6 MB. It runs as a single instance, keeps a tray icon, and needs no installer.
Windows
Windows 10 & 11 · 64-bit
One 2.6 MB .exe — no installer, no admin rights. Uses the WebView2 runtime already on Windows 10 and 11.
DownloadmacOS
Apple silicon & Intel
Already builds in CI. Unsigned and un-notarised, so not published yet.
Linux
AppImage · x86-64
Already builds in CI, awaiting a tagged release.
Android
Phone & tablet
Planned. Web push and the responsive layout already work in a mobile browser.
iOS
iPhone & iPad
Planned. Installs as a home-screen web app in the meantime.