Rewriting the cosmOS kernel in Rust

When we released the first version of cosmOS last year, it was written in Go. Go is a wonderful language, but it’s been a while since I’ve seen an article on the front page of Hacker News about rewriting some important tool in Go and I see articles on there about rewriting things in Rust every single week.

So we rewrote cosmOS in Rust. Here’s what we learned.

Why Rust?

Rust offers several advantages for systems programming:

  • Memory safety without garbage collection
  • Zero-cost abstractions that don’t sacrifice performance
  • Fearless concurrency with compile-time guarantees
  • Rich type system that catches bugs at compile time
use std::sync::Arc;
use tokio::sync::Mutex;

#[derive(Clone)]
pub struct Kernel {
    state: Arc<Mutex<KernelState>>,
}

impl Kernel {
    pub fn new() -> Self {
        Self {
            state: Arc::new(Mutex::new(KernelState::default())),
        }
    }

    pub async fn process(&self, command: Command) -> Result<Response, Error> {
        let mut state = self.state.lock().await;
        state.execute(command)
    }
}

The migration process

The migration took about 6 months and involved:

  1. Setting up the build system - We used Cargo for dependency management
  2. Porting core modules - Starting with the most critical components
  3. Writing tests - Comprehensive test coverage to ensure correctness
  4. Performance tuning - Optimizing hot paths and reducing allocations

Performance improvements

After the rewrite, we saw significant performance improvements:

  • 30% faster boot times
  • 50% reduction in memory usage
  • 2x improvement in concurrent request handling
#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_kernel_process() {
        let kernel = Kernel::new();
        let command = Command::new("test");
        let result = kernel.process(command).await;
        assert!(result.is_ok());
    }
}

Challenges we faced

The migration wasn’t without challenges:

  • Learning curve - Rust’s borrow checker takes time to understand
  • Ecosystem maturity - Some libraries we needed weren’t as mature as their Go counterparts
  • Compile times - Rust’s compile times are longer than Go’s

Despite these challenges, we’re happy with the decision to rewrite in Rust. The performance improvements and memory safety guarantees make it worth the effort.

Conclusion

Rewriting cosmOS in Rust was a significant undertaking, but the results speak for themselves. If you’re considering a similar migration, we’d recommend it — just be prepared for the learning curve!