<- all tokdocs

A $12 droplet topped out at 232 requests per second, and "5,000 concurrent users" is really 20 seconds of think time doing the work

Watch on TikTok

View on TikTok ->

A 111-second clip (1:51) at 1080x1920, posted 2026-09-25 by @arjay_mccandless (channel name "Arjay McCandless"), sitting at 265,800 views, 20,800 likes, 408 comments, 1,273 reposts and 9,203 saves at capture, scored to "Shadow Protocol" by Jasper Reed. I read all 56 frames in tokdoc_frames/ against a 467-word Whisper transcript. The format is a split screen: animated data cards on the top half, the creator talking to camera in a kitchen on the bottom half, with burned-in captions. The cards name the hardware as a DigitalOcean "Basic Droplet" in nyc1 at $12/month, Ubuntu 24.04, "≈ $0.018 per hour", broken out as 1 vCPU (shared core, 2.0 GHz), 2 GB RAM ("1,967 MB usable"), 50 GB SSD ("whole DB is 357 MB"). The app is labeled "Express 5 · TypeScript", "a tiny Twitter clone", exposing GET /feed, GET /posts/:id, POST /posts/:id/like and POST /posts. A seed card counts up to 50,000 users, 500,000 posts and 2,016,005 likes with "database size 349 MB" split "users 7 · posts 134 · likes 208". An architecture strip shows Users → Nginx → Node.js → Postgres with "DB on the same box", a red X through "separate DB server", and the tags "1 vCPU", "2 GB RAM", "no Docker". The load generator is a second DigitalOcean box at "4 vCPU · 8 GB" running k6, "< 1 ms" away, "generator peaked at 37 % CPU", billed "4.5 h × $0.13 = $0.60". The k6 loop is drawn as a circle: load feed GET /feed → wait 3-7 s → open post + wait 3-8 s → "like it? 15 %" → "post? 2 %" → wait 5-15 s. Result cards run 10/50/100 users at 5.2/4.5/4.2 ms median with CPU at 9 %, then 1,000 users at 83 req/s and 39 % CPU, then 2,000 users where p95 goes 19 ms → 161 ms and p99 goes 50 ms → 276 ms, then 3,000 users failing the stated gates (p95 < 500 ms measured 1,356 ms, p99 < 1 s measured 2,287 ms, errors < 1 % measured 0 %), then 2,500 users at 232 req/s, 11 ms median, "0 of 92,799" errors, p95 288 ms and p99 775 ms. A diagnosis card reads "RAM 863 of 1,967 MB ✓", "Postgres ~1 ms queries ✓", "CPU 80 % at 2,500 users". The fix is two cards: a Node in-process cache showing the snippet if (cache && cache.expires > now) return cache.body labeled "cache: /feed JSON lives in RAM, 1 s", "no new infra", "+ $0 / month", with Redis crossed out; then an Nginx "micro-cache, 1 s". The final bar chart reads baseline 2,500 → + Node cache 4,000 → + Nginx cache 5,250 with "× 2.1 users", "p95 160 ms", "p99 454 ms", closing on "5,250 at the same time", "5-10 % of users online at once", "≈ tens of thousands daily users".

The hardware and the price are real, and the price ladder checks out

Every hardware number on screen matches DigitalOcean's own pricing page. The Basic Droplet at 1 vCPU, 2 GB RAM and 50 GB SSD is listed at $12.00 per month and $0.01786 per hour. The card's "≈ $0.018 per hour" is that figure rounded up. The step chart later in the clip showing $12 (1 vCPU) → $24 (2 vCPU) → $48 (4 vCPU) → $96 (8 vCPU) also holds: the same page lists the 4 vCPU / 8 GB Basic Droplet at $48.00 per month and the 8 vCPU / 16 GB at $96.00 per month, and the 2 vCPU / 4 GB Basic tier is $24.00 per month.

The load generator line is the one number that needs a caveat. The card says "4 vCPU · 8 GB" billed at "$0.13" per hour. A Basic 4 vCPU / 8 GB droplet is $0.07143 per hour, not $0.13. The CPU-Optimized 4 vCPU / 8 GB droplet is $84.00 per month, $0.12500 per hour, which is what $0.13 rounds from. At the actual $0.125 rate, 4.5 hours costs $0.5625, so the on-screen "$0.60" is generous by about four cents. The stack is otherwise ordinary and current: Express 5 shipped on 15 October 2024 after a ten-year release PR, and Ubuntu 24.04 is the Noble Numbat LTS line, still receiving point releases through 24.04.5 in September 2026.

The throughput arithmetic holds to within about 12 percent

