Skip to content

[Engine] Windows, RTX 5090 D: engine started from a low-priority process inherits Low I/O priority although CPU class is Normal: PLE reads ~15x slower, decode -14% #4733

Open

Description

@yoinp

Summary

I found that the engine's speed depends on the I/O priority it inherits from the process that launches it. With the CPU priority class forced to Normal, a child of a low-priority launcher still gets I/O priority 1 (Low) (normal: 2). On my machine this made the same engine with the same arguments run decode about 14% slower and cold prompt reads 3-5x slower, with the PLE direct-read probe reporting the drive as slow. Setting the I/O priority back to normal in the launcher removed the whole difference. The memory page priority, which is also inherited low, made no difference.

Environment

Windows 11, RTX 5090 D (32 GB), Ryzen 7 9800X3D, 96 GB DDR5, NVMe, NVFP4 GPTQ pack, engine 0.1.54 (control 0.1.53 server layer), 256K context, same 40 arguments in every run, same boot.

What I measured

The launcher was an AI coding agent's terminal (Below-Normal CPU, I/O 1, page 2). Values read with NtQueryInformationProcess (class 33 = ProcessIoPriority, 39 = ProcessPagePriority). The engine started from that launcher inherits I/O 1 and page 2 even though its CPU class is forced to Normal; the engine started by the desktop app has I/O 2 and page 5.

I then changed the two inherited values one at a time in the launcher process before CreateProcess (NtSetInformationProcess). Same engine, same arguments, same disk, each row a fresh load:

inherited I/O / page priority PLE direct read probe expert load cold prefill 4.6K / 16K / 32K (tok/s) decode, 3,000 tokens x 3 (tok/s)
1 / 2 (as inherited) 8,029 rows/s (warns "measures slow") 4.38 GiB/s 728 / 1,162 / 1,694 128.6, 133.4, 142.3 (avg 134.8)
1 / 5 (page only fixed) 7,763 rows/s (warns) 4.33 GiB/s 741 / 1,146 / 1,788 119.8, 134.6, 139.0 (avg 131.1)
2 / 2 (I/O only fixed) 121,863 rows/s (fine) 4.98 GiB/s 3,145 / 5,042 / 5,762 159.4, 163.0, 159.9 (avg 160.8)
2 / 5 (both fixed) 122,569 rows/s (fine) 4.90 GiB/s 3,175 / 5,045 / 5,776 152.3, 159.4, 159.1 (avg 156.9)

The same engine started by the desktop app (I/O 2, page 5) gives the same numbers as the last two rows. The order of runs was launcher (slow) -> desktop app (fast) -> launcher (slow) -> launcher with the fix (fast), so it is not drift in machine state. A reboot, Windows fast startup off, power plan, fan curve, memory and BIOS settings were checked first and made no difference.

Fix that worked (launcher side)

Before CreateProcess, set the launcher process's own I/O priority back to normal; the child inherits it:

import ctypes
nt = ctypes.windll.ntdll; k = ctypes.windll.kernel32
k.GetCurrentProcess.restype = ctypes.c_void_p
h = ctypes.c_void_p(k.GetCurrentProcess())
v = ctypes.c_ulong(2)                      # ProcessIoPriority = 2 (Normal)
nt.NtSetInformationProcess(h, 33, ctypes.byref(v), 4)

Impact

Any launcher that runs at low priority passes this on: Task Scheduler tasks with the default priority, services, and terminals or scripts started from IDEs or coding agents. Because the engine's own check only looks at the PLE read rate, the symptom shows up as "the drive is slow" (--ple-io direct measures slow here), although the drive is fine. The CPU priority class is the setting people usually check, and it can be Normal while the I/O priority is low.

Suggestion

At start, have the engine (or serve.server) set its own I/O priority to normal, or warn when it reads a low value.

Possibly related

#126 and #3897 describe slow loading when started from Task Scheduler / a Below-Normal host, and #1425 describes slow PLE direct reads on a fast SSD. I have not verified that the cause is the same there; I only mention them in case the inherited I/O priority is worth checking.

Activity

  1. github-actions commented on Oct 30, 2026

    @github-actions

    Thanks for the issue. To keep the tracker readable, every item needs an area prefix in the title and the parts of the issue form filled in. This one is missing:

    • Start the title with its area: [Engine], [GUI], [TUI], [Benchmark], [Docs] or [Other], then a short description. Example: "[Engine] decode stops after 2 minutes".

    Edit the issue (title and description) and this note goes away on its own. If it is still missing parts in 5 days it will be closed, which is not a rejection: fix it and comment /reopen.

    Details: CONTRIBUTING.md

  2. changed the title [-][Windows, RTX 5090] Engine started from a low-priority process inherits Low I/O priority and page priority although CPU class is Normal: PLE reads ~15x slower, decode -14%[/-] [+][Engine] Windows, RTX 5090: engine started from a low-priority process inherits Low I/O priority although CPU class is Normal: PLE reads ~15x slower, decode -14%[/+] on Oct 30, 2026
  3. github-actions commented on Oct 30, 2026

    @github-actions

    Thanks, this follows the format now.

  4. changed the title [-][Engine] Windows, RTX 5090: engine started from a low-priority process inherits Low I/O priority although CPU class is Normal: PLE reads ~15x slower, decode -14%[/-] [+][Engine] Windows, RTX 5090 D: engine started from a low-priority process inherits Low I/O priority although CPU class is Normal: PLE reads ~15x slower, decode -14%[/+] on Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions