zgx performance · macOS · 2026-10-26

zgx uses the least CPU in 10 of 10 tests and the least GPU power in 9, against GPUI Fast, MyGo and Rune.

zgx against GPUI Fast (Zed's GPUI with its fast-path optimizations, as apps ship it) MyGo (a Go desktop framework, through its GPU-drawn native UI) and Rune (Rust, wgpu, Taffy and Parley): the same four scenes, built from the same workload code, measured on one Mac in one session. Lower is better throughout.

CPU, heavy dashboard (both)
6.6%51% less than GPUI Fast, 56% less than MyGo, 69% less than Rune
GPU power, heavy dashboard (both)
154 mW8% less than GPUI Fast, 32% less than MyGo, 68% less than Rune
long frames (over 25 ms), at most
0.2%median of each mode's captures, every scene; GPUI Fast, MyGo and Rune: up to 20.3%
CPU while idle
0.00%GPUI Fast 0.42%, MyGo 0.00%, Rune 0.00%

Heavy dashboard

A 1280×800 dashboard: 6 tiles, 30 cards of 26 sparkline bars, a status table and a log. Most values change 60 times a second; the table scrolls. Raw data

CPU % of one core lower is better
ModeFrameworkMedian (range)
Idlezgx0.00
GPUI Fast0.42 (0.41–0.42)
MyGo0.00
Rune0.00
Streamingzgx6.3 (6.1–6.4)
GPUI Fast13.3 (12.5–13.6)
MyGo14.8 (14.8–15.4)
Rune18.3 (17.5–18.7)
Scrollingzgx2.7 (2.4–2.8)
GPUI Fast7.2 (6.6–7.8)
MyGo12.7 (11.6–13.1)
Rune17.9 (17.6–18.6)
Bothzgx6.6 (5.8–7.0)
GPUI Fast13.3 (11.8–14.6)
MyGo15.1 (14.8–15.4)
Rune21.2 (20.9–21.5)
WindowServer CPU % of one core: the system compositor, while the app runs (the desktop alone: 0.3) lower is better
ModeFrameworkMedian (range)
Idlezgx4.3 (3.4–5.2)
GPUI Fast0.3
MyGo2.0 (0.3–3.7)
Rune3.2 (0.2–6.1)
Streamingzgx10.4 (10.3–10.8)
GPUI Fast10.2 (10.0–14.2)
MyGo11.3 (11.0–12.3)
Rune9.9 (9.9–10.0)
Scrollingzgx10.7 (10.1–11.4)
GPUI Fast9.9 (9.8–10.0)
MyGo11.1 (10.6–11.5)
Rune10.0 (9.9–10.0)
Bothzgx10.6 (10.5–10.7)
GPUI Fast10.0 (9.8–11.4)
MyGo11.1 (11.1–11.2)
Rune9.8 (9.8–10.0)
GPU power mW, the whole GPU (the window server's compositing included), less the desktop alone (0.6 mW) lower is better
ModeFrameworkMedian (range)
Streamingzgx128.3 (127.5–129.5)
GPUI Fast166.9 (166.0–178.4)
MyGo225.8 (224.9–228.6)
Rune488.0 (480.7–491.0)
Scrollingzgx82.9 (81.6–87.4)
GPUI Fast166.9 (164.2–168.9)
MyGo115.5 (113.9–116.4)
Rune490.1 (487.4–491.6)
Bothzgx154.5 (153.4–154.7)
GPUI Fast167.5 (165.9–171.5)
MyGo226.7 (226.1–228.7)
Rune489.3 (479.3–489.5)
App GPU time million GPU cycles a second, the app's own; includes per-frame wake latency lower is better
ModeFrameworkMedian (range)
Streamingzgx17.2 (17.2–17.5)
GPUI Fast22.0 (21.9–22.1)
MyGo25.8 (24.9–26.1)
Rune46.1 (45.5–46.3)
Scrollingzgx12.6 (12.3–12.7)
GPUI Fast22.4 (22.3–22.5)
MyGo17.0 (16.3–17.5)
Rune46.0 (46.0–46.2)
Bothzgx19.2 (19.1–19.6)
GPUI Fast22.0 (21.6–22.3)
MyGo26.0 (25.4–26.2)
Rune46.2 (44.9–46.3)
Frame time, 99th percentile ms between frames lower is better
ModeFrameworkMedian (range)
Streamingzgx18.6 (17.9–21.1)
GPUI Fast25.3 (25.2–25.3)
MyGo21.3 (17.8–25.6)
Rune25.3 (18.5–35.4)
Scrollingzgx17.9 (17.8–20.3)
GPUI Fast25.0 (24.9–25.4)
MyGo20.1 (18.3–25.5)
Rune19.0 (18.8–24.1)
Bothzgx17.8 (17.7–18.1)
GPUI Fast25.4 (25.3–25.6)
MyGo20.9 (20.6–25.2)
Rune22.0 (19.5–33.6)
Long frames % of frames over 25 ms lower is better
ModeFrameworkMedian (range)
Streamingzgx0.0
GPUI Fast2.9 (2.4–3.8)
MyGo0.4 (0.0–3.5)
Rune2.8 (0.0–11.0)
Scrollingzgx0.0 (0.0–0.2)
GPUI Fast0.6 (0.6–2.9)
MyGo0.2 (0.0–3.5)
Rune0.0 (0.0–0.2)
Bothzgx0.0
GPUI Fast3.3 (2.9–3.4)
MyGo0.2 (0.2–1.6)
Rune0.4 (0.2–11.0)
Memory MB, physical footprint lower is better
ModeFrameworkMedian (range)
Idlezgx53
GPUI Fast71
MyGo69 (66–73)
Rune75
Streamingzgx264
GPUI Fast264 (264–281)
MyGo308 (307–308)
Rune478 (477–479)
Scrollingzgx260
GPUI Fast263 (263–274)
MyGo297 (297–298)
Rune632 (631–634)
Bothzgx265 (265–266)
GPUI Fast265 (265–278)
MyGo308 (307–308)
Rune630 (630–631)

Text and a 100,000-row list

A streaming transcript beside a 100,000-row virtual list, updated 60 times a second. Raw data

CPU % of one core lower is better
ModeFrameworkMedian (range)
Streamingzgx2.5 (2.2–2.5)
GPUI Fast5.0 (4.7–5.2)
MyGo7.2 (7.0–7.3)
Rune6.0 (6.0–6.4)
Scrollingzgx2.2 (2.2–2.3)
GPUI Fast4.0 (3.5–4.2)
MyGo5.3 (5.3–5.8)
Rune5.8 (5.6–6.4)
Bothzgx2.8 (2.6–2.8)
GPUI Fast5.3 (4.8–5.5)
MyGo7.7 (7.3–7.8)
Rune6.8 (6.3–7.2)
WindowServer CPU % of one core: the system compositor, while the app runs (the desktop alone: 0.8) lower is better
ModeFrameworkMedian (range)
Streamingzgx10.5 (10.4–13.8)
GPUI Fast10.3 (9.7–12.5)
MyGo11.5 (10.8–14.1)
Rune10.3 (9.6–12.6)
Scrollingzgx10.6 (10.3–13.8)
GPUI Fast10.3 (9.4–13.3)
MyGo11.0 (11.0–13.2)
Rune10.4 (9.6–10.5)
Bothzgx10.5 (10.4–10.6)
GPUI Fast9.6 (9.4–10.0)
MyGo10.9 (10.9–11.0)
Rune9.7 (9.6–10.7)
GPU power mW, the whole GPU (the window server's compositing included), less the desktop alone (0.9 mW) lower is better
ModeFrameworkMedian (range)
Streamingzgx58.5 (57.0–58.6)
GPUI Fast108.2 (107.1–109.7)
MyGo68.9 (68.8–69.1)
Rune309.8 (303.0–315.2)
Scrollingzgx61.6 (61.4–62.4)
GPUI Fast106.1 (105.7–107.4)
MyGo98.0 (97.9–99.3)
Rune306.1 (301.3–307.0)
Bothzgx67.1 (66.6–67.5)
GPUI Fast108.3 (107.4–108.6)
MyGo105.2 (104.1–105.6)
Rune315.4 (309.5–319.0)
App GPU time million GPU cycles a second, the app's own; includes per-frame wake latency lower is better
ModeFrameworkMedian (range)
Streamingzgx11.8 (11.5–11.9)
GPUI Fast18.4 (18.1–18.7)
MyGo12.4 (12.4–12.5)
Rune33.7 (33.0–34.3)
Scrollingzgx12.7 (12.3–12.9)
GPUI Fast18.4 (17.4–18.6)
MyGo15.8 (15.6–15.8)
Rune33.4 (32.3–33.6)
Bothzgx13.2 (13.1–13.7)
GPUI Fast18.8 (18.7–18.9)
MyGo16.7 (16.5–16.7)
Rune33.9 (33.8–34.5)
Frame time, 99th percentile ms between frames lower is better
ModeFrameworkMedian (range)
Streamingzgx18.3 (17.8–18.3)
GPUI Fast23.3 (18.4–25.0)
MyGo25.0 (17.7–25.1)
Rune33.5 (31.1–34.1)
Scrollingzgx18.2 (18.1–18.5)
GPUI Fast18.3 (17.9–18.4)
MyGo25.1 (17.6–25.2)
Rune34.0 (33.8–35.2)
Bothzgx18.9 (18.3–21.4)
GPUI Fast18.5 (18.2–19.6)
MyGo18.0 (17.5–25.2)
Rune35.0 (26.6–39.1)
Long frames % of frames over 25 ms lower is better
ModeFrameworkMedian (range)
Streamingzgx0.0
GPUI Fast0.8 (0.2–1.0)
MyGo0.8 (0.0–1.6)
Rune10.9 (10.4–12.8)
Scrollingzgx0.0 (0.0–0.2)
GPUI Fast0.2 (0.0–0.2)
MyGo1.2 (0.0–1.6)
Rune16.2 (9.6–19.7)
Bothzgx0.0 (0.0–0.2)
GPUI Fast0.4 (0.2–0.4)
MyGo0.0 (0.0–2.8)
Rune20.3 (5.5–23.1)
Memory MB, physical footprint lower is better
ModeFrameworkMedian (range)
Streamingzgx243 (242–244)
GPUI Fast246 (246–256)
MyGo272
Rune424 (421–432)
Scrollingzgx241
GPUI Fast248 (243–255)
MyGo262
Rune428 (419–430)
Bothzgx243 (243–244)
GPUI Fast246 (246–247)
MyGo272 (271–272)
Rune432 (432–433)

Animation

48 blinking dots and a shimmering line of text, animated on every refresh of a 120 Hz display. Raw data

CPU % of one core lower is better
ModeFrameworkMedian (range)
Animatingzgx3.7 (3.7–3.8)
GPUI Fast5.9 (5.5–5.9)
MyGo7.2 (7.1–7.2)
Rune7.0 (6.9–7.5)
WindowServer CPU % of one core: the system compositor, while the app runs (the desktop alone: 0.7) lower is better
ModeFrameworkMedian (range)
Animatingzgx18.1 (18.1–18.3)
GPUI Fast21.1 (18.3–21.2)
MyGo23.4 (22.9–26.5)
Rune20.4 (17.8–21.6)
GPU power mW, the whole GPU (the window server's compositing included), less the desktop alone (1.0 mW) lower is better
ModeFrameworkMedian (range)
Animatingzgx122.1 (117.9–125.4)
GPUI Fast146.5 (144.6–146.9)
MyGo116.0 (111.8–121.7)
Rune300.7 (294.6–304.6)
App GPU time million GPU cycles a second, the app's own; includes per-frame wake latency lower is better
ModeFrameworkMedian (range)
Animatingzgx23.0 (22.9–23.0)
GPUI Fast30.1 (29.8–30.1)
MyGo23.4 (23.1–23.5)
Rune43.8 (43.8–43.9)
Frame time, 99th percentile ms between frames lower is better
ModeFrameworkMedian (range)
Animatingzgx14.5 (13.8–15.3)
GPUI Fast17.3 (13.0–17.8)
MyGo17.7 (12.7–17.8)
Rune17.4 (17.4–27.0)
Long frames % of frames over 25 ms lower is better
ModeFrameworkMedian (range)
Animatingzgx0.0 (0.0–0.1)
GPUI Fast0.0
MyGo0.0
Rune0.0 (0.0–1.1)
Memory MB, physical footprint lower is better
ModeFrameworkMedian (range)
Animatingzgx241 (240–241)
GPUI Fast253
MyGo263 (263–264)
Rune426 (423–426)

Variable-height list

100,000 chat rows of wrapped text, 1 to 8 lines each, about one in four with an image, in each framework's own list widget, which measures the rows: scrolled steadily, flung, and scrolled with a jump to a far row every half second. Raw data

CPU % of one core lower is better
ModeFrameworkMedian (range)
Scrollingzgx2.5 (2.4–2.5)
zgx (Luau)2.6 (2.5–2.6)
GPUI Fast4.7 (4.3–4.9)
MyGo8.9 (8.1–9.2)
Rune7.4 (6.9–7.7)
Flingingzgx2.7 (2.3–2.8)
zgx (Luau)2.7 (2.6–2.8)
GPUI Fast4.8 (4.7–5.0)
MyGo9.4 (8.0–9.9)
Rune8.3 (7.6–8.3)
Jumpingzgx2.7 (2.7–2.9)
zgx (Luau)2.8 (2.7–2.8)
GPUI Fast5.2 (4.8–5.3)
MyGo10.0 (9.4–10.4)
Rune9.6 (9.5–10.1)
WindowServer CPU % of one core: the system compositor, while the app runs (the desktop alone: 0.2) lower is better
ModeFrameworkMedian (range)
Scrollingzgx10.3 (10.2–10.3)
zgx (Luau)10.4 (10.3–10.5)
GPUI Fast9.6 (9.4–9.9)
MyGo11.3 (11.2–11.3)
Rune9.8 (9.7–9.9)
Flingingzgx10.4 (10.1–10.8)
zgx (Luau)10.4 (10.3–10.9)
GPUI Fast10.8 (10.5–11.2)
MyGo11.4 (11.1–13.0)
Rune9.9 (9.9–10.0)
Jumpingzgx10.3 (10.0–10.5)
zgx (Luau)10.2 (10.1–10.3)
GPUI Fast9.6 (9.4–9.9)
MyGo11.2 (11.1–11.3)
Rune9.5 (9.5–9.6)
GPU power mW, the whole GPU (the window server's compositing included), less the desktop alone (0.8 mW) lower is better
ModeFrameworkMedian (range)
Scrollingzgx60.5 (58.8–60.9)
zgx (Luau)61.3 (59.1–61.5)
GPUI Fast89.7 (87.7–90.3)
MyGo94.9 (94.5–95.1)
Rune246.1 (243.3–247.0)
Flingingzgx60.7 (59.5–62.6)
zgx (Luau)61.4 (59.2–62.3)
GPUI Fast90.6 (89.6–92.7)
MyGo95.8 (93.3–98.0)
Rune248.7 (241.9–249.0)
Jumpingzgx62.1 (60.3–62.3)
zgx (Luau)61.3 (59.8–61.9)
GPUI Fast89.6 (88.8–91.0)
MyGo95.7 (94.4–98.4)
Rune244.6 (244.0–248.6)
App GPU time million GPU cycles a second, the app's own; includes per-frame wake latency lower is better
ModeFrameworkMedian (range)
Scrollingzgx13.2 (12.9–13.4)
zgx (Luau)13.2 (13.2–13.3)
GPUI Fast17.2 (17.0–17.4)
MyGo15.9 (15.9–16.0)
Rune29.4 (29.3–29.5)
Flingingzgx13.4 (13.2–13.5)
zgx (Luau)13.2 (13.1–13.4)
GPUI Fast17.1 (16.9–17.1)
MyGo15.9 (15.0–16.1)
Rune29.3 (29.2–29.3)
Jumpingzgx13.2 (13.0–13.5)
zgx (Luau)13.2 (13.1–13.3)
GPUI Fast17.2 (17.2–17.3)
MyGo15.8 (15.3–16.1)
Rune29.4 (29.3–29.5)
Frame time, 99th percentile ms between frames lower is better
ModeFrameworkMedian (range)
Scrollingzgx18.1 (17.9–18.4)
zgx (Luau)18.2 (17.7–18.8)
GPUI Fast17.7 (17.5–18.2)
MyGo18.1 (18.0–19.4)
Rune25.4 (25.4–34.3)
Flingingzgx18.2 (18.1–20.8)
zgx (Luau)18.4 (18.2–18.5)
GPUI Fast19.0 (18.6–23.5)
MyGo18.5 (17.8–25.2)
Rune35.3 (25.6–41.1)
Jumpingzgx18.4 (17.9–18.4)
zgx (Luau)18.8 (18.5–19.0)
GPUI Fast18.6 (17.7–18.8)
MyGo20.6 (18.2–25.4)
Rune34.0 (33.3–40.8)
Long frames % of frames over 25 ms lower is better
ModeFrameworkMedian (range)
Scrollingzgx0.0
zgx (Luau)0.0 (0.0–0.2)
GPUI Fast0.0 (0.0–0.2)
MyGo0.0 (0.0–0.2)
Rune2.7 (2.0–21.3)
Flingingzgx0.2 (0.0–0.2)
zgx (Luau)0.0
GPUI Fast0.2 (0.0–0.6)
MyGo0.4 (0.2–3.4)
Rune17.6 (4.6–19.1)
Jumpingzgx0.0 (0.0–0.2)
zgx (Luau)0.0
GPUI Fast0.2 (0.0–0.2)
MyGo0.4 (0.0–2.1)
Rune15.9 (7.4–18.3)
Unfilled rows % of window captures showing a gap lower is better
ModeFrameworkMedian (range)
Scrollingzgx0.0
zgx (Luau)0.0
GPUI Fast0.0
MyGo0.0
Rune0.0
Jumpingzgx0.0
zgx (Luau)0.0
GPUI Fast0.0
MyGo0.0
Rune0.0
Memory MB, physical footprint lower is better
ModeFrameworkMedian (range)
Scrollingzgx244
zgx (Luau)247 (246–247)
GPUI Fast281 (281–290)
MyGo263 (262–263)
Rune450
Flingingzgx245 (244–245)
zgx (Luau)248
GPUI Fast288 (285–293)
MyGo264 (263–264)
Rune452 (451–452)
Jumpingzgx245
zgx (Luau)248
GPUI Fast282
MyGo268 (267–269)
Rune454

Microbenchmarks

One state change, and one scroll step of 10,000 rows, timed headless in process CPU per operation (the median over batches after a warm-up) from the change through to a frame ready to present. Each framework's frame is compared with the frames that do the same work: GPUI Fast's headless frame stops before the GPU encode, so it sits beside zgx's frame without one; Rune's and MyGo's include it (MyGo's also rasterizes on the CPU), beside zgx's with it. How they are defined

State update µs of CPU per operation lower is better One counter bound to one text, over a static grid of 1,000 texts: set the counter.
FrameFrameworkMedian (p10–p90)
Without the GPU encodezgx1.9 (1.7–2.2)
zgx (Luau)2.4 (2.2–2.5)
GPUI Fast675 (660–685)
With the GPU encodezgx81.6 (75.6–123.0)
zgx (Luau)60.7 (56.2–81.3)
Rune1,424 (1,384–1,454)
MyGo482 (461–495)
Scroll step, fixed rows µs of CPU per operation lower is better 10,000 rows of 28 pt: scroll 12 pt.
FrameFrameworkMedian (p10–p90)
Without the GPU encodezgx3.5 (3.1–4.1)
zgx (Luau)4.2 (3.8–4.9)
GPUI Fast26.5 (24.5–30.1)
With the GPU encodezgx91.2 (79.3–100.7)
zgx (Luau)113 (100–191)
Rune210 (126–231)
MyGo208 (200–304)
Scroll step, variable rows µs of CPU per operation lower is better 10,000 of the list scene's rows (wrapped text, some images), measured as they mount: scroll 12 pt.
FrameFrameworkMedian (p10–p90)
Without the GPU encodezgx6.9 (0.8–11.5)
zgx (Luau)9.7 (0.8–14.9)
GPUI Fast119 (98–137)
With the GPU encodezgx112 (87–137)
zgx (Luau)109 (86–143)
Rune209 (174–278)
MyGo431 (356–509)

How this was measured

How Rune is driven

Caveats

Data