Binary Framing
All communication over the Unix socket uses length-prefixed binary framing:
[4 bytes: payload length (big-endian u32)] [payload bytes]
Frame Size Limits
MAX_FRAME_SIZE
number
default: "104857600"
Maximum data frame size: 100 MiB (matches blob size limit)
Maximum control/handshake frame size: 64 KiB
The handshake and JSON request/response frames use the 64 KiB limit to prevent oversized frames from forcing large allocations before channel routing.
Handshake
Every connection starts with a JSON handshake as the first frame:
Pool Channel
Settings Sync
Notebook Sync
Blob Channel
Handshake Fields
Channel type: pool, settings_sync, notebook_sync, or blob
Notebook sync only : Notebook file path or UUID (for untitled notebooks)
Notebook sync only : Protocol version (v1 or v2). Use v2 for typed frames.
Notebook sync only : Working directory for untitled notebooks (used for project file detection)
Pool Channel
Request Types
All requests are JSON objects with a type field:
Take Environment
Return Environment
Pool Status
Ping
Shutdown
Flush Pool
List Rooms
{
"type" : "take" ,
"env_type" : "uv" // or "conda"
}
Response Types
Environment Acquired
Pool Empty
Environment Returned
Pool Statistics
Pong
Shutting Down
Pool Flushed
Error
Rooms List
{
"type" : "env" ,
"env" : {
"env_type" : "uv" ,
"venv_path" : "/Users/username/.cache/runt/envs/runtimed-uv-abc123/" ,
"python_path" : "/Users/username/.cache/runt/envs/runtimed-uv-abc123/bin/python"
}
}
Pool Status Fields
Number of prewarmed UV environments ready to claim
Number of UV environments currently being created
Number of prewarmed Conda environments ready to claim
Number of Conda environments currently being created
Error info if UV pool is in error state (e.g., invalid default packages)
Error info if Conda pool is in error state
Notebook Sync Channel
Protocol v2: Typed Frames
Notebook sync connections using protocol: "v2" send typed frames where the first byte indicates the message type:
Byte Type Content 0x00Automerge Sync Binary Automerge sync message 0x01Request JSON NotebookRequest 0x02Response JSON NotebookResponse 0x03Broadcast JSON NotebookBroadcast
After the handshake, the server sends a ProtocolCapabilities response indicating the negotiated protocol before starting sync.
Notebook Requests
Launch Kernel
Execute Cell
Clear Outputs
Interrupt Execution
Shutdown Kernel
Get Kernel Info
Run All Cells
Send Comm (Widget Interaction)
Get History
Code Completion
Save Notebook
Sync Environment
{
"action" : "launch_kernel" ,
"kernel_type" : "python" ,
"env_source" : "uv:inline" ,
"notebook_path" : "/path/to/notebook.ipynb"
}
Notebook Responses
Kernel Launched
Cell Queued
Kernel Info
Queue State
History Result
Completion Result
Error
{
"result" : "kernel_launched" ,
"kernel_type" : "python" ,
"env_source" : "uv:inline" ,
"launched_config" : {
"uv_deps" : [ "numpy" , "pandas" ],
"conda_deps" : null ,
"conda_channels" : null ,
"deno_permissions" : null
}
}
Notebook Broadcasts
Broadcasts are sent proactively to all connected peers when events occur:
Kernel Status
Execution Started
Output
Outputs Cleared
Display Update (Widget Progress)
Comm Message (Widget)
Comm State Sync
Environment Progress
Environment Sync State
{
"event" : "kernel_status" ,
"status" : "busy" ,
"cell_id" : "550e8400-e29b-41d4-a716-446655440000"
}
Blob Channel
Store Blob Flow
1. Client sends handshake:
{"channel": "blob"}
2. Client sends request (JSON frame):
{"action": "store", "media_type": "image/png"}
3. Client sends blob data (raw binary frame):
[PNG binary bytes]
4. Server responds (JSON frame):
{"hash": "a1b2c3d4e5f6..."}
Get Blob Port
Query the HTTP server port:
Example: Pool Client
use runtimed :: client :: PoolClient ;
use runtimed :: EnvType ;
#[tokio :: main]
async fn main () -> anyhow :: Result <()> {
// Connect to daemon (finds socket automatically)
let client = PoolClient :: connect ( None ) . await ? ;
// Ping to verify connection
client . ping () . await ? ;
println! ( "Daemon is alive" );
// Get pool statistics
let stats = client . status () . await ? ;
println! ( "UV available: {}" , stats . uv_available);
println! ( "Conda available: {}" , stats . conda_available);
// Acquire a UV environment
match client . take ( EnvType :: Uv ) . await ? {
Some ( env ) => {
println! ( "Got environment: {:?}" , env . python_path);
// Use the environment...
// Return it to the pool when done
client . return_env ( env ) . await ? ;
}
None => {
println! ( "No environments available" );
}
}
Ok (())
}
Example: Notebook Sync Client
use runtimed :: notebook_sync_client :: NotebookSyncClient ;
#[tokio :: main]
async fn main () -> anyhow :: Result <()> {
// Connect to notebook room
let client = NotebookSyncClient :: connect (
"/path/to/notebook.ipynb" ,
None , // daemon socket (auto-detect)
) . await ? ;
// Update cell source (syncs to all peers)
client . update_source (
"550e8400-e29b-41d4-a716-446655440000" ,
"print('Hello from daemon')"
) . await ? ;
// Listen for changes from other peers
tokio :: spawn ( async move {
loop {
if let Some ( change ) = client . recv_changes () . await ? {
println! ( "Notebook updated: {} cells" , change . cells . len ());
}
}
});
Ok (())
}
Error Handling
Connection Errors
Socket not found : Daemon is not running
Connection refused : Socket exists but daemon is not accepting connections (crashed)
Timeout : Daemon is unresponsive (hung)
Protocol Errors
Frame too large : Oversized payload (check MAX_FRAME_SIZE limits)
Invalid JSON : Malformed request/response
Unknown channel : Invalid handshake channel
Unknown frame type : Invalid typed frame byte (notebook sync v2)
Pool Errors
Empty pool : No environments available (check with status)
Invalid env type : Unknown environment type (must be uv or conda)
Creation failed : Environment creation error (check daemon logs)