raylib performance — backend comparison

rlvk (moltenvk)  vs  rlvk (moltenvk threaded)  |  GPU Apple M5 (24576 MB)  |  Driver MoltenVK 1.4.2  |  OS macOS 26.5.1  |  3 runs × 10000 ms full speed

Green = best backend for that example/metric, red = worst. Frame time & FPS are the representative run; software (rlsw) has no GPU so its VRAM is ~0. Shader-heavy examples may not execute custom shaders on the software backend.

° = at that backend's floor (median within 15% of its own bench_idle median): the scene finishes its real work faster than one present/loop turnaround, so the number measures presentation pacing or loop overhead, not rendering cost, and cross-backend ratios there compare present plumbing. On macOS, Metal-backed Vulkan presents pace on drawable acquire (~1.6-1.8 ms) while GL's IOSurface flush has no floor - only rows without ° compare backend rendering cost.

Read this before comparing FPS on macOS. Uncapped FPS on light scenes here measures presentation, not rendering. Apple GL presents by flushing an IOSurface — no per-frame handshake, essentially free — while Vulkan on macOS (MoltenVK or KosmicKrisp) can only present through Metal, which must acquire a CAMetalDrawable from CoreAnimation each frame, paced at ~1.6–1.8 ms on a composited window no matter how little the frame draws. Measured on shapes_basic_shapes, uncapped: frame interval avg 1.95 ms, of which 1.76 ms (90%) is "Retrieve a CAMetalDrawable" (MoltenVK's own performance tracking; the drawing itself costs ~0.12 ms and the GPU is nearly idle). Every native Metal app pays the same pacing; no driver knob removes it (KosmicKrisp's is lowered from ~3.3 to ~1.6 ms by MESA_VK_WSI_PRESENT_MODE=mailbox, MoltenVK's config surface is exhausted). Cells marked ° sit at that backend's floor: their cross-backend ratios compare macOS present plumbing. Rows above the floor compare real rendering — there the Vulkan backend leads (e.g. 8000 draw calls: 120 fps GL vs 581 fps rlvk). Under vsync all backends lock to the display rate and the floor is invisible.

speedup = rlvk (moltenvk threaded) relative to rlvk (moltenvk), per metric direction (>1x favors rlvk (moltenvk threaded)); ° on a ratio means at least one side sits at its floor, so it compares present plumbing.

Frames per second (higher is better)

Sustained FPS at full speed (uncapped).
Examplerlvk (moltenvk)rlvk (moltenvk threaded)rlvk (moltenvk threaded) speedup
shapes_basic_shapes516°8310°16.11x°
textures_tiled_drawing472°8418°17.83x°
textures_particles_blending532°7990°15.03x°
shapes_starfield_effect529°8236°15.58x°
models_loading2897887°27.33x°
models_heightmap_rendering559°7630°13.66x°
models_skybox_rendering3318253°24.91x°
models_waving_cubes544°12942.38x°
models_first_person_maze3098192°26.49x°
core_3d_camera_free3536687°18.95x°
shaders_basic_lighting512°6934°13.53x°
shaders_basic_pbr282611521.72x
shaders_mandelbrot_set412°435710.59x°
shaders_raymarching_rendering1562621.68x
performance_stress_test1951780.91x
performance_stress_test_direct330.95x
bench_idle415°8363°20.14x°
bench_drawcalls474°16933.57x°
bench_instanced362680018.81x

Median frame time, ms (lower is better)

Median per-frame CPU wall time.
Examplerlvk (moltenvk)rlvk (moltenvk threaded)rlvk (moltenvk threaded) speedup
shapes_basic_shapes1.601°0.104°15.39x°
textures_tiled_drawing1.616°0.105°15.39x°
textures_particles_blending1.603°0.114°14.06x°
shapes_starfield_effect1.603°0.105°15.27x°
models_loading3.3690.110°30.63x°
models_heightmap_rendering1.684°0.118°14.27x°
models_skybox_rendering3.0440.105°28.99x°
models_waving_cubes1.657°0.7672.16x°
models_first_person_maze3.2910.106°31.05x°
core_3d_camera_free2.9310.107°27.39x°
shaders_basic_lighting1.606°0.113°14.21x°
shaders_basic_pbr3.4050.17119.91x
shaders_mandelbrot_set1.888°0.2268.35x°
shaders_raymarching_rendering3.6563.7380.98x
performance_stress_test5.1015.5280.92x
performance_stress_test_direct325.523340.7850.96x
bench_idle1.840°0.109°16.88x°
bench_drawcalls1.835°0.5853.14x°
bench_instanced2.4720.16415.07x

Average frame time, ms (lower is better)

Mean per-frame wall time.
Examplerlvk (moltenvk)rlvk (moltenvk threaded)rlvk (moltenvk threaded) speedup
shapes_basic_shapes1.939°0.120°16.11x°
textures_tiled_drawing2.119°0.119°17.83x°
textures_particles_blending1.881°0.125°15.03x°
shapes_starfield_effect1.892°0.121°15.58x°
models_loading3.4640.127°27.33x°
models_heightmap_rendering1.790°0.131°13.66x°
models_skybox_rendering3.0180.121°24.91x°
models_waving_cubes1.837°0.7732.38x°
models_first_person_maze3.2330.122°26.49x°
core_3d_camera_free2.8330.150°18.95x°
shaders_basic_lighting1.951°0.144°13.53x°
shaders_basic_pbr3.5520.16421.72x
shaders_mandelbrot_set2.430°0.23010.59x°
shaders_raymarching_rendering6.4133.8171.68x
performance_stress_test5.1235.6290.91x
performance_stress_test_direct329.243347.2280.95x
bench_idle2.408°0.120°20.14x°
bench_drawcalls2.111°0.5913.57x°
bench_instanced2.7660.14718.81x

CPU utilization, %

Average process CPU as percent of the whole machine.
Examplerlvk (moltenvk)rlvk (moltenvk threaded)rlvk (moltenvk threaded) speedup
shapes_basic_shapes3.99.90.39x
textures_tiled_drawing3.510.30.35x
textures_particles_blending4.210.00.42x
shapes_starfield_effect4.110.00.41x
models_loading1.99.40.20x
models_heightmap_rendering4.49.10.48x
models_skybox_rendering2.19.50.22x
models_waving_cubes7.611.80.64x
models_first_person_maze2.09.60.21x
core_3d_camera_free2.39.00.25x
shaders_basic_lighting4.39.00.47x
shaders_basic_pbr2.18.20.25x
shaders_mandelbrot_set3.26.90.46x
shaders_raymarching_rendering1.30.81.60x
performance_stress_test10.310.50.98x
performance_stress_test_direct0.00.00.39x
bench_idle2.99.80.30x
bench_drawcalls7.79.50.81x
bench_instanced3.111.20.28x

RAM, MB

Average working-set memory.
Examplerlvk (moltenvk)rlvk (moltenvk threaded)rlvk (moltenvk threaded) speedup
shapes_basic_shapes85.487.70.97x
textures_tiled_drawing85.788.30.97x
textures_particles_blending85.587.80.97x
shapes_starfield_effect85.387.70.97x
models_loading101.2103.00.98x
models_heightmap_rendering88.790.90.98x
models_skybox_rendering161.7164.20.98x
models_waving_cubes92.893.90.99x
models_first_person_maze86.388.30.98x
core_3d_camera_free85.287.30.98x
shaders_basic_lighting102.4104.60.98x
shaders_basic_pbr140.7141.80.99x
shaders_mandelbrot_set103.6105.40.98x
shaders_raymarching_rendering118.9120.30.99x
performance_stress_test152.8153.11.00x
performance_stress_test_direct104.0105.90.98x
bench_idle84.987.50.97x
bench_drawcalls86.587.90.98x
bench_instanced103.6105.70.98x

GPU VRAM, MB

Average per-process video memory.
Examplerlvk (moltenvk)rlvk (moltenvk threaded)rlvk (moltenvk threaded) speedup
shapes_basic_shapes0.00.0
textures_tiled_drawing0.00.0
textures_particles_blending0.00.0
shapes_starfield_effect0.00.0
models_loading0.00.0
models_heightmap_rendering0.00.0
models_skybox_rendering0.00.0
models_waving_cubes0.00.0
models_first_person_maze0.00.0
core_3d_camera_free0.00.0
shaders_basic_lighting0.00.0
shaders_basic_pbr0.00.0
shaders_mandelbrot_set0.00.0
shaders_raymarching_rendering0.00.0
performance_stress_test0.00.0
performance_stress_test_direct0.00.0
bench_idle0.00.0
bench_drawcalls0.00.0
bench_instanced0.00.0