Documentation Index Fetch the complete documentation index at: https://mintlify.com/slunghq/slung/llms.txt
Use this file to discover all available pages before exploring further.
Slung provides official client SDKs that handle binary protocol encoding, connection management, and error handling.
TypeScript/Node.js SDK
The TypeScript SDK provides a simple, type-safe client for Node.js applications.
Installation
cd sdks/client/typescript
pnpm install
Quick Start
import { SlungClient } from "@slunghq/client" ;
const client = new SlungClient ( "ws://127.0.0.1:2077" );
await client . connect ();
client . sendEvent ({
value: 23.5 ,
timestamp: Date . now () * 1000 , // Convert to microseconds
series: "temp" ,
tags: [ "sensor=1" , "env=prod" ]
});
client . close ();
API Reference
SlungClient
Main client class for connecting to Slung and sending events.
Constructor
const client = new SlungClient ( url ?: string )
url: WebSocket URL (default: ws://127.0.0.1:2077)
Methods
// Connect to Slung server
await client . connect (): Promise < void >
// Send a single event
client . sendEvent ( event : SlungEvent ): void
// Start simulated event stream (for testing)
client . startSimulatedStream ( options ?: SimulatedStreamOptions ): () => void
// Close connection
client . close ( code ?: number , reason ?: string ): void
SlungEvent
Event structure for metrics:
type SlungEvent = {
value : number ; // Metric value
timestamp : number ; // Unix microseconds
series : string ; // Series name
tags : string []; // Tags (format: "key=value")
};
Timestamp Helpers
import { nowUnixMicros } from "@slunghq/client" ;
const timestamp = nowUnixMicros (); // Current time in microseconds
Real-World Examples
Streaming Simulated Data
From examples/simulated.ts:
import { SlungClient } from "../src/index.ts" ;
async function main () : Promise < void > {
const client = new SlungClient (
process . env . SLUNG_WS_URL ?? "ws://127.0.0.1:2077" ,
);
await client . connect ();
console . log ( "connected to slung websocket" );
console . log ( "sending simulated events every 10ms" );
const stop = client . startSimulatedStream ({
intervalMs: 10 ,
initialValue: 90 ,
jitter: 1.2 ,
series: "temp" ,
tags: [ "sensor=1" , "env=dev" , "service=api" ],
});
const shutdown = () => {
stop ();
client . close ( 1000 , "shutdown" );
process . exit ( 0 );
};
process . on ( "SIGINT" , shutdown );
process . on ( "SIGTERM" , shutdown );
}
main (). catch (( err ) => {
console . error ( err );
process . exit ( 1 );
});
Run the example:
pnpm run example:simulated
Manual Event Sending
import { SlungClient , nowUnixMicros } from "@slunghq/client" ;
const client = new SlungClient ();
await client . connect ();
// Send CPU usage
client . sendEvent ({
value: 45.2 ,
timestamp: nowUnixMicros (),
series: "cpu.usage" ,
tags: [ "host=server-1" , "core=0" ]
});
// Send memory metrics
client . sendEvent ({
value: 8192.5 ,
timestamp: nowUnixMicros (),
series: "memory.used" ,
tags: [ "host=server-1" , "unit=mb" ]
});
High-Throughput Ingestion
import { SlungClient , nowUnixMicros } from "@slunghq/client" ;
const client = new SlungClient ();
await client . connect ();
// Send batch of events
const events = Array . from ({ length: 1000 }, ( _ , i ) => ({
value: Math . random () * 100 ,
timestamp: nowUnixMicros (),
series: "metric.batch" ,
tags: [ `index= ${ i } ` , "batch=true" ]
}));
for ( const event of events ) {
client . sendEvent ( event );
}
Binary Encoding
The SDK handles binary encoding automatically via encodeEventBinary (from src/wire.ts):
export function encodeEventBinary ( event : WireEvent ) : Buffer {
const seriesBuf = toUtf8 ( event . series , "series" );
const tagBufs = event . tags . map (( tag ) => toUtf8 ( tag , "tag" ));
return encodeFromBuffers ( event . timestamp , event . value , seriesBuf , tagBufs );
}
function encodeFromBuffers (
timestamp : number ,
value : number ,
seriesBuf : Buffer ,
tagBufs : Buffer [],
) : Buffer {
const HEADER_BYTES = 8 + 8 + 2 + 2 ;
const MAX_U16 = 0xffff ;
if ( tagBufs . length > MAX_U16 ) {
throw new Error ( `tag count exceeds ${ MAX_U16 } ` );
}
let total = HEADER_BYTES + seriesBuf . length ;
for ( const tag of tagBufs ) total += 2 + tag . length ;
const out = Buffer . allocUnsafe ( total );
let offset = 0 ;
// Write header
out . writeBigInt64LE ( BigInt ( Math . trunc ( timestamp )), offset );
offset += 8 ;
out . writeDoubleLE ( value , offset );
offset += 8 ;
out . writeUInt16LE ( seriesBuf . length , offset );
offset += 2 ;
out . writeUInt16LE ( tagBufs . length , offset );
offset += 2 ;
// Write series
seriesBuf . copy ( out , offset );
offset += seriesBuf . length ;
// Write tags
for ( const tag of tagBufs ) {
out . writeUInt16LE ( tag . length , offset );
offset += 2 ;
tag . copy ( out , offset );
offset += tag . length ;
}
return out ;
}
You can also import encoding functions directly:
import { encodeEventBinary , createEventBinaryEncoder } from "@slunghq/client" ;
// One-off encoding
const buffer = encodeEventBinary ({
timestamp: nowUnixMicros (),
value: 42.0 ,
series: "temp" ,
tags: [ "sensor=1" ]
});
// Pre-compiled encoder (reuses buffers)
const encoder = createEventBinaryEncoder ( "temp" , [ "sensor=1" ]);
const buffer = encoder ( nowUnixMicros (), 42.0 );
Benchmarking
Run ingestion benchmarks:
# Send 1M events in batches of 2000
pnpm run example:benchmark -- --count 1000000 --batch 2000 --series temp --tags sensor=1,env=bench
# Duration-based benchmark (30 seconds)
pnpm run example:benchmark -- --duration 30 --batch 2000 --series temp --tags sensor=1,env=bench --linger-ms 3000
Benchmark options:
--url ws://127.0.0.1:2077 # Server URL
--count 1000000 # Total events to send
--duration 30 # Run for N seconds
--batch 2000 # Events per batch
--series temp # Series name
--tags sensor=1,env=bench # Comma-separated tags
--max-buffered 4194304 # Max buffer size
--linger-ms 3000 # Linger time after sending
--progress-ms 1000 # Progress update interval
Error Handling
import { SlungClient } from "@slunghq/client" ;
const client = new SlungClient ();
try {
await client . connect ();
console . log ( "Connected successfully" );
} catch ( err ) {
console . error ( "Connection failed:" , err );
process . exit ( 1 );
}
try {
client . sendEvent ({
value: 23.5 ,
timestamp: Date . now () * 1000 ,
series: "temp" ,
tags: [ "sensor=1" ]
});
} catch ( err ) {
console . error ( "Send failed:" , err );
// WebSocket not connected - call connect() first
}
Other SDKs
Additional language SDKs are planned. Contributions welcome!
Next Steps
WebSocket Protocol Implement your own client using the protocol specification
Ingestion Overview Learn about other ingestion methods