The k6 loop drawn in frame 17 is enough to predict the request rate, and the prediction lands close to the measurement. Counting the branches on the circle, one iteration issues one GET /feed, one GET /posts/:id, a like 15 percent of the time and a post 2 percent of the time. That is 2.17 requests per iteration. The think time is three sleeps at 3-7 s, 3-8 s and 5-15 s, so roughly 5 + 5.5 + 10 = 20.5 seconds at the midpoints. That gives 0.106 requests per second per virtual user, and 2,500 virtual users predicts 265 req/s. The card reports 232 req/s. The 12 percent gap implies an effective iteration time near 23.4 seconds instead of 20.5, which ramp-up and per-request latency account for.

A second consistency check passes too. The card reports "0 of 92,799" requests at the 2,500-user step. At 232 req/s that is 400 seconds of steady traffic, a sensible 6-minute-40-second stage.

This arithmetic only works because k6 uses a closed model. Grafana's own docs state that "in a closed model, the next iteration doesn't start until the previous one finishes" and that "the start or arrival rate of new VU iterations is tightly coupled with the iteration duration". sleep() "suspend[s] VU execution for the specified duration". The same docs warn that a closed model produces coordinated omission: when the server slows down, iterations take longer and the test applies less load, which makes the failure point look softer than it is.

"5,000 people using it at the same time" is about 3 to 20 requests in flight

This is where the clip's framing runs ahead of its own data. The transcript says:

Moving to Nginx pushed me past 5,000 concurrent users on my $12 machine. Remember, that's 5,000 people using it at the same time.

Frame 51 draws it as a grid with "1 dot = 1 user" and "all at the same time" underlined. But a virtual user in this loop spends 20.5 of every 23.4 seconds asleep. Apply Little's Law to the reported numbers. At 2,500 users the server did 232 req/s with an 11 ms median, so the average number of requests actually in flight was 232 × 0.011 ≈ 2.6. Even using a mean latency of 50 ms to account for the 288 ms p95 and 775 ms p99 tail, that is under 12 in flight. Scaling the same loop to 5,250 users gives roughly 487 req/s, and at the reported p95 of 160 ms the in-flight count is still in the low tens.

So the honest version of the claim is that the box sustained 232 req/s uncached and close to 490 req/s with the Nginx micro-cache. The "5,000 users" figure is that throughput multiplied by a 20-second think time. Change the think time to 5 seconds and the same server supports roughly 1,300 of those users, not 5,250. The clip never states the think time out loud, and it is the single assumption doing the most work in the headline.

The one-second cache wins because the traffic is high, and because there is only one feed

The Node change is the classic micro-cache, and the snippet on screen is the whole thing: if (cache && cache.expires > now) return cache.body. Skipping Redis for a single-box deployment is sound. The video's own diagram states the tradeoff correctly as "+1 service, +1 network hop" avoided.

What the clip does not say is that a 1-second TTL is only impressive at high request rates. At the baseline mix, roughly 46 percent of requests are GET /feed, so 232 req/s means about 107 feed requests per second. A 1-second TTL means exactly one origin render per second, so the hit rate is about 99.1 percent. At the post-cache rate of roughly 490 req/s the hit rate rises to about 99.6 percent. Run the same cache against 10 feed requests per second and it only saves 90 percent. The cache did not make the server faster. It converted a request rate into a fixed one-render-per-second cost, and the benefit scales with the rate you were already handling.

NGINX's own blog measured the same effect at a larger ratio, going from 5.53 req/s uncached to 2,185.03 req/s with proxy_cache_valid 200 1s, proxy_cache_lock on and proxy_cache_use_stale updating, with only 16 requests reaching the origin across a 30-second test. The clip's 2.1x is far more modest than that 400x, which is the correct outcome for a backend that was already serving 11 ms medians.

The bigger structural assumption is that GET /feed has one cacheable body. The card reads "cache: /feed JSON lives in RAM, 1 s" with a single expiry, and the Nginx version is a micro-cache on one URL. That only works if every one of the 50,000 seeded users sees the identical global timeline. A per-user feed would need 50,000 cache entries, each with its own 1-second window and its own miss, and the hit rate would collapse toward zero. Real Twitter-shaped products are personalized, so this optimization transfers to public feeds, trending pages and anonymous landing endpoints, and does not transfer to a logged-in home timeline as-is.

Postgres stayed quiet because the entire database fit in RAM

