Terminal ZSH Performance Issue Under Home Manager - HELP!

New clean DS Nix with standard config running smoothly on MBP early 2015, no complaint.

Until I noticed a slow zsh prompt after every command - not slow loading zsh.
It takes a sec or 2s to display prompt after any simple command (eg. ls)

This zsh is enabled on the home manager instead on configuration.nix because I wanted to add starlight and I don’t know yet what to do in order to have global zsh outcome eval starship.

Testing command time zsh -i -l -c ':' still reasonable (?) .52 real 1.66 user 0.66 sys

There is also some activities info on the terminal’s title bar eg. type -p bash64, bash64, tr type, fzf and others so I went on removing packages on the configuration.nix however it don’t seem to matter.

Some info on system:

  • system: "x86_64-darwin"
  • host os: Darwin 24.1.0, macOS 10.16
  • multi-user?: yes
  • sandbox: no
  • version: nix-env (Nix) 2.24.10
  • channels(root): ""
  • nixpkgs: /nix/store/rxn26bq4xm2p0x4whkp94afhy1g88cm7-source

It’s a clean early 2015, 8GB RAM and 256GB storage, I did patch it though using OpenCore Legacy to install Sequoia which I don’t think have got anything to do with the issue but worth mentioning.

/etc/shells:

# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

# List of shells managed by nix.
/run/current-system/sw/bin/zsh

flake.nix:

{
  description = "Worka's macOS Darwin system flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    nix-darwin = {
      url = "github:LnL7/nix-darwin";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs@{ self, nix-darwin, nixpkgs, home-manager, ... }: 
  {
    # Build darwin flake using:
    # $ darwin-rebuild build --flake .#Workas-MacBook-Pro
    darwinConfigurations."Workas-MacBook-Pro" = nix-darwin.lib.darwinSystem 
    {
      modules = [ 
        ./configuration.nix

	home-manager.darwinModules.home-manager
	{
          # home-manager configuration
	  home-manager.useGlobalPkgs = true;
	  home-manager.useUserPackages = true;
	  home-manager.users.workambp1 = import ./home.nix;
	}
      ];
    };

    # Expose the package set, including overlays, for convenience.
    darwinPackages = self.darwinConfigurations."Workas-MacBook-Pro".pkgs;
  };
}

configuration.nix:

{ config, lib, pkgs, ... }:

{
  # List packages installed in system profile. To search by name, run:
  # $ nix-env -qaP | grep wget
  environment.systemPackages = with pkgs; [
    neovim
    git
  ];

  users.users.workambp1.home = "/Users/workambp1";
  
  # Auto upgrade nix package and the daemon service.
  services.nix-daemon.enable = true;
  
  # Font
  fonts.packages = with pkgs; [
    (nerdfonts.override { fonts = [ "JetBrainsMono" ]; })
  ];

  # nix.package = pkgs.nix;

  # Necessary for using flakes on this system.
  nix.settings.experimental-features = "nix-command flakes";
 
  # Finder settings
  system.defaults.finder = {
    ShowPathbar = true;
  };

  # Dock settings
  system.defaults.dock = {
    autohide = true;
    show-recents = false;
    tilesize = 50;
    magnification = true;
    largesize = 64;
    orientation = "bottom";
    mineffect = "scale";
    launchanim = false;
  };

  # Used for backwards compatibility, please read the changelog before changing.
  # $ darwin-rebuild changelog
  system.stateVersion = 5;

  nix.configureBuildUsers = true;

  # The platform the configuration will be used on.
  nixpkgs.hostPlatform = "x86_64-darwin";
}

home.nix:

{ pkgs, lib, config, ... }:

