Thnkrr — Video in Posts: How We Store It, How We Check It, What It Costs
What this is: the full record for video in posts (decision D-69, built 28 September 2026). It follows a video from the moment a student picks the file to the moment it plays in someone's feed: where it is kept, how it is checked, what is still to build, and what it costs. The one-page summary for the founder is 24-video-founder-summary.md.
Status: built and tested on the development branch. Not live yet. Prices checked on 29 September 2026 (AWS US East region, US dollars). Where a number is our own estimate rather than a price or a measurement, it says so.
In one minute
- A post can carry one video: up to 15 minutes and 5 GB, never together with photos. These are LinkedIn's own limits.
- Every video is rebuilt on our own server, so hidden location data from the phone can't survive. Its speech is turned into text, so a phone number said out loud is caught just like a written one.
- A person watches every video all the way through before anyone else can see it.
- Money: at the volume we expect, storing and delivering video costs about $5–20 a month, paid from our AWS credits. The automatic picture check we still have to add costs about $54 a month from Amazon, or nothing on our own server.
- The real cost is people's time: about 9–13 hours of reviewing a month at the volume we expect, and 33–50 hours in a busy month.
- Still to build: checks against lists of known child-abuse videos (free), detection of new child-abuse material (Thorn, price on request, or Google, free if approved), the automatic picture check, and some smaller fixes (section 7).
- Decisions we need from the founder: video length, which picture check, how long to keep originals, the free applications, and reviewer hours (section 7.3).
1. What a student can do
We copied LinkedIn's rules for member posts exactly (from LinkedIn's help pages, checked 28 September 2026).
| Rule | Limit |
|---|---|
| Videos per post | One. A post has photos or a video, never both. Text is optional. |
| File types | MP4, MOV, WEBM, MKV, AVI, WMV, MPEG |
| File size | 75 KB to 5 GB |
| Length | 3 seconds to 15 minutes |
| Picture size | From 256×144 up to 4096×2304 (4K), either way up — so vertical phone videos are fine |
| Shape | No wider than 2.4 : 1 and no taller than 1 : 2.4 |
| Frame rate | 10 to 60 frames a second |
The length and size limits are settings, not code. If the founder decides on a shorter limit for the pilot, it changes without a new release.
Posting a video, step by step:
- Tap Add video in the post box and pick a file. The browser checks the limits it can read (type, size, length) before sending anything.
- The file uploads straight away, with a progress bar. The student can keep writing.
- "Processing your video…" — our server rebuilds it and drafts captions (section 2).
- The student reviews it before posting:
- a preview they can play;
- a thumbnail: a frame we pick, or a picture they upload;
- captions: the ones drafted from the speech, which they check and correct line by line; or a caption file they upload (the common ".srt" format); or none.
- Post. The post waits for a person to check it (section 4).
What everyone else sees once it's approved:
- In the feed the video plays silently once most of it is on screen, one video at a time. Clips under 30 seconds loop.
- Captions are on by default, with buttons for captions, sound, and full size.
- Full size plays the sharper copy with sound, with a speed control (0.5× to 2×), and picks up where the feed left off.
- Anyone can turn off autoplay under Settings → Appearance → Autoplay videos. Devices set to "reduce motion" never autoplay.
Two deliberate differences from LinkedIn:
- No view counts. Thnkrr shows no popularity numbers anywhere (founder confirmed).
- Published posts can't be edited, as for every post on Thnkrr. A post the check rejected can be fixed: its text, captions and thumbnail can change, but never the video itself. To use a different video, delete the post and post again.
2. Where a video goes, step by step
Step 1 — Upload, into a locked room. The browser sends the file in pieces of 16 MB, three at a time, straight into private storage — a locked storage area only our server can open. We call it quarantine. If a piece fails, it is retried. If the connection drops, the upload carries on from the pieces already stored (as long as the same browser tab is still open). The upload goes straight into storage rather than through our server, so a big upload can't slow the site down.
Step 2 — Processing on our own server. Our server then fetches the file from private storage and, behind the scenes, one video at a time:
-
Reads what the file really is, and checks it against every limit in section 1 again. A file can lie about itself; the browser's word isn't trusted. A file that fails gets a plain explanation, like "Videos need to be at least 3 seconds long."
-
Rebuilds the video from scratch. It keeps exactly one picture track and one sound track and throws everything else away: location tags, phone make and model, chapters, subtitles, GPS tracks from action cameras. Then it checks the rebuilt file, and if anything other than a few harmless technical labels is left, the video is refused. (Tested on an iPhone-style file carrying a GPS location, "Apple" and "iPhone 17": all three were gone.)
-
Makes two copies for playing:
- SD (480p, about DVD quality): what the feed plays. Small, quick to load.
- HD (720p, basic high definition): what full size plays. Only made if the original is sharper than 480p. Nothing is ever enlarged.
Both are ordinary MP4 files that play in every browser, at up to 30 frames a second.
-
Makes a poster (the still picture shown before playing) and a storyboard — 30 small frames taken evenly across the whole video, laid out in a grid. The storyboard is only for the person reviewing it.
-
Turns the speech into text, if the video has sound. This runs on our own server using Whisper: free speech-recognition software that anyone can download and inspect ("open-source"). AI software like this is called a "model". Because it runs on our server, no student's voice is sent to any other company. It only writes down the words. It never tries to work out who is speaking.
-
Saves the copies back into private storage and marks the video ready.
Step 3 — The student reviews and posts. Section 1, step 4.
Step 4 — A person checks it. Every video post goes to a human reviewer (section 4). The video's captions and the text of its speech are also read by the same automatic text check as every written post.
Step 5 — Approved: it goes public. The server copies the SD and HD files, the poster (or the student's own thumbnail) and a caption file into public storage. From there, Amazon's delivery network (CloudFront) serves them to viewers quickly. The copying happens inside storage; the video never passes through our main server.
Step 6 — Removed or deleted: it comes down. If a moderator removes the post, or the student deletes it, the public copies are deleted, not just hidden, so a saved link stops working too. The post is replaced by a short "removed" notice. The private copies stay, as the record of what happened.
3. What we store, and for how long
| What | Where | Who can see it | Size | How long |
|---|---|---|---|---|
| The original file | Private storage | Nobody. Only our server reads it. | Typically 90–130 MB per minute of 1080p (Full HD, most phones' normal setting); about three times that for 4K (ultra HD) | Forever, today. We recommend 30 days, unless it is evidence in a safety case (kept 1 year for child-abuse reports; section 7.2). |
| SD copy (480p) | Private; also public once approved | The author before approval; the school community after | About 5 MB per minute (never more than about 9) | For as long as the post exists |
| HD copy (720p) | Private; also public once approved | Same | About 17 MB per minute (never more than about 22) | Same |
| Poster | Private; also public once approved | Same | About 30–150 KB | Same |
| Storyboard (30 frames) | Private only | Reviewers only | About 100 KB | As long as the review record (no end date set yet) |
| Captions | Our database; a public caption file once approved | Everyone who can see the post | A few KB | For as long as the post exists |
| Transcript (the words spoken) | Our database only | Reviewers and the automatic text check. Never shown publicly. | A few KB | As long as the review record (no end date set yet) |
| Facts about the video (length, whether it has sound, which copies exist, why a file was refused) | Our database | Our server | Tiny | As long as the review record (no end date set yet) |
The SD and HD sizes were measured on a busy 3-minute 1080p test video (17.3 MB per minute for HD and 4.7 MB for SD). Ordinary footage usually comes out smaller. The "never more than" figures are the ceilings our settings allow.
4. How we keep video safe
| The risk | What we do | Built? |
|---|---|---|
| Hidden location data. Phones write GPS and device details into the file. | The file is rebuilt with only its picture and sound, then checked; anything left over means it's refused. | Yes |
| Something said, not written. "Message me at…" said out loud passes every text check. | The speech is turned into text on our own server, and that text goes through the same checks as any post. A spoken phone number flags the post. | Yes (tested) |
| What's in the picture. No automatic check can see a video the way a person can. | A person watches every video before it's shown (how, below the table). | Yes |
| Files built to attack our server. Video files can be crafted to exploit the software that reads them. | Our server opens only a short list of allowed video formats, and the video software is blocked from reaching the internet, so a booby-trapped file can't fetch anything. Every step has a time limit and runs at low priority, so it can't take over the server. | Yes |
| Known child-abuse material. | Matching against the lists kept by child-protection bodies. | No — section 7.1 |
| Harmful pictures a reviewer might miss in a long video. | An automatic picture check that marks where to look. | No — section 7.1 |
| Classmates or teachers filmed without agreeing; secret classroom recordings. | A reviewer checklist ("no identifiable classmates without their agreement; no classroom recordings unless a teacher posts them"), plus a way for someone to say "that's me and I didn't agree". Some US states restrict recording in class (California requires the teacher's and principal's consent). | No — section 7.1 |
| Taking a video down. | Removal deletes the public copies, not just the link. | Yes for removed and deleted posts. The intimate-image takedown tool needs one fix for video (section 7.1). |
How the reviewer checks a video:
- They first see the storyboard: 30 still pictures from across the whole video.
- The video stays blurred and silent until they choose to play it, so nothing shocking catches them off guard.
- The transcript and captions sit alongside.
- Approve stays locked until the whole video has played (up to 2× speed; skipping ahead doesn't count).
5. How reliable each check is
| Check | What it's good at | What it can miss |
|---|---|---|
| Rebuilding the file | Removing hidden data. Very reliable: the file is rebuilt and then inspected. | It can't remove what's visible in the picture — a street sign, a house number, a face. That's the reviewer's job. |
| Speech-to-text | Clear speech in a quiet room. On our 3-minute test talk it wrote 539 words without one wrong word — but that was a clear computer voice, which is easier than real students. | Loud music, several people talking at once, strong accents. Hindi is weaker than English with the model we use now; a bigger model is more accurate but about three times slower. The reviewer listens anyway; the transcript is a helper, not proof. |
| A person watching | The strongest check we have — context, tone, who's in the frame. | Attention. The watch lock proves the whole video was played, not that someone paid attention to every second. Long videos cost the most here (section 6.5). |
| Automatic picture check (to build) | Obvious nudity, and text written on screen (a phone number, a social media handle). | Anything shown between the frames it samples. It checks about one frame a second, so a half-second flash can slip past. Weak on context: a toy gun vs a real one, a medical picture. |
| Known child-abuse matching (to build) | Near-certain on material that is already on the lists. | Anything new. That's what new-material detection (below) is for. |
| New child-abuse detection (to build: Thorn or Google) | New material nobody has catalogued. | Raises false alarms. A person always confirms. |
6. What it costs
6.1 Our assumptions
These are our own estimates, to be replaced with real numbers in the pilot's first month.
| Expected month | Busy month | |
|---|---|---|
| Videos posted | 300 | 1,000 |
| Average length | 1.5 minutes | 2 minutes |
| Minutes of video posted | 450 | 2,000 |
| Video watched by all viewers together | about 0.85 TB | about 2 TB |
The viewing estimate assumes 1,500 people use Thnkrr each day. Each sees about four videos play silently for a few seconds, then opens one video full size and watches about half of it. For a busy month we assume about 2½ times as much watching per person (more videos, and longer ones).
6.2 Storage
Amazon storage (S3) costs $0.023 per GB per month.
| Expected month | Busy month | |
|---|---|---|
| Finished copies (SD + HD) added each month | about 10 GB | about 44 GB |
| Monthly bill for these after a year of build-up (about 120 GB / 530 GB) | about $2.75 a month | about $12 a month |
| Originals, if kept 30 days | about $1–1.40 a month | about $4–6 a month |
| Originals, if kept forever (today's behaviour) | about $11–16 a month by month 12, still rising | about $50–72 a month by month 12, still rising |
| Posters, storyboards, captions | under 1 cent | under 1 cent |
Storage is cheap either way. Deleting originals after 30 days is still worth doing: it stops the one number that grows forever, and it means we hold less of children's data.
6.3 Delivery to viewers
Amazon's delivery network (CloudFront) is free for the first 1 TB every month, then $0.085 per GB.
| Expected month | Busy month | |
|---|---|---|
| Video delivered | about 0.85 TB | about 2 TB |
| Cost | $0–15 (video alone fits in the free 1 TB; with photos it may go slightly over) | about $85 for video alone; up to about $110 with photos |
The feed only downloads a video's poster until it starts playing, so videos scrolled past cost almost nothing.
6.4 Processing on our own server (measured)
We ran our real processing steps on a 3-minute 1080p test video with continuous speech, on a modern laptop processor (Apple M4). A cloud server's processor is slower; we assume 2–3 times slower, which is our estimate, not a measurement.
| Step | Processor time on the laptop, per minute of video (measured) | Estimated on our server, per minute of video | Memory at its peak |
|---|---|---|---|
| Making the SD and HD copies | 49 seconds of computing | 1.6–2.5 minutes | about 410 MB |
| Speech-to-text | 13 seconds | 0.4–0.7 minutes | about 600 MB |
| Poster and storyboard | about 1 second | a few seconds | small |
| All together | about 63 seconds | about 2–3 minutes | one step at a time, so about 600 MB at most |
What that means for our server. The planned server is Amazon Lightsail's $12 plan: 2 processors and 2 GB of memory. It can run steadily at 20% of each processor, and go faster for short stretches using credit it saves up while quiet (Amazon's published figures). Over a month, that steady allowance is about 290 hours of computing.
| Expected month | Busy month | |
|---|---|---|
| Computing needed for video | 16–24 hours | 70–105 hours |
| Share of the server's steady allowance | about 5–8% | about 24–36% |
| Wait before a 1.5-minute video is ready | about 2 minutes | same |
| Wait before a 15-minute video is ready | about 15–25 minutes | same |
The wait is about half the computing time because the server's two processors share the work. It assumes the server has saved-up credit; if that has run out, waits can be several times longer.
Cost: $0 extra at the volume we expect. The things to watch are bursts, not the monthly total. A run of long videos can use up the saved-up credit and slow down the whole site. If that happens, we move video processing onto a second $12 server (the same software, doing only background work). That costs $12 a month more, from the credits. (The $24 plan has the same processors and only adds memory, so it helps only if the server runs short of memory.)
6.5 Checking (moderation)
Reviewer time is the biggest cost of video. A reviewer plays each video in full (at 1–2× speed) and spends about a minute on the storyboard, transcript and decision.
| Expected month | Busy month | |
|---|---|---|
| Watching | 225–450 minutes | 1,000–2,000 minutes |
| Storyboard, transcript, decision | 300 minutes | 1,000 minutes |
| Reviewer time | about 9–13 hours (about 18–25 minutes a day, counting every day of the month) | about 33–50 hours (1–1.7 hours a day) |
A single 15-minute video takes a reviewer 8–16 minutes. The monthly totals depend on the average length, so a lower limit mostly protects against the worst cases: a burst of long videos, or someone uploading long videos on purpose to flood the queue.
The automatic checks:
| Check | Status | Cost — expected month | Cost — busy month |
|---|---|---|---|
| Speech-to-text on our own server | Built | $0 (uses the computing in 6.4) | $0 |
| — or Amazon Transcribe instead | Not used | about $3–11 (see note) | $12–48 |
| Reading captions and speech with the existing text check | Built | under $1 | a few dollars |
| Automatic picture check — Amazon Rekognition, one frame a second, pictures and on-screen text | Not built | about $54 ($0.12 per minute) | about $240 |
| — or the same, one frame every 2 seconds | Not built | about $27 | about $120 |
| — or Rekognition's video service (pictures only, no on-screen text) | Not built | about $45 ($0.10 per minute) | about $200 |
| — or an open-source model on our own server | Not built | $0 (see 6.7) | $0 |
| Known child-abuse matching — three child-protection services (section 7.1 #1) | Not built | $0 — all free once accepted | $0 |
| New child-abuse detection — Thorn (a US child-safety non-profit), or Google's Content Safety API | Not built | Thorn: price on request (their smallest published plan is $30,720 a year, sized far beyond us). Google: free if approved. | same |
Note on Transcribe: Amazon's own worked example uses $0.006 a minute; older price lists say $0.024. We haven't confirmed which applies to us, so the table shows both ends.
6.6 The total, per month
Everything from Amazon is paid from our ≈ $5,000 in AWS credits.
| Expected month | Busy month | |
|---|---|---|
| Storage (originals kept 30 days), after a year | about $4 | about $18 |
| Delivery | $0–15 | $85–110 |
| Server | $0 extra | $0–12 extra |
| Speech-to-text (our server) | $0 | $0 |
| Automatic picture check (to build) | $0 on our server, or about $54 on Rekognition | $0, or about $240 |
| Known child-abuse matching (to build) | $0 | $0 |
| Money, not counting Thorn | about $5–75 | about $100–380 |
| New child-abuse detection (to build) | Thorn quote, or free via Google | same |
| Reviewer time | 9–13 hours | 33–50 hours |
6.7 Running models on our own server, or paying a service?
We already run one model on our own server: speech-to-text. It costs no money, and uses about 1–2% of the server's steady allowance at the volume we expect. It also keeps every student's voice inside our own systems.
We could do the same for the automatic picture check with an open-source model:
- Money: $0 per video.
- Computing (our estimate, not yet measured): small models check a frame in about 0.01–0.03 seconds on a cloud processor; larger, more accurate ones take about 0.3–0.7 seconds. At one frame a second, that is between a couple of seconds and about 45 seconds of computing per minute of video — at most about 6 hours a month at the volume we expect, and 25 hours in a busy month. It fits on the same server.
- The catch is accuracy, not money. Our earlier research (docs/20 §10.3) found the open-source picture models check nudity only — no violence, weapons, drugs or hate symbols — and one popular model also labels faces, which clashes with our promise of no face analysis. Reading text written on screen would need a second open-source tool. And nobody stands behind their results but us.
- What can never run on our own server: child-abuse detection. No legitimate open-source model for it exists; those checks are only available from Thorn, Google, Microsoft and the child-protection bodies, under agreement.
Would running models ourselves raise costs a lot? No. There is no per-use charge, unlike a paid service. The one possible cost is the second server from 6.4: $12 a month more. What we give up is accuracy, and a supplier who is accountable for the results.
Our recommendation: use Amazon Rekognition for the picture check. It covers more kinds of harm, the credits pay for it, and it's the same work the photo check needs anyway. Build it so the supplier can be swapped without rework, as we did for speech-to-text, so an open-source model can replace it later if the cost or a privacy concern calls for it.
7. What's still to build
7.1 On the moderation side
| # | What | Why | Cost | Waiting on |
|---|---|---|---|---|
| 1 | Known child-abuse matching for video, three ways: (a) Project Arachnid (Canadian Centre for Child Protection) checks whole videos we send it. (b) Google's CSAI Match compares each video's "fingerprint" (a short code that identifies it without sharing it) with about 220,000 known abuse videos. (c) Our server compares key still pictures with the list kept by NCMEC (the US National Center for Missing & Exploited Children). | Required safety floor | Free | Three free applications, filed by a person. About a day of code once access arrives. |
| 2 | New child-abuse detection: Thorn Safer, or Google's Content Safety API | Catches material nobody has listed yet | Thorn: quote. Google: free if approved. | The Thorn email already drafted, or a Google application |
| 3 | Automatic picture check (section 6.7) | Tells the reviewer where to look; the only automatic check that reads text written on screen | about $54 a month (Rekognition), or $0 on our server | Nothing. Same work as the photo check, which isn't built yet either. |
| 4 | Re-upload block: when a video is removed for abuse or intimate-image reasons, its frames go on the blocked list, so the same video can't come back | Stops the same harm returning | Free | The moderation and video work being merged first (the blocked list lives in one, video in the other) |
| 5 | Intimate-image takedown for video. The takedown tool deletes one public file. A video has several, so today that tool would leave a video's files reachable by their web address. (Removing the post does delete them.) | A 2-hour legal clock applies in India | Free, a small fix | Same as 4 |
| 6 | "That's me and I didn't agree" — the intimate-image request page, extended to videos | Someone filmed without consent | Free | Nothing |
| 7 | Reviewer checklist for video — no identifiable classmates without their agreement; no classroom recordings unless a teacher posts them | Consent problems no machine can judge | Free, one page | Nothing |
7.2 Before going live
| What | Why |
|---|---|
| Install the video software and the speech-to-text software (with its 148 MB data file) on the server, and tell the server where that file is (names in section 8) | Without them, videos can't be processed or captioned |
| Storage rule: let the web app read caption files, and see the receipt storage gives back for each uploaded piece (details in section 8) | Without it, captions don't show and large uploads can't finish |
| Storage rule: throw away pieces of uploads that were abandoned halfway, after 1 day | Unfinished uploads are charged for until cleaned up |
| Storage rule: delete originals after 30 days, except those under a safety hold | Stops storage growing forever. Safety holds (1 year for child-abuse reports) must be excluded. |
| Give video its own background queue | Today photos and videos share one queue that works on one upload at a time, so a long video would make photo uploads wait behind it |
| An alert when the server's saved-up processing credit runs low | The early sign to add the second server (section 6.4) |
| Fix the three out-of-date automated tests on the moderation branch | They check old screen names, not real faults |
7.3 Decisions for the founder
Product decisions and paperwork only; technical choices are the team's (below).
- Video length for the pilot. 15 minutes (LinkedIn's limit) or shorter. The cost is reviewer time (section 6.5); the setting changes without a release.
- How long we keep the student's original file (the full-quality upload, locked away where nobody sees it): 30 days (recommended, except evidence in an abuse report) or forever.
- Send the free child-abuse matching applications (7.1 #1) and ask Thorn for pilot pricing in the email already drafted (7.1 #2).
- Reviewer hours: plan for about 18–25 minutes of video review a day at the volume we expect (counting every day of the month), and measure the real figure in week one.
Decided by the team: the picture check will be Amazon Rekognition, behind a connector an open-source model could replace later (section 6.7).
8. For engineers: where things live
| Piece | Where |
|---|---|
| Decision record | docs/07, D-69 |
| Limits and data shapes | packages/contracts/src/media.ts (VIDEO_LIMITS), social.ts (PostVideoInput, PostVideo) |
| Upload, publish, takedown | src/modules/media/video-service.ts |
| Probe, rebuild, verify, poster, storyboard, speech | src/modules/media/video.ts |
| Speech-to-text connector | src/lib/transcriber.ts (WHISPER_BIN, WHISPER_MODEL) |
| Settings | VIDEO_MAX_DURATION_S, VIDEO_MAX_BYTES, FFMPEG_BIN, FFPROBE_BIN in src/config.ts |
| Tests | test/integration/post-videos-flow.test.ts (real ffmpeg); web e2e/post-video.spec.ts |
| Web: composer, player, reviewer card | ComposerVideo.tsx, PostVideo.tsx, ReviewVideo.tsx, lib/video-upload.ts |
| Server install | ffmpeg/ffprobe and whisper-cli on the PATH; WHISPER_MODEL = path to ggml-base.bin (148 MB) |
| Bucket rules | CORS: allow GET on caption files and expose the ETag header (multipart uploads); lifecycle: abort incomplete multipart uploads after 1 day; expire originals/ after 30 days, excluding safety holds |
| Database | media gains video columns; posts.video_media_id (migration 0014_post_videos; renumbered 0019 on the combined branch) |