How I Rescued Ubuntu on a USB Pendrive: Fixing High I/O Wait, Stuttering, and Flash Drive Wear

Linux07 Oct 2026

As an engineer working with an older laptop where the internal storage was constrained and couldn't easily be extended or upgraded with a dedicated SSD, I opted for a creative, portable alternative: installing and running a full Ubuntu desktop directly off an external USB 3.0 flash drive (SanDisk 128 GB).

Initially, the experience was great. But over time, the system began to feel sluggish. Windows would hesitate when opening, switching apps felt stuttery, and terminal commands that wrote to disk would stall. Memory and network were completely fine, but the system felt like it was constantly dragging its feet.

Was the pendrive dying? Or was something deeper happening under the hood? Here is how I diagnosed the root causes, the surprising discoveries in kernel logs, and how simple tweaks reduced system load from 7.01 down to 0.49.


1. Diagnosing the Bottleneck: The High I/O Wait Trap

When Linux feels laggy despite low CPU utilization, the first suspect is always I/O Wait (wa). I checked the live system statistics using vmstat:

$ uptime
02:57:25 up 5 min, load average: 7.01, 3.37, 1.38

$ vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 0  7      0 8.4G   120M  3.8G    0    0     0  8752 2605 3286  1  1 64 35  0  0
 1  5      0 8.3G   120M  3.8G    0    0     0  4712 4810 4731  6  1 62 31  0  0

Notice the numbers:

  • Load average was 7.01 just five minutes after boot, despite actual CPU usage being barely 2%!
  • wa (I/O Wait) was hovering between 31% and 35%. One-third of CPU cycles were spent sitting idle waiting for storage blocks to flush.
  • b (Blocked processes) was 5 to 7. Several key threads were frozen in uninterruptible sleep (D state).

Checking the processes trapped in D state revealed the culprit:

$ ps -eo pid,user,stat,comm | grep -E " D"
  356 root D usb-storage
  987 root D kworker/u57:8+flush-8:0
 1115 root D jbd2/sda3-8

The ext4 filesystem journal (jbd2), kernel page flusher, and USB storage driver were all locked up waiting for the flash memory controller to acknowledge writes.


2. The Flash Drive Reality Check

Running a write benchmark with dd and conv=fdatasync showed the harsh reality:

67108864 bytes (64 MiB) copied, 10.79 s, 6.2 MB/s

Sequential write speed was only 6.2 MB/s. For comparison, modern internal SSDs write at 2,000–3,500 MB/s. When an operating system, web browser, and logging daemons write hundreds of small files simultaneously, random 4K write speeds drop below 0.3 MB/s.

Additionally, my /home partition had reached 83% capacity (only 6.3 GB free). Standard USB flash drives use TLC/QLC NAND without TRIM support or DRAM cache. When a thumb drive exceeds 75–80% capacity, the controller runs out of pre-erased blocks. Every single write becomes an agonizing read-erase-write cycle (write amplification).


3. Discovery: The Hidden 10-Second Crash Loop

While checking the systemd journal, I discovered a background service failing repeatedly:

systemd[1]: broadcast-system.service: Failed with result ''exit-code''.
(node)[5798]: broadcast-system.service: Failed at step USER spawning /usr/bin/node: No such process

Due to a small username typo in the service unit file, the service was failing and restarting every 10 seconds indefinitely. Every restart forced systemd to spawn processes and write logs, which constantly triggered ext4 journal syncs on the slow USB drive.


4. The Optimizations That Fixed Everything

A. Leverage Unused RAM with tmpfs

The laptop has 14 GB of RAM, but only ~3.5 GB is actively used. Why commit temporary files, browser caches, and logs to a slow USB flash drive when 10 GB of high-speed RAM is sitting idle?

I added the following entries to /etc/fstab:

tmpfs   /tmp                          tmpfs   defaults,noatime,mode=1777,size=1G            0  0
tmpfs   /var/tmp                      tmpfs   defaults,noatime,size=512M                     0  0
tmpfs   /var/log                      tmpfs   defaults,noatime,size=100M,mode=755            0  0
tmpfs   /home/santhoshreddym/.cache   tmpfs   defaults,noatime,uid=1000,gid=1000,size=2G    0  0

And ensured systemd journal logs stay in memory in /etc/systemd/journald.conf:

[Journal]
Storage=volatile
RuntimeMaxUse=100M

Now, browser caches, thumbnails, and temporary files write to RAM at gigabytes per second, bypassing the USB drive completely.

B. Disabling the Looping Service

sudo systemctl stop broadcast-system.service
sudo systemctl disable broadcast-system.service

C. Reclaiming 9.5 GB by Sweeping Inactive node_modules

Scanning my ~/Documents/Git directory revealed that abandoned node_modules across various projects were consuming nearly 10 GB of space. I removed them all with a single prune command:

find ~/Documents/Git -name "node_modules" -type d -prune -exec rm -rf {} +

This instantly dropped /home usage from 28 GB down to 19 GB.

D. Moving Google Chrome Profile to the Root Partition

Google Chrome profiles take around 3.8 GB across multiple user profiles and service worker storage. Since the root partition (/) had 29 GB of free space while /home was tight, I moved the Chrome directory to /opt and linked it back:

sudo mkdir -p /opt/google-chrome
sudo chown -R $USER: /opt/google-chrome
cp -a ~/.config/google-chrome/. /opt/google-chrome/
rm -rf ~/.config/google-chrome
ln -s /opt/google-chrome ~/.config/google-chrome

This brought /home usage down to 41% (with 22 GB free space)!


5. The Results: Before vs. After

Metric Before Optimization After Optimization Impact
System Load Average 7.01 0.49 14x Reduction
CPU I/O Wait (wa) 16% – 35% 0% Completely Eliminated
Blocked Processes (D state) 5 to 7 0 Zero Stuttering
Write Throughput 6.2 MB/s 9.6 MB/s 55% Faster
/home Space Used 83% (6.3 GB free) 41% (22.0 GB free) +15.7 GB Free Space

Key Takeaways

  1. Flash drives need free headroom: Never let a USB drive without TRIM exceed 75% capacity.
  2. Put high-churn caches in RAM: Mounting ~/.cache and /tmp in tmpfs saves your flash drive from wear and makes desktop apps fly.
  3. Watch out for crash loops: A background service looping every few seconds can quietly bring a slow storage bus to its knees.