{
  home.packages = with pkgs; [
    tree
  ];

  home.stateVersion = "24.05";

  # home-manager enable
  programs.home-manager.enable = true;

  # ZSH additional config
 
  # SOURCE OF SLOWNESS - might want to check init
  programs.zsh = {
    enable = true;
    autosuggestion.enable = true;
    syntaxHighlighting.enable = true; 
  };

  # Trying wezterm
  programs.wezterm = {
    enable = true;
    extraConfig = ''
      -- local wezterm = require 'wezterm' <- already added to /Users/workambp1/.config/wezterm/wezterm.lua by hm
      return {
        cursor_blink_rate = 800,
	color_scheme = "Dracula (Official)",
	tab_bar_at_bottom = true,
	window_decorations = "RESIZE",
        front_end = "WebGpu",
        window_background_opacity = 0.9,
        macos_window_background_blur = 10,
	-- Set font to JetBrains Mono
        font = wezterm.font("JetBrainsMono Nerd Font"),
      }
    '';
  };

  # Trying Starship
  programs.starship = {
    enable = true; 
    enableZshIntegration = true;
    settings = {
      add_newline = false;
    };
  };

  # Eza
  programs.eza = {
    enable = false;
    icons = "auto";
    enableZshIntegration = false; 
  };

}

Anyone ever experience this issue? Any thoughts?

TIA

More informations:

workambp1@Workas-MacBook-Pro:~/ > <— prompt SLOW

Running zsh -f is fast
Workas-MacBook-Pro% <— prompt FAST

Using bash
bash-5.2$ <— prompt FAST

Next tried zsh --no-globalrcs
Workas-MacBook-Pro% <— prompt is SLOW.
Does this means the global rc messing with me?

zsh --sourcetrace

+/nix/store/8r2knnwn6lmadga51494xhgh41yj51d4-zsh-5.9/etc/zshenv:1> <sourcetrace>
+/etc/zshenv:1> <sourcetrace>
+/Users/workambp1/.zshenv:1> <sourcetrace>
+/etc/profiles/per-user/workambp1/etc/profile.d/hm-session-vars.sh:1> <sourcetrace>
+/etc/zshrc:1> <sourcetrace>
+/Users/workambp1/.zcompdump:1> <sourcetrace>
+/Users/workambp1/.zshrc:1> <sourcetrace>
+/Users/workambp1/.zcompdump:1> <sourcetrace>
+/nix/store/7khagfdmv8v27q34khnhdhnyb2cwnfcl-wezterm-20240203-110809-5046fc22/etc/profile.d/wezterm.sh:1> <sourcetrace>

etc/profile.d/ > tree
.
└── nix.sh

and the content of nix.sh

# Nix
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
    . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi
# End Nix

Is the perf issue happening under other term emulators or just wezterm?

Same thing happened with Terminal (one from mac os). I don’t have other terminals emulators installed.

Edit
I enabled alacritty just to make sure and yeah, prompt in it still SLOW. My bad habit is to press enter key several times while thinking :slight_smile: and the delay is unbearable…

Does this slowness still happen when you disable starship?

Yes, it persisted.
Even bare bone zsh install is SLOW.
It only occurs only when enabling zsh via home manager.

If it globally enabled via configuration.nix above, it runs fast as usual.
But I have no idea yet how to apply starship to a global zsh.

The output can be tedious to read through, but I’d just run set -x and see what’s running. If it’s not easy to spot one obvious spot it hangs, you can also tweak your PS4 to print a timestamp on each line.

I am a noob in this area. Never used a mac or linux before. Maybe ssh-ing to a project infra and that’s it. Care to elaborate some more details?

Is this what you mean?

