Two bottlenecks, one laptop: measuring before buying
August 9, 202610 min read
Two things had been going wrong on my daily driver, a Dell Precision 5510 from 2015.
The first: sessions dying. Browser tabs showing sad faces, processes getting killed, everything crawling.
The second: video calls falling apart. Audio and video breaking up, getting worse as the meeting went on, improving when everyone turned their cameras off.
The obvious story is that these are the same problem — the machine is old, it's out of memory, everything suffers. That story is half right, and the half that's wrong would have cost me a lot of money.
The rule: measure before buying
Before pricing a single component I went looking for numbers. Not "it feels slow" — counters, with units.
Here is what the machine reported.
Bottleneck one: memory, for the work
$ free -h
total used free shared buff/cache available
Mem: 15Gi 11Gi 490Mi 313Mi 4.9Gi 4.4Gi
Swap: 15Gi 14Gi 1.1Gi
$ zramctl
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS
/dev/zram0 zstd 15.5G 13.5G 4.8G 4.9G
Sixteen gigabytes of physical RAM, and 13.5 GB of live data sitting in compressed swap. The real working set is somewhere around 25 GB on a machine built for 16.
What's holding that? A browser with a working day's worth of tabs, several long-running agent sessions, a container runtime, a Node toolchain. None of them individually unreasonable. Together, they don't fit.
The kernel had already made that official:
$ journalctl -k --since "30 days ago" | grep -i "out of memory"
Aug 08 00:46:03 kernel: Out of memory: Killed process 1429919 (electron)
total-vm:1480458672kB anon-rss:61404kB
UID:1000 oom_score_adj:300
That oom_score_adj:300 is worth a paragraph of its own. Chromium-based browsers deliberately raise the OOM score of their tab renderers, telling the kernel "kill me first, I'm recoverable." So when memory runs out, you lose a dozen tabs while the process that actually ate the memory keeps running. The sad-face tabs are a symptom of pressure, not the cause of it, and chasing the browser is chasing the wrong process.
The firmware also told me where the ceiling is:
$ sudo dmidecode -t memory
Maximum Capacity: 32 GiB
Number Of Devices: 2
Size: 8 GiB Locator: DIMM A Type: DDR4 Speed: 2400 MT/s
Size: 8 GiB Locator: DIMM B Type: DDR4 Speed: 2400 MT/s
Two slots, both occupied, 32 GB maximum. So the memory fix on this chassis has exactly one shape: replace 2×8 with 2×16 and you are done forever, because 32 GB is the roof.
For this kind of work, RAM is the binding constraint. Not clock speed, not cores. Agent sessions, browsers and containers are memory-resident workloads: they hold state, they don't spin the CPU. When they don't fit, the kernel starts compressing pages and the whole machine goes to treacle — and no CPU upgrade fixes that, because the CPU was never busy.
Bottleneck two: heat, for the meetings
This is the one I would have gotten wrong.
The tell was in the symptom description: it got worse as the meeting went on, and it improved when the video streams stopped. A memory ceiling doesn't behave like that. Memory pressure tracks what you have open, not how long you've been in a call.
So I looked at temperature:
$ sensors
Package id 0: +98.0°C (high = +100.0°C, crit = +100.0°C)
Core 0: +98.0°C
Core 1: +97.0°C
Core 2: +94.0°C
Core 3: +92.0°C
fan1: 5113 RPM (min = 0 RPM, max = 4900 RPM)
fan2: 5106 RPM (min = 0 RPM, max = 4900 RPM)
Ninety-eight degrees, two degrees below the critical threshold, with both fans spinning above their own rated maximum — 5113 RPM against a 4900 RPM spec. The cooling system is past the end of its authority and the chip is still cooking. Load average at the time was 5.78 across 8 threads: busy, not extreme.
And the accumulated cost:
$ cat /sys/devices/system/cpu/cpu0/thermal_throttle/package_throttle_total_time_ms
32143829
$ awk '{print int($1)}' /proc/uptime
307274
Roughly nine hours of thermal throttling across 85 hours of uptime — ten percent of the machine's life spent below the speed it advertises.
Now the mechanism is obvious. A video call is one of the heaviest sustained CPU loads a laptop ever sees: continuous encode of your camera, continuous decode of everyone else's, plus audio processing, for the entire duration. On a thermally saturated chip, that load walks the die up to the ceiling over the first few minutes, throttling engages, the frequency drops, the codec misses its real-time deadline, and audio and video start tearing. Everyone kills their camera, the codec load vanishes, the die cools, and it recovers.
Every detail of the complaint is explained, and none of it is memory.
There was a compounding factor in software. My own browser config had this:
# ~/.config/brave-flags.conf
--disable-features=VaapiVideoDecoder,VaapiVideoEncoder
added months earlier for a real reason — a documented VRAM-exhaustion problem on this Optimus machine. The consequence, forgotten since: every video call encodes and decodes in software, on the CPU, on the chip that is already thermally underwater. Hardware video engines exist precisely to keep that work off the cores.
What I ruled out, and how
A diagnosis is only worth something if it also says what it isn't.
The network. The first suspect for a choppy call, and the easiest to test wrong. ICMP was useless here — my ISP drops it:
$ ping -c 3 1.1.1.1 ; ping -c 3 google.com
1.1.1.1: 100% packet loss
google.com: 100% packet loss
A hundred percent loss to every public host, while web traffic worked fine all day. That is a filtered protocol, not a broken link, and reading it as "the internet is down" would have been the wrong turn. The honest measurements:
gateway (WiFi only): 0% loss, avg 2.1 ms, mdev 1.2 ms
TCP handshake to 1.1.1.1:443, ×10:
min 14 ms · avg 14 ms · max 15 ms · jitter 0 ms
Fourteen milliseconds with no measurable jitter. The network is not the problem, and no router, plan, or antenna would have improved a single meeting.
The discrete GPU. The machine has a Quadro M1000M. It contributes nothing:
$ nvidia-smi --query-gpu=memory.used,utilization.gpu --format=csv
2 MiB, 0 %
$ for d in /sys/class/drm/card*-*/; do echo "$(basename $d): $(cat $d/status)"; done
card1-eDP-1: connected (i915 — Intel HD 530)
card1-DP-1: disconnected
card1-HDMI-A-1: disconnected
Every display connector hangs off the Intel GPU. The NVIDIA card owns zero outputs — it is a compute-only Optimus device, sitting at 74°C doing nothing, kept powered on deliberately because dynamic power management used to freeze the machine. It is contributing heat to a chassis that has none to spare, and it will never drive a monitor here. Anyone budgeting monitors around "but it has a dedicated card" would be budgeting around a device that cannot participate.
Two problems, two different fixes
Once the causes are separated, so are the remedies — and they are not the same size.
Heat is a maintenance problem, not a purchase. Fans running past their rated maximum on a decade-old chassis point at dried thermal compound and a dust-loaded heatsink. That is a service, not a component. In my market it runs 300–500 MXN at a shop, or the price of a syringe of paste if you open it yourself. It is the cheapest line item available and it addresses the symptom that actually interrupts paid work.
Memory is a purchase, and it has a ceiling. 2×16 GB DDR4 SODIMM lands the machine at its architectural maximum of 32 GB. In my market that kit is 3,000–4,500 MXN — noticeably more than the equivalent desktop DIMM kit, which starts around 2,222 MXN for the same capacity. Laptop memory carries a premium here that a US price list will not warn you about.
That price gap is the hinge of the whole decision.
The part where the arithmetic changes the plan
I started this expecting to buy a laptop. The numbers argued me out of it, twice.
First: mobile CPUs. The affordable new laptops in my market with eight cores are built on 15-watt parts — Ryzen 7 7730U, 5700U, 5825U. My decade-old i7-6820HQ is a 45-watt chip. Buying one of those would mean more cores with a third of the power budget to feed them; under exactly the sustained load that breaks my meetings, it is not obviously an upgrade at all. The laptops that do carry 35–54 W parts cost roughly twice as much, and they solve the thermal problem the same way mine does: by throttling.
Second: the same money buys more desk than lap. A desktop tower with an eight-core, 65-watt Ryzen 7 5700G, 16 GB and an SSD sells for about 9,363 MXN here. That is less than most of the 15-watt laptops. It sustains its clocks indefinitely, its memory ceiling is 128 GB instead of 32, and it has a PCIe slot, which means a graphics card is a decision I can defer instead of a door that is closed.
So the shape of the fix inverted:
| Role | Machine | What it costs |
|---|---|---|
| Workshop — where the load lives | new tower + RAM | ~11,600 MXN |
| Field — client visits | the 5510, cleaned | 300–500 MXN |
| Bridge | WireGuard + SSH + tmux | already built |
The mobility objection — I visit clients and need my work with me — dissolves once you stop trying to transport the power and start reaching it. The tower stays on a desk and answers over a tunnel; the laptop becomes a terminal with a battery. Sessions keep running when the lid closes. This is not exotic; it is how I already work against a VPS.
Portable desktops do exist, by the way, and they are genuinely appealing: Mini-ITX cases with carry handles — Hyte Revolt 3, Jonsbo C6-ITX, Cooler Master NR200 — that take full desktop parts in about 18 litres. But a client visit means carrying 7–10 kg plus a monitor, keyboard and power brick, with no battery, to do a job a laptop already does. The handle solves the wrong half of the problem.
What the whole fix costs
Prices from my own market, read today, not converted from a US list:
| Item | MXN |
|---|---|
| Tower, Ryzen 7 5700G, 8C/16T, 16 GB, 500 GB SSD | 9,363 |
| RAM to 32 GB — refill free slots / replace the pair | 1,200 / 2,222 |
| UPS with AVR | 1,148 – 1,600 |
| 24" 1080p monitor | 1,439 – 2,300 |
| USB mic + boom arm | 550 – 1,100 |
| Keyboard | ~300 |
| Thermal service on the old laptop | 300 – 500 |
Under fifteen thousand pesos — roughly nine hundred dollars — for a machine that will not throttle, will not swap, drives two monitors natively, and keeps a decade-old laptop alive as the portable half.
Two notes on that table that are easy to get wrong.
The UPS is not optional the way it looks. Moving from laptop to tower means giving up a battery you currently have for free. Today a blackout is a non-event; on a desktop it is an instant power cut with a filesystem underneath it. A line-interactive UPS also does the voltage regulation job that a plain AVR box does, so it replaces two purchases with one. This matters more when there is an air conditioner about to share the panel — a compressor's inrush sags the whole house every time it starts.
And the RAM line has a thousand-peso spread depending on something you cannot know from the product page: whether the machine ships its 16 GB as 2×8 in a two-slot board (you must replace) or in a four-slot board (you can refill, and for the price of replacing you land at 48 GB instead of 32). Ask before you pay. It is the only free upgrade on the list.
What I'd tell someone with the same complaint
Look at the shape of the symptom before you look at the price list.
Degrades over minutes and recovers when the load stops — that is heat. Read sensors and the throttle counters. If the fans are at or past spec and the package is near its critical temperature, no component you can buy will fix it; a cleaning will.
Degrades with what you have open, and the kernel is killing things — that is memory. Read free -h, zramctl and the OOM lines in the kernel journal, then read your firmware's maximum before you shop, because the ceiling may be lower than you want.
Choppy in a call — measure the network before you blame it, and remember that a blocked ICMP looks exactly like a dead link. Use TCP.
Three commands, ten minutes, and the difference between a 400-peso service and a 20,000-peso laptop that would have thermally throttled just like the old one.