Upgrading My Raspberry Pi 5 from microSD to NVMe SSD — Without Reinstalling the OS
How I migrated my existing Raspberry Pi OS to a 256GB NVMe SSD using the Pimoroni NVMe Base, and accidentally disrupted my home network along the way.
Why I decided to upgrade
I’ve been gradually expanding my homelab, and one of the devices I use is a Raspberry Pi 5 with 8GB RAM.
Initially, I was running Raspberry Pi OS Lite from a 128GB microSD card.
It worked fine, but I wanted something better suited for running containers, Kubernetes experiments, monitoring tools, and other self-hosted services.
So I decided to move my operating system to an NVMe SSD.
The goal was simple:
- Keep my existing Raspberry Pi OS installation.
- Preserve installed applications and configurations.
- Move everything from microSD to NVMe.
- Boot directly from the SSD.
- Avoid reinstalling and configuring everything again.
And, ideally, not break anything else in my homelab. 😅
Hardware used
Here’s the setup I used:
Raspberry Pi 5, 8 GB RAM
Original storage 128GB microSD
New storage: 256 GB NVMe SSD,
NVMe adapter: Pimoroni NVMe Base PIM699O
Raspberry Pi OS Lite (64-bit)
The Pimoroni NVMe Base connects to the Raspberry Pi 5’s PCIe interface using a ribbon cable.
One benefit of this setup is that I can keep using the existing OS and migrate it to faster storage.
Step 1: Install the NVMe SSD
First, shut down the Raspberry Pi.
sudo poweroffDisconnect the power supply before installing the NVMe Base.
Install the SSD onto the Pimoroni board, connect the PCIe ribbon cable to the Raspberry Pi 5, and secure the adapter.
Make sure the ribbon cable is properly seated at both ends.
Keep the existing microSD card installed for now.
Power on the Pi normally.
Step 2: Verify that the NVMe SSD is detected
Connect to the Raspberry Pi using SSH or a keyboard and monitor.
Run:
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODELIn my case, the output showed two storage devices:
mmcblk0 119.1G
nvme0n1 238.5Gmmcblk0 was the existing microSD card, while nvme0n1 was the new SSD.
I also checked the PCIe devices:
lspci -nnMy SSD appeared as a MAXIO Technology MAP1202 NVMe controller.That confirmed the adapter and SSD were being detected.
Step 3: Check the Raspberry Pi bootloader
The Raspberry Pi 5 needs a compatible bootloader to boot from NVMe storage.
Check the installed version:
sudo rpi-eeprom-updateI also checked the configured boot order:
sudo rpi-eeprom-configIf the firmware is outdated, update the system and bootloader before migrating.
sudo apt update
sudo apt full-upgrade -yPimoroni recommends Raspberry Pi 5 firmware dated December 6, 2023 or newer for the NVMe Base.
The bootloader version can also be managed through sudo raspi-config.
Step 4: Clone Raspberry Pi OS to the SSD
This was the main part of the migration.
Since I wanted to keep my existing OS, applications, SSH configuration, and other settings, I chose to clone the microSD installation rather than start from scratch.
Before cloning, verify the current root filesystem:
findmnt -no SOURCE /While running from the microSD card, the expected result is:
/dev/mmcblk0p2Important: Back up important data before proceeding. Stop any services that actively write to disk, such as databases, Docker containers, and K3s workloads.
A live block-level clone can capture inconsistent application data. For critical systems, use an offline cloning environment instead.
The cloning command is:
sudo dd if=/dev/mmcblk0 of=/dev/nvme0n1 \
bs=4M status=progress conv=fsyncHere’s what it does:
ifspecifies the source disk (microSD).ofspecifies the destination disk (NVMe).bs=4Msets the copy block size.status=progressshows copying progress.conv=fsyncflushes written data before completion.
Warning: This overwrites the entire destination SSD. Confirm the device names carefully before running it.
After copying, the NVMe contains the OS installation and its boot and root partitions.
Step 5: Configure the Raspberry Pi to boot from NVMe
Next, I configured the boot order.
sudo raspi-configNavigate to:
Get sanjid salam’s stories in your inbox
Join Medium for free to get updates from this writer.
Advanced Options → Boot Order → NVMe/USB Boot
Finish and shut down:
sudo poweroffI removed the original microSD card and powered the Pi back on.
This is an important verification step because it ensures the Raspberry Pi isn’t silently booting from the old microSD card.
It also avoids running with two cloned drives containing duplicate filesystem identifiers.
Step 6: Verify that the OS is running from NVMe
After rebooting, I checked the root filesystem:
findmnt -no SOURCE /The output was:
/dev/nvme0n1p2Success! The Raspberry Pi was now running its OS directly from NVMe storage.
I also checked the partitions:
lsblk -fMy output showed:
nvme0n1
├─nvme0n1p1 vfat bootfs /boot/firmware
└─nvme0n1p2 ext4 rootfs /The operating system and boot partition were both located on the NVMe SSD.
Step 7: Expand the filesystem
When cloning from a smaller card to a larger SSD, the filesystem might initially retain the original storage size.
You can check this with:
df -h /If necessary, use the filesystem expansion option in raspi-config, or carefully grow the root partition and filesystem using appropriate Linux utilities.
In my case, the filesystem expansion was already successful.
My final result:
Filesystem Size Used Avail Use%
/dev/nvme0n1p2 235G 8.2G 217G 4%I now had the full SSD capacity available without reinstalling the OS.
Step 8: Check NVMe health
After completing the migration, I installed NVMe monitoring tools:
sudo apt install -y nvme-cli smartmontoolsThen I checked the SSD health:
sudo nvme smart-log /dev/nvme0n1Some results from my SSD:
The SSD looked healthy.
I also checked PCIe speed:
sudo lspci -vv | grep -E 'LnkCap:|LnkSta:'The SSD was using PCIe Gen 2 ×1 at 5 GT/s, which is normal for Raspberry Pi 5.
PCIe Gen 3 is possible experimentally, but I decided to prioritise stability over maximum speed.
The unexpected problem: My internet stopped working!
The NVMe migration wasn’t the only lesson from this upgrade.
While working on my Raspberry Pi, I suddenly noticed network connectivity problems on my Mac.
At first, I thought something was wrong with my router or internet connection.
Then I remembered how I’d configured my homelab.
I use Tailscale for remote access, and my Raspberry Pi was advertising a subnet route to my home network.
I had disconnected that very Raspberry Pi during the storage upgrade.
My Mac was still connected to Tailscale, but a route it depended on was no longer available.
That explained why parts of my home network were unreachable.
If DNS also depends on resources behind a failed subnet route, even normal internet browsing can appear broken.
The lesson was simple: a device that looks unimportant during maintenance might actually be providing critical network connectivity.
Before taking down a homelab device, check whether it’s acting as a DNS server, subnet router, exit node, reverse proxy, or other shared service.
For a more resilient setup, I want to avoid relying on a single Raspberry Pi for important network routes.
Final results
The storage migration was successful.
- Raspberry Pi OS now boots from NVMe.
- Existing OS configurations were retained.
- Root filesystem uses the larger SSD.
- NVMe SMART health checks look good.
- The original microSD card is available as a recovery option.
And I learned a useful lesson about network dependencies along the way.
What I’d do differently next time
Before performing hardware maintenance, I’d check which services depend on the device.
I’d also make sure I had local network access that didn’t depend on Tailscale and a backup of any important application data.
For anyone running Raspberry Pi devices as part of a homelab, I recommend keeping a simple record of device roles and dependencies.
A storage upgrade is straightforward until the device you’re upgrading turns out to be part of your network infrastructure.
That’s the interesting part of building a homelab. Even small changes teach you something new.
Useful references
- Pimoroni: https://learn.pimoroni.com/article/getting-started-with-nvme-base
- Raspberry Pi documentation: https://www.raspberrypi.com/documentation/
- Tailscale documentation: https://tailscale.com/kb/








