Home Assistant on the Pi 3B: Keeping It Reliable

The network is laid out, the Pi has a reserved address at 192.168.1.21, and the device integrations are planned. Time to actually install the thing.

This post covers installing Home Assistant OS on a Pi 3B and the specific tweaks that matter for getting reliable, long-term operation out of hardware that is, frankly, a bit underpowered for the job. If you're on a Pi 4 or newer most of this still applies, but the Pi 3B needs more care.


What You Need

  • Raspberry Pi 3B (or 3B+)
  • A USB drive or SSD — strongly recommended over a microSD card (more on this below)
  • Ethernet cable — skip WiFi for a server
  • Another computer to flash the image from

SD card vs USB storage

The Pi 3B's Achilles heel for server use is the microSD slot. Home Assistant writes to its database constantly — sensor history, state changes, logs. SD cards are not designed for this write pattern and will fail within months to a couple of years under HA's workload. A USB-connected SSD or flash drive lasts orders of magnitude longer and is significantly faster.

The Pi 3B does not boot from USB by default. You need to set a one-time OTP (one-time programmable) bit first. Instructions are in the next section.


Identifying Your Pi Model

The steps below only apply to the Pi 3B. The 3B+ has USB boot enabled from the factory and can skip ahead to flashing.

The easiest way to tell them apart is the PCB label on the underside of the board — it will read either Raspberry Pi 3 Model B or Raspberry Pi 3 Model B+. Physically, the 3B+ has a silver metal heat spreader over the CPU; the 3B has a bare black chip. The 3B+ also has a 4-pin PoE header next to the ethernet port that the 3B lacks.

If the Pi is already running an OS:

cat /proc/cpuinfo | grep Revision
# a020d3 = 3B+   |   a02082 / a22082 = 3B

Enabling USB Boot on the Pi 3B

This only needs to be done once and permanently enables USB boot.

Boot the Pi from any Raspberry Pi OS SD card (the Lite image is fine), then run:

echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
sudo reboot

After the reboot, verify the OTP bit is set:

vcgencmd otp_dump | grep 17:
# Should output: 17:3020000a

The last digit of 17: changes from 0 to a when USB boot is enabled. Once confirmed, the SD card is no longer needed and you can flash HAOS directly to the USB drive.

Pi 3B+ note: USB boot is enabled from the factory — skip this section and go straight to flashing.


Flashing Home Assistant OS

Download the Raspberry Pi 3 image from the Home Assistant installation page. Make sure to pick the 64-bit image — the 32-bit image has been deprecated and misses performance improvements in recent HAOS releases.

Flash it to your USB drive using the Raspberry Pi Imager:

# Arch / Manjaro
sudo pacman -S rpi-imager

# Ubuntu / Debian
sudo apt install rpi-imager

Launch it, choose Use custom image, select the downloaded .img.xz file, and write it to your USB drive. No decompression needed — the imager handles it.

Alternatively with dd if you prefer:

xz -d haos_rpi3-64-XX.X.img.xz
sudo dd if=haos_rpi3-64-XX.X.img of=/dev/sdX bs=4M status=progress conv=fsync

Replace /dev/sdX with your USB drive's device path — double-check this with lsblk before running.


First Boot

Plug the USB drive into the Pi, connect ethernet, and power it on. The first boot takes 5–10 minutes as HAOS expands the filesystem and starts all services.

Once it's up, navigate to http://192.168.1.21:8123 in a browser (or http://homeassistant.local:8123 if mDNS works on your network). You'll be greeted by the onboarding wizard.

Work through it:

  1. Create your account — this becomes the owner account. Use a strong password; this account has full admin access.
  2. Name your home and set the location — used for sun-based automations.
  3. Select your unit system and currency — harder to change later than you'd think.
  4. Skip the automatic device discovery for now — let the system settle before adding integrations.

Essential Add-ons

Add-ons are managed under Settings → Add-ons. Install these before anything else.

Studio Code Server (VS Code in the browser)

The single most useful add-on. Gives you a full VS Code interface for editing configuration.yaml and all other config files, with YAML validation and Home Assistant syntax highlighting.

Install it, then in its configuration set:

{
  "ssl": false,
  "certfile": "fullchain.pem",
  "keyfile": "privkey.pem"
}

Set ssl: false unless you have a certificate set up — otherwise the UI won't load.

SSH & Web Terminal

Gives you SSH access and an in-browser terminal. Essential for debugging and running HA CLI commands.

After installing, set a password in the add-on configuration and enable it on port 22. Then from any machine on the network:

ssh root@192.168.1.21

Samba share

Exposes the /config directory as a network share. Useful for editing config files from your desktop and for copying backups off the Pi.


Installing HACS

HACS (Home Assistant Community Store) is the package manager for community integrations, Lovelace cards, and themes. Most of the best integrations for real-world devices are only available through HACS.

Install it via the terminal:

wget -O - https://get.hacs.xyz | bash -

Then restart Home Assistant and add the HACS integration under Settings → Integrations → Add Integration → HACS. You'll need to authenticate with a GitHub account.


Pi 3B Optimisations

This is where the Pi 3B needs specific attention. The defaults are tuned for more capable hardware.

1. Move the recorder database off the SD card

