# Deviations from PLAN.md Every deviation from the fixed plan, with date (UTC) and reason. Changes to the original are timestamped. > Published copy. Internal names, paths and versions of the client project are withheld ([withheld]); only the > withheld passages and the reference to the timestamp file are changed or reworded in the original portion. The > correction dated 2026-10-14 is a later addition, not covered by those timestamps. The timestamps cover the unaltered > original, which stays private, so they cannot be checked against this copy. ## 2026-10-12 (UTC) — round 1 set-up - Originals of the project mirror lie in `[withheld]` (the uploads); another folder of the mirror holds only the extracted audio. `vhb project` reads the uploads. Aggregates only, as planned. - Hetzner included traffic is 20 TiB = 21.99 TB (API `included_traffic`); `configs/prices.toml` uses 21.99 TB. - Vimeo's price page served USD for German language settings as well (request from Sweden); prices stay in USD at the ECB rate. Cloudflare's Stream pricing page names no required plan; no surcharge is added. - `configs/clips.lock` was committed after the timestamped PLAN.md (the download took about 25 minutes); no measurement used the clips before the lock. - Encoding timing (`vhb encode`, 19:33 UTC): the desktop was not idle — a media player used one core (100 %) and the browser a few per cent; ffmpeg is pinned to CPUs 0-3, the other processes are not. The times are indicative, as planned. - Vimeo test video 76979871 ("The New Vimeo Player", owner Vimeo): the planned check `oembed.json?url=https://vimeo.com/76979871` returned 404 on 2026-10-12, but the same video answers 200 via `https://vimeo.com/channels/staffpicks/76979871`, and its player configuration reports `privacy: anybody` with HLS, DASH and progressive files. The video is public and embeddable; it stays. - Load test, found in a local dry run with the pinned k6 2.3.0 and Caddy 2.11.7 before any server was created (2026-10-12): k6 let running iterations go on for 30 s after each stage (`gracefulStop`), which would have overstated Gbit/s by about a sixth; stages now stop on time (`gracefulStop: '0s'`) and Gbit/s uses k6's measured run duration. The viewer script requested `init.mp4`, but the HLS muxer names the init file after the stream index (`init_3.mp4` for 1080p); the catalogue now carries the real name, as a player reads it from the playlist. - Encodes without the cap ran on all 32 CPUs in the first pass (19:33 UTC), the capped ones on 4. ffmpeg derives x264's thread count from the usable CPUs, and the thread count changes the bitstream: c11, whose cap does not bind (identical rates in both runs), came out 15 % smaller at 1080p without the cap. The comparison would have measured threads, not the cap. All encodes now run on CPUs 0-3, matching the 4 vCPUs of the production server, where ffmpeg also chooses the thread count itself. The uncapped clip encodes and the uncapped project sample (`vhb project cap`, whose capped sizes come from the production server) were repeated on 4 CPUs; the earlier result files stay in `results/` and are superseded by the newer ones (`results.latest`). - Load test, first start (20:11 UTC): aborted at the warm-up before any measurement. `rsync -a` into `/root` gave `/root` the owner and mode of the local folder, and sshd (StrictModes) then refused the key. The `finally` block deleted all three servers after about three minutes. The generator files now go to `/root/vhb`, and uploads copy files and times only (`rsync -rlt`). Pinned Chromium: Ubuntu 26.04 restricts unprivileged user namespaces, so Lighthouse starts the Playwright Chromium with `--no-sandbox`, as Playwright itself does by default. Check after the repeat: with identical commands (cap not binding), cap and no cap now differ by at most 0.05 % per clip (x264 with frame threads and a rate limit is not bit-exact between runs); c11 at 1080p 3.386 vs 3.386 Mbit/s, before 3.39 vs 2.95. The uncapped project sample on 4 CPUs: median 1.059 of the original (before 1.044), 63 % above the original (before 57 %); the capped values are unchanged. Check of comparability: five videos of the sample encoded locally with the cap on 4 CPUs come within 0.06 % of the production files (0.9999 to 1.0006). - Player measurement, first pass (21:03–21:19 UTC): the own player did not play, because the measurement page gave `` a relative `src` and Video.js 10.0.1 cannot resolve it ("Invalid base URL"); the project's page template uses an absolute URL ([withheld]), so the page now does too. Requests without host (`blob:` and `data:` URLs, no network traffic) were counted as a third-party host `''` with -1 bytes (Bunny); they are now left out. `cloudflare` overlapped the load test's HLS upload to the second target (21:17:03–21:18:16 UTC). `own`, `cloudflare` and `bunny` were measured again; the newer result files supersede the earlier ones. - Player measurement, second pass: the local measurement server sent text uncompressed, so the own player (690 kB JavaScript) and the facade carried bytes that no real web server sends; YouTube & Co. deliver compressed. The server now compresses text with gzip like Caddy or nginx (`.html`, `.js`, `.css`, `.m3u8`; segments unchanged), and all eight variants were measured again in one pass (21:33 UTC onwards). For comparison: the production bundle (Video.js [withheld], code splitting) has 481 kB, 120 kB with gzip; the measured one (10.0.1, one file) 690 kB, 161 kB with gzip. - Vimeo did not play in the test browser (Playwright Chromium 1248, no Widevine): after the click its player shows "Unable to play video. Please try again in a supported browser." (screenshot checked; the video also offers an encrypted `hls_cenc` rendition). The values before the click stand; after the click Vimeo loaded no segments, so its "after" values are a lower bound. All other variants played (`playing: true`), the baseline has no player. - Load test, second start (20:16–22:20 UTC): complete; both targets with both series, servers deleted. Three of the four series ended at about 5.4 Gbit/s. On the cpx22 the CPU was near its limit (79–89 %); on the cpx32 it was not (53–57 %). - Network check, added after the load test (not in the plan, 22:25–22:30 UTC, `vhb loadtest --netcheck`): iperf3 with 8 TCP streams for 20 s, sender in the role of the target, the ccx33 in the role of the generator. cpx32 to ccx33 12.7 Gbit/s, cpx22 to ccx33 13.6 Gbit/s, both at once 13.0 Gbit/s. The network did not limit the load test. What limited the cpx32 at about 5.4 Gbit/s is not identified (neither its CPU nor the network; the generator with k6 and TLS is possible), so the cpx32 values are lower bounds. A ccx43 as a second receiver was refused by Hetzner ("dedicated core limit exceeded"); two senders at once into the ccx33 answer the question instead. A first network check stopped at that limit and a second one at a result key with `>`; neither produced data, all servers were deleted. ## 2026-10-13 (UTC) — after the expert, data and code reviews - Vimeo: the Plan Usage Policy (last updated 2026-06-30) requires a Business Use plan for accounts used by or for a company; Vimeo's help page calls Studio "built for small-to-mid-sized businesses" and says it unlocks everything of the individual plans. The cost model now prices both: Starter (smallest plan for individuals, as planned) and Studio (400 USD a month billed annually, 10 TB storage, 36 TB bandwidth a year without monthly cap). The upgrade page also names upload limits for the individual plans (60/120/240 videos per seat and year), which the plan did not model. - Own server: the model puts the whole inventory on a volume, while spec §4.3 says "volume for the storage above the disk". Kept on purpose: the local disk holds the system, the originals and work files; originals are counted for no provider. With the spec's rule scenario M would cost about 4 EUR less and the break-even against Bunny would drop from about 137,000 to about 115,000 views a month (code review). - Added after the measurement: break-even view counts for both ends of the watched-share band, the band in the chart (spec §4.2, missing in the first report), German decimal commas and separated labels in the chart, storage entries in the browser per player variant (counted from the captured storage), and the storage per minute of the project against the test clips. - Load-test limit, rule set after the measurement: a series counts as limited by the target only where another target carried the stage at which it broke down, with the same generator and series (cpx22 in the mix: the cpx32 carried 3,200). Otherwise it is "open" and the capacity a lower bound (cpx22 all 1080p, both cpx32 series). The first rule (target CPU of at least 80 % where the series broke down) was also set after the measurement and is replaced. The network check ran iperf3 without TLS on 8 streams; it does not cover thousands of TLS connections. - Load-test limits not named in the plan: the 1.7 GB of test clips lay on the local disk and fit into the RAM of the cpx22, so they were served from the page cache; Caddy ran without access log and without the project's matchers. A large inventory on a volume with rarely requested videos is not measured. - Player capture: data, third-party hosts, cookies and storage come from one Playwright run in a desktop window (1280x900); only the Lighthouse values are medians of five runs. - Timestamps: the first Bitcoin attestation of PLAN.md is in block 971134 at 19:58:05 UTC; the calendar commitments were made when it was stamped, before the first measurement, but the project aggregates (19:23 UTC) and the first encodes (from 19:36 UTC) are older than the Bitcoin block. - `vhb clips fetch` rewrote configs/clips.lock with whatever Commons served; it now stops on a new version and only `--relock` accepts it (no effect on round 1: `vhb clips verify` still matches the lock). ## 2026-10-13 (UTC) — after the second expert and data reviews - Vimeo plans for individuals: the model now applies the upload limits of the upgrade page (Starter 60, Standard 120, Advanced 240 videos per seat and year, one seat). Uploads in the first year = inventory plus twelve months of new videos. Scenario S then needs Standard, scenario M fits no plan for individuals. Vimeo names no upload limit for Studio. The article compares only Studio, since companies need a business plan. - Bunny Stream: the model also prices Bunny's Volume network (0.005 USD per GB, 10 PoPs, bunny.net/pricing/cdn, checked 2026-10-13). The existing line is the Standard network at the Europe and North America rate. The own server with a CDN keeps the Standard network. - Derived values for readers who want to recompute: traffic, storage, uploads in the first year, originals and the time to re-encode the inventory per scenario (`costs volumes`). The originals do not fit on the local disk of the server in scenario L; the article no longer says they do. - Labels: the cap table calls the clips "test clips" (3 of the 13 are not Terra X). The chart no longer shows the Vimeo Starter line. - Player: the LCP of the iframe variants is not comparable. Lighthouse evaluates the main frame only, and the values of the iframe variants varied between passes on the same day (for example Bunny 1,817 ms, then 617 ms). The article no longer compares LCP. The own player ran without a poster image. - Publication: the published copies of PLAN.md and of this file withhold internal names, paths and versions of the client project and the planned timing of the access-log check. - Correction: the network check from cpx22 to ccx33 reached 13.5 Gbit/s (13.547 in the result), not 13.6 as written above; the summary, the tables and the article use 13.5. ## 2026-10-14 (UTC) — model correction and article review This addition is not covered by the original timestamps. The timestamped private originals remain unchanged. - Hetzner Volumes now use at least 10 GB, rounded up to whole GB, for both self-hosted variants. S/M/L provision 10/76/759 GB. Costs, break-even values and the chart were regenerated from the existing measurements. - Byte-based provider costs are identified as a model at equal assumed byte volumes, not measured provider encodes or equal visual quality. All-1080p sensitivity is shown; no pre-start video transfer or extra buffering/repeated downloads is included in the baseline. Watched duration is distinguished from delivered duration and log evidence. - Aggregate Lighthouse scores are removed from comparison tables; raw data stays available. The article limits claims about activation before a click, cache-resident server capacity, platform feature equivalence and accessibility. - Original archives, separate backups, spare capacity and labour are explicitly excluded from the cost table. The project owner confirmed customer notification and estimated effort on 2026-10-14: 4–8 hours for setup and commissioning, depending on size and setup, and 2–4 hours of operation per month. These are estimates, not newly measured results. The regenerated summary identifies the committed source/input revision via repo_commit with repo_dirty=false. See README.md for the updated interpretation and schema. No new player, encode or load measurements were made.