I'd like to get some numbers on what kind of build times people are seeing when building things with Roc.
This is very open-ended! I'm just trying to get a sense of what people are seeing in practice, since I care a lot about build times being fast but since I'm focused on compiler work right now, I don't have a sense of what people are experiencing on their projects. :smile:
Feel free to post any numbers you have in this thread! It's helpful to know if they're cold builds (--no-cache) or rebuilds, and also ideally what system you're running on and what roc version outputs.
Building Joy TodoMVC:
roc build --target=wasm32 --no-cache app.roc
roc build
✓ Resolving Dependencies 484ms
✓ Parsing 8ms
✓ Name Resolution 3ms
✓ Type Inference 50ms
✓ Compile-Time Evaluation 3ms
Monotype Lowering 1ms
LIR Generation 0ms
LIR Passes 0ms
ARC 0ms
Static Data 0ms
x64 Instruction Generation 0ms
Execution 1ms
Store Results 0ms
✓ Monotype Setup 0ms
✓ Root + Wrapper Setup 0ms
✓ Specialization Lookup + Reservation 1ms
✓ Dispatch Evidence 5ms
✓ Body Graph Setup 6ms
✓ Body Traversal + Binding 58ms
✓ Body Type Graph 0ms
✓ Body Call Dispatch 0ms
✓ Body Draft IR Construction 0ms
✓ Body Reachability + Proofs 0ms
✓ Body Source Mapping 0ms
✓ Body Local Procedure Context 0ms
✓ Body Sealing + Commit 5ms
✓ Procedure Completion 0ms
✓ Layout Requests 0ms
✓ Static Data Requests 0ms
✓ Monotype Finalization 0ms
✓ Closure Lifting 0ms
✓ SpecConstr 15ms
✓ Lambda-Set Solving 7ms
✓ Inline Planning 0ms
✓ LIR Generation 1ms
✓ LIR Passes 2ms
✓ ARC 1ms
✓ Static Data 0ms
✓ LLVM IR Generation 6ms
✓ LLVM Optimize + Emit 406ms
✓ Linking 7ms
roc build 1.1s
0 errors and 0 warnings found in 1.1s while successfully building:
app.wasm
Edited source with cache:
roc build --target=wasm32 app.roc
0 errors and 0 warnings found in 552ms while successfully building:
app.wasm
NixOS, x86, AMD 9950X, Roc 94cbed386c51a8739ced3be76e7ab7b84dd22852.
Check and test times too? Test times in particular I noticed are a bit on the slower side, especially for the relatively small number and libraries I run these for.
Using Roc build from nix flake, revision 38c51448b837ae3fd1b606805ef2b254b196596e
# roc check --no-cache rvn/main.roc
No errors found in 627ms for main.roc
# roc test --no-cache rvn/main.roc
All (82) tests passed in 9832.2 ms.
# roc check --no-cache gregorian/main.roc
No errors found in 501ms for gregorian/main.roc
# roc test --no-cache gregorian/main.roc
All (48) tests passed in 4508.5 ms.
those test times are very surprising! I'll look into that, thanks :+1:
Linux x64 AMD Ryzen 7 9700X 8-Core Processor
Screwbot on a gaming rig
Makes me think we should add a flag for build times in a machine readable format like JSON
| $ roc build --output="./bt" --opt=speed apps/burntranscribe/main.roc
roc build
✓ Resolving Dependencies 3ms
✓ Parsing 9ms
✓ Name Resolution 18ms
✓ Type Inference 295ms
✓ Compile-Time Evaluation 1.2s
Monotype Lowering 1.1s
LIR Generation 78ms
LIR Passes 2ms
ARC 3ms
Static Data 1ms
arm64 Instruction Generation 11ms
Execution 11ms
Store Results 1ms
✓ Monotype Setup 0ms
✓ Root + Wrapper Setup 0ms
✓ Specialization Lookup + Reservation 8ms
✓ Dispatch Evidence 0ms
✓ Body Graph Setup 37ms
✓ Body Traversal + Binding 785ms
✓ Body Type Graph 0ms
✓ Body Call Dispatch 0ms
✓ Body Draft IR Construction 0ms
✓ Body Reachability + Proofs 0ms
✓ Body Source Mapping 0ms
✓ Body Local Procedure Context 0ms
✓ Body Sealing + Commit 590ms
✓ Procedure Completion 2ms
✓ Layout Requests 0ms
✓ Static Data Requests 0ms
✓ Monotype Finalization 0ms
✓ Closure Lifting 1ms
✓ SpecConstr 854ms
✓ Lambda-Set Solving 209ms
✓ Inline Planning 0ms
✓ LIR Generation 27ms
✓ LIR Passes 287ms
✓ ARC 72ms
✓ Static Data 0ms
✓ LLVM IR Generation 1.4s
✓ LLVM Optimize + Emit 10.0s
✓ Linking 285ms
roc build 15.9s
Same timings with --no-cache on the second run. App is 3.5k LoC, Platform is 3k LoC Roc + 71k LoC Rust, Macbook M1
$ roc build --no-cache --output="./bt" --opt=speed examples/realworld/main.roc
roc build
✓ Resolving Dependencies 3ms
✓ Parsing 6ms
✓ Name Resolution 8ms
✓ Type Inference 105ms
✓ Compile-Time Evaluation 12ms
Monotype Lowering 5ms
LIR Generation 2ms
LIR Passes 0ms
ARC 1ms
Static Data 0ms
arm64 Instruction Generation 1ms
Execution 2ms
Store Results 0ms
✓ Monotype Setup 0ms
✓ Root + Wrapper Setup 0ms
✓ Specialization Lookup + Reservation 3ms
✓ Dispatch Evidence 4ms
✓ Body Graph Setup 12ms
✓ Body Traversal + Binding 258ms
✓ Body Type Graph 0ms
✓ Body Call Dispatch 0ms
✓ Body Draft IR Construction 0ms
✓ Body Reachability + Proofs 0ms
✓ Body Source Mapping 0ms
✓ Body Local Procedure Context 0ms
✓ Body Sealing + Commit 43ms
✓ Procedure Completion 1ms
✓ Layout Requests 0ms
✓ Static Data Requests 0ms
✓ Monotype Finalization 0ms
✓ Closure Lifting 2ms
✓ SpecConstr 54ms
✓ Lambda-Set Solving 56ms
✓ Inline Planning 0ms
✓ LIR Generation 137ms
✓ LIR Passes 92ms
✓ ARC 27ms
✓ Static Data 1ms
✓ LLVM IR Generation 641ms
✓ LLVM Optimize + Emit 5.1s
✓ Linking 96ms
roc build 6.6s
Example is 1.2k LoC, platform is 1.3k LoC
@Karl @Jasper Woudenberg @Niclas Ahden out of curiosity, do you normally use roc build when building for development? or do you use roc without build to just build and run? or something else?
I've been using the CLI as listed without the --no-cache just because 5-15s doesn't really bother me (Rust...) but I mean to switch over to just running it in roc for the hot reload. I haven't done it yet because it's not picking up the changes. I think it's the main loop not terminating and it'll work if I tweak it but I haven't gotten around to it. I've been very platform focused on both projects so I haven't been doing a lot of app work and that would change the motivation.
The 7min timing for rebuilding the Roc compiler (which is like 5:50 LLVM) does annoy me but that's a matter of Apple silicon getting zig incremental builds.
ok maybe we should change the default...roc build is actually doing optimized builds, which is not necessary - if you do roc build --opt=dev it will not use LLVM and will be way faster
the reasoning for making --opt=speed the default for roc build was the assumption that roc without build would be used for normal development, and once you wanted to do roc build it was probably because you were ready to actually release, so it would be helpful to make it so you couldn't forget to do --opt=speed but maybe that's actually not the right default after all :sweat_smile:
I think that was the right decision. I do it this way because I run compiled languages in release unless it's slow enough to really disrupt things and I'm not annoyed to the point of making the change. As mentioned, I do plan on switching over to the base roc for dev once I figure out why the hot reload isn't getting picked up on my platforms which is my issue and not roc.
oh you shouldn't need to do anything
it might be the way it's structured though - basically what happens is that when roc detects a change to the entrypoint function(s) your app provides to the platform, it just swaps them out for the new ones so that the next time the platform calls them, it'll get the new ones
so if you're not seeing any hot loading, I'm guessing it's because the platform only calls those functions once on startup?
They're both on an event loop so I think I have to trampoline the loop or something.
does the event loop call them repeatedly? :thinking:
Richard Feldman said:
Karl Jasper Woudenberg Niclas Ahden out of curiosity, do you normally use
roc buildwhen building for development? or do you userocwithoutbuildto just build and run? or something else?
I haven't used roc build much yet because I've been working on libraries. Now I'm back to working on my platform jay, there I don't expect to use roc build much either because the nature of jay is that you run it as a script.
Richard Feldman said:
the reasoning for making
--opt=speedthe default forroc buildwas the assumption thatrocwithoutbuildwould be used for normal development, and once you wanted to doroc buildit was probably because you were ready to actually release, so it would be helpful to make it so you couldn't forget to do--opt=speedbut maybe that's actually not the right default after all :sweat_smile:
I’m using it exactly as you describe, so I’m happy with the current situation :ok:
ok then I'll leave it as-is for now!
Tested on a Mac:
MacBook Pro M1 Max: Full TodoMVC build
MacBook Pro M1 Max: build --watch on a small change
nice!
Here's an example from roc-pg:
Roc version: nightly-2026-August-05-24f0b47
Source: https://github.com/sandprickle/roc-pg/blob/migrate-zig-compiler/examples/query.roc
MacBook Air M1
HyperFine output
roc build output
Dev build is just a hair over 700ms
Last updated: Aug 12 2026 at 12:35 UTC