If you're on a USB SSD this is already handled. If you're still on SD for any reason, or if you want the database on a separate partition, configure the recorder to write elsewhere:

# configuration.yaml
recorder:
  db_url: sqlite:////media/usb/home-assistant_v2.db

Point it at whatever path your USB storage is mounted at. Check the mount point under Settings → System → Storage.

2. Reduce recorder history retention

The default retention period is 10 days of full state history. On a Pi 3B that means a growing SQLite database that makes the UI sluggish when loading history graphs and slows down HA startup.

Reduce it:

recorder:
  purge_keep_days: 3
  commit_interval: 30
  exclude:
    domains:
      - automation
      - script
      - scene
    entity_globs:
      - sensor.*_signal_strength
      - sensor.*_rssi
      - sensor.*_lqi

commit_interval: 30 batches database writes every 30 seconds instead of continuously, which reduces SD/USB write pressure significantly. exclude stops recording entities that produce lots of data but that you'll never look at historically — signal strength sensors are particularly noisy.

3. Disable unused integrations at startup

HA loads a large number of built-in integrations by default, even if you're not using them. Disable the ones you don't need in configuration.yaml:

default_config:

# Remove components you don't use
# Comment out or add to this list
homeassistant:
  customize: !include customize.yaml

# Explicitly disable unused domains
stream:  # only needed for camera streams
  # comment the whole block to disable

mobile_app:  # only needed if using the HA mobile app

The more surgical approach is to not use default_config: at all and only list what you actually need — but that's a bigger undertaking once you're set up. Disabling the heaviest unused components (stream, camera, media_player if unused) gives a measurable reduction in idle RAM.

4. Limit the logbook

The logbook records every state change for display in the UI. On an active system it grows quickly and is expensive to render. Either disable it entirely or exclude chatty entities:

logbook:
  exclude:
    domains:
      - automation
      - script
    entity_globs:
      - sensor.*_signal_strength
      - binary_sensor.*_motion  # if motion sensors fire constantly

To disable it completely: remove logbook: from configuration.yaml and add logbook to the default_config exclusion list.

5. Set a lower log level

The default log level is warning for most components, but some integrations are verbose. If you notice the system log filling up quickly:

logger:
  default: warning
  logs:
    homeassistant.components.recorder: error
    homeassistant.components.http: error

This doesn't affect functionality — it just stops HA writing log entries you'll never read.

6. Enable ZRAM

ZRAM creates a compressed swap area in RAM, which helps when the Pi's 1GB gets tight. In HAOS this is configured through the Supervisor:

In the SSH terminal, run:

ha os info

HAOS 10+ enables ZRAM by default. If you're on an older release, update HAOS first via Settings → System → Updates.

7. Keep add-ons lean

On a Pi 3B, every running add-on costs RAM. A rough guide to what each costs at idle:

Add-on Approx. RAM
Studio Code Server ~80MB
SSH & Web Terminal ~20MB
Mosquitto Broker ~15MB
ESPHome ~120MB
Node-RED ~150MB
InfluxDB ~180MB

HAOS itself with a modest config uses 500–650MB. Running HAOS + Mosquitto + ESPHome + Node-RED simultaneously on 1GB puts you at or over capacity.

Recommendation: Stop the ESPHome add-on when you're not actively flashing devices. Don't run InfluxDB + Grafana on the Pi 3B — offload that to another machine or wait until you upgrade hardware.


Backups

Home Assistant's built-in backup system creates full snapshots of your config, add-ons, and data. Configure automatic backups under Settings → System → Backups.

The snapshots are stored on the Pi itself though — useless if the drive dies. Get them off the Pi automatically by adding a backup location. The easiest option with the Samba add-on already running:

  1. Go to Settings → System → Backups → Add Backup Location
  2. Choose Network Storage and point it at a share on another machine on 192.168.1.x

Alternatively, sync backups to the cloud using the same rclone setup from the cloud sync post — the HA backup directory is at /backup/ on the Pi and accessible via the Samba share.


Verifying the Setup

Once everything is configured, check the system health:

Settings → System → Repairs — flags any configuration issues HA has detected.

Settings → System → System Health — shows memory, disk usage, database size, and version info. On a healthy Pi 3B with the optimisations above you should see:

  • RAM usage under 75%
  • Database size under 500MB after a few days
  • No errors in the Repairs panel

From the SSH terminal, you can also run the HA CLI directly:

# Check overall system info
ha info

# Check supervisor status
ha supervisor info

# Force a database purge immediately
ha core check
sqlite3 /config/home-assistant_v2.db "SELECT page_count * page_size / 1024 / 1024 as size_mb FROM pragma_page_count(), pragma_page_size();"

What's Next

With HAOS running and the Pi stable, the next steps are:

  1. Add the device integrations — Brilliant switches via LocalTuya, Xiaomi fan via syssi/xiaomi_fan, and the Panasonic heat pump via panasonic_cc. All covered in the device integrations post.
  2. Set up automations — the point of all this.
  3. Consider a hardware upgrade — the Pi 3B will run this setup, but a Pi 4 (4GB) or an Intel N100 mini-PC removes every constraint listed above. When the Pi 3B starts struggling under the load of a growing system, that's the natural next step.