The diagnosis card credits Postgres with "~1 ms queries ✓" and RAM at "863 of 1,967 MB ✓". That result is a direct consequence of the seed size. The database is stated as 349 MB on one card and 357 MB on another, against 1,967 MB of usable memory. PostgreSQL's default shared_buffers is 128 MB, so the database does not fit in Postgres's own buffer pool, but the documentation notes that "PostgreSQL also relies on the operating system cache". With under a gigabyte of the 2 GB in use, the OS page cache holds the whole 349 MB working set after warm-up. Every query is a memory read.

This is the assumption that breaks first in production. Grow the same schema to 5 GB on the same $12 box and the feed query starts hitting the 50 GB SSD, p95 moves from tens of milliseconds to hundreds, and the bottleneck moves off the CPU. The clip's "no dedicated database" conclusion is correct for a 349 MB dataset and says nothing about a dataset larger than RAM.

One operational detail the clip skips: nginx ships with worker_connections 512 and worker_processes 1 as documented defaults. On a 1 vCPU droplet worker_processes auto also resolves to 1. Holding 5,250 keep-alive connections needs worker_connections raised well above 512 plus a matching file-descriptor limit. The test presumably tuned this, since the run reported zero errors, but the video presents "two really simple changes" without mentioning it.

Where the voiceover and the screen disagree

Several numbers differ between the spoken track and the cards, and one differs in a way that matters.

The transcript says "my CPU utilization hit 90%". Frame 33 reads "CPU 80 %" with the caption "80 % at 2,500 users". The transcript says the Node cache "pushed me from roughly 2,500 users all the way up to 4,000", and frame 43 shows "3,887" under "+ Node cache" before the final chart rounds it to 4,000. The transcript says "I rented for about 4 hours" while the card says "4.5 h". The seed card shows "349 MB" while the spec card says "whole DB is 357 MB". The transcript says "2 million likes" against a precise 2,016,005 on screen.

Separately, several eye-catching numbers in the frames are odometer artifacts from count-up animations rather than results. The opening two frames show "266" and then "5,195" in the same "users at once" slot before it settles. Frame 12 shows "virtual users 2,907" mid-count. Frame 48 shows "2,476 / 3,844 / 1,254" in the same bar chart that frame 49 resolves to "2,500 / 4,000 / 5,250". Frame 50 shows "3,602 people, right now" counting toward 5,250. Anyone screenshotting mid-animation would quote a number the creator never claimed.

Key Takeaways

  • The $12/month DigitalOcean Basic Droplet at 1 vCPU / 2 GB / 50 GB is real and costs $0.01786 per hour as of the pricing page fetched 2026-09-27. The clip's $12, $24, $48 and $96 vCPU ladder matches DigitalOcean's Basic tier list.
  • The headline result is 232 req/s uncached at 2,500 virtual users with a 288 ms p95, 775 ms p99, 11 ms median and zero errors across 92,799 requests. That number is the one to quote.
  • The "5,250 concurrent users" figure is throughput multiplied by roughly 20.5 seconds of scripted think time. By Little's Law the server held single-digit to low-double-digit requests in flight. Halving the think time roughly halves the user count on identical hardware.
  • The per-VU arithmetic reconstructs to 0.106 req/s (2.17 requests per iteration over 20.5 s of sleep), predicting 265 req/s at 2,500 users against 232 measured. The experiment is internally consistent within about 12 percent.
  • A 1-second cache on /feed gives about a 99 percent hit rate at 107 feed req/s and only 90 percent at 10 feed req/s. The gain is a function of the request rate you already have, and it assumes one global feed body rather than a per-user timeline.
  • Postgres stayed at ~1 ms because the 349 MB database fit entirely in the 2 GB of RAM. PostgreSQL's default shared_buffers is 128 MB, so the OS page cache was doing the work. This result does not extend to a dataset larger than RAM.
  • The voiceover says 90 percent CPU where the card shows 80 percent, and says 4,000 users where the intermediate card shows 3,887.
  • The load generator card reads "$0.13" per hour for a 4 vCPU / 8 GB box, which matches DigitalOcean's CPU-Optimized tier at $0.125 rather than the Basic tier at $0.07143. At $0.125, 4.5 hours is $0.5625, not the $0.60 shown.
  • Unverified: I could not confirm the closing "5-10 % of users online at once" heuristic against any primary source. Published peak-concurrent-to-DAU ratios vary enormously by product category, so the jump from 5,250 concurrent to "25,000 or 30,000 daily active users" is a plausible rule of thumb with no measurement behind it. I also could not verify the raw k6 script, the Nginx proxy_cache configuration, the exact worker_connections value used, the Postgres version, or the GET /feed query and page size, because no repository, gist or long-form writeup is linked from the video or its description.

Resources

Published September 25, 2026. Writeup generated from a favorited TikTok.