log_with_timestamp:1> local message='Checking if Zsh is loaded...'
+log_with_timestamp:2> date '+%Y-%m-%d %H:%M:%S'
+log_with_timestamp:2> local timestamp='2024-11-10 22:23:04'
+log_with_timestamp:3> echo '2024-11-10 22:23:04 - Checking if Zsh is loaded...'
2024-11-10 22:23:04 - Checking if Zsh is loaded...
+./test.zsh:16> [[ /bin/zsh == *zsh* ]]
+./test.zsh:17> log_with_timestamp 'Zsh is successfully loaded!'
+log_with_timestamp:1> local message='Zsh is successfully loaded!'
+log_with_timestamp:2> date '+%Y-%m-%d %H:%M:%S'
+log_with_timestamp:2> local timestamp='2024-11-10 22:23:05'
+log_with_timestamp:3> echo '2024-11-10 22:23:05 - Zsh is successfully loaded!'
2024-11-10 22:23:05 - Zsh is successfully loaded!
+./test.zsh:23> log_with_timestamp 'Shell version:'
+log_with_timestamp:1> local message='Shell version:'
+log_with_timestamp:2> date '+%Y-%m-%d %H:%M:%S'
+log_with_timestamp:2> local timestamp='2024-11-10 22:23:05'
+log_with_timestamp:3> echo '2024-11-10 22:23:05 - Shell version:'
2024-11-10 22:23:05 - Shell version:
+./test.zsh:24> zsh --version
zsh 5.9 (x86_64-apple-darwin24.0.0)
+./test.zsh:27> log_with_timestamp 'Current Zsh environment variables:'
+log_with_timestamp:1> local message='Current Zsh environment variables:'
+log_with_timestamp:2> date '+%Y-%m-%d %H:%M:%S'
+log_with_timestamp:2> local timestamp='2024-11-10 22:23:05'
+log_with_timestamp:3> echo '2024-11-10 22:23:05 - Current Zsh environment variables:'
2024-11-10 22:23:05 - Current Zsh environment variables:
+./test.zsh:28> env
+./test.zsh:28> grep ZSH
__HM_ZSH_SESS_VARS_SOURCED=1
+./test.zsh:31> log_with_timestamp 'Current shell prompt: ./test.zsh'
+log_with_timestamp:1> local message='Current shell prompt: ./test.zsh'
+log_with_timestamp:2> date '+%Y-%m-%d %H:%M:%S'
+log_with_timestamp:2> local timestamp='2024-11-10 22:23:05'
+log_with_timestamp:3> echo '2024-11-10 22:23:05 - Current shell prompt: ./test.zsh'
2024-11-10 22:23:05 - Current shell prompt: ./test.zsh
+./test.zsh:34> whoami
+./test.zsh:34> log_with_timestamp 'Current user: workambp1'
+log_with_timestamp:1> local message='Current user: workambp1'
+log_with_timestamp:2> date '+%Y-%m-%d %H:%M:%S'
+log_with_timestamp:2> local timestamp='2024-11-10 22:23:05'
+log_with_timestamp:3> echo '2024-11-10 22:23:05 - Current user: workambp1'
2024-11-10 22:23:05 - Current user: workambp1
+./test.zsh:35> pwd
+./test.zsh:35> log_with_timestamp 'Current directory: /Users/workambp1/test'
+log_with_timestamp:1> local message='Current directory: /Users/workambp1/test'
+log_with_timestamp:2> date '+%Y-%m-%d %H:%M:%S'
+log_with_timestamp:2> local timestamp='2024-11-10 22:23:05'
+log_with_timestamp:3> echo '2024-11-10 22:23:05 - Current directory: /Users/workambp1/test'
2024-11-10 22:23:05 - Current directory: /Users/workambp1/test
+./test.zsh:38> set +x
workambp1@Workas-MacBook-Pro:~/test/ >

I noticed that they all are within the 22:23:04~05 should be acceptable?
It’s the delay AFTER commands are executed that irks me. The prompt should be displayed instantaneously except it’s not.

Screen Recording 2024-11-10 at 22.32.33-2

Hi @jakdev , I just faced the same issue with a similar setup (home manager + wezterm + zsh) and managed to fix it.

The issue comes from the wezterm shell integrations that is slowing each command by setting user var and other pre and post operations.

Wezterm Shell Integration

The enableZshIntegration and enableBashIntegration are set to true by default in the wezterm nixos options so simply setting them to false will solve the issue.

Wezterm Nixos Options

Thanks to @abathur for the set -x that helped me after a lot of troubleshooting.

2 Likes