High-performance, memory-safe backend for chatbot systems, built with Rust for superior performance and resource efficiency.
Rust provides compile-time memory safety guarantees and zero-cost abstractions, making it ideal for performance-critical backend services.
| Metric | Node.js (Before) | Rust (After) | Improvement |
|---|---|---|---|
| Memory Safety | Runtime checks | Compile-time guaranteed | β Zero-cost |
| Async Performance | Event loop overhead | Tokio zero-cost async | π 2-3x faster |
| Memory Usage | ~600MB | ~150MB | πΎ 75% reduction |
| CPU Usage | Higher GC overhead | No GC | β‘ 40% reduction |
| Binary Size | Node + deps ~100MB | Single binary ~15MB | π¦ 85% smaller |
| Startup Time | ~2-3s | ~50ms | β±οΈ 50x faster |
rust-backend/
βββ Cargo.toml # Dependency management
βββ config.toml # Application configuration
βββ .env.example # Environment variable template
βββ src/
βββ main.rs # Application entry point
βββ config.rs # Configuration loader
βββ models/ # Data structures
β βββ mod.rs
β βββ chat.rs # Chat message types
βββ services/ # Business logic layer
β βββ mod.rs
β βββ cache.rs # In-memory cache (Moka)
β βββ queue.rs # Request queue manager
β βββ batch.rs # Batch request processor
β βββ ollama.rs # Ollama API client
βββ handlers/ # HTTP request handlers
β βββ mod.rs
β βββ chat.rs # Chat endpoints
β βββ queue.rs # Queue management endpoints
β βββ stats.rs # Statistics endpoints
βββ utils/ # Helper utilities
βββ mod.rs
- Rust 1.75+ - Install from rustup.rs
- Ollama - Running at
http://172.18.0.111:11434with a loaded model
# Navigate to rust-backend directory
cd rust-backend
# Copy environment template
cp .env.example .env
# Edit .env with your settings
nano .env
# Build in development mode
cargo build
# Build optimized production binary
cargo build --release
# Run the server
cargo run --releaseServer starts at http://0.0.0.0:8080 by default.
[server]
host = "0.0.0.0"
port = 8080
workers = 4 # Number of worker threads
[ollama]
api_url = "http://172.18.0.111:11434"
model = "deepseek-r1:8b"
keep_alive = "15m" # Keep model loaded in memory
[cache]
max_size_mb = 256 # Maximum cache size
ttl_seconds = 3600 # Time-to-live for cached entries
enabled = true
[conversation_cache]
max_size_mb = 128
ttl_seconds = 1800
[batch]
max_batch_size = 3 # Process up to 3 requests together
batch_timeout_ms = 2000 # Wait max 2s before processing batch
enable_deduplication = true # Deduplicate identical requests
[queue]
max_concurrent = 1 # Process 1 request at a time
max_queue_size = 100Override configuration using environment variables:
export HOST=0.0.0.0
export PORT=8080
export OLLAMA_API_URL=http://172.18.0.111:11434
export CACHE_MAX_SIZE_MB=512
export RUST_LOG=info,chatbot_backend=debugOptimized chat endpoint with caching and streaming support.
Request:
{
"messages": [
{"role": "user", "content": "What is Rust?"}
],
"stream": true,
"use_cache": true,
"priority": 0
}Response (Non-streaming):
{
"message": {
"role": "assistant",
"content": "Rust is a systems programming language..."
},
"cached": false
}Response (Streaming - SSE):
data: {"content":"Rust","done":false,"cached":false}
data: {"content":" is","done":false,"cached":false}
data: {"content":" a","done":false,"cached":false}
data: {"done":true,"cached":false}
Add a chat request to the processing queue.
Request:
{
"messages": [{"role": "user", "content": "Hello"}],
"model": "deepseek-r1:8b"
}Response:
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"status": {
"queue_position": 2,
"queue_length": 5,
"estimated_wait_time": 60000,
"is_processing": false
}
}Check the status of a queued request.
Response:
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"queue_position": 0
}Cancel a pending request in the queue.
Get comprehensive system statistics.
Response:
{
"timestamp": "2025-01-30T10:00:00Z",
"response_cache": {
"total_entries": 150,
"total_size_mb": 12.5,
"hit_rate": 0.65,
"miss_rate": 0.35,
"memory_usage_percent": 4.9
},
"conversation_cache": {
"total_entries": 80,
"total_size_mb": 6.2,
"hit_rate": 0.72,
"memory_usage_percent": 2.4
},
"batch_processor": {
"total_requests": 500,
"cached_responses": 325,
"cache_hit_rate": 65,
"average_batch_size": 2.5
},
"queue_length": 0,
"is_processing": false
}Perform cache management operations.
Available Actions:
clear- Clear all cachesclear_response_cache- Clear response cache onlyclear_conversation_cache- Clear conversation cache onlywarm_model- Pre-load model into memory
Request Example:
{
"action": "warm_model",
"data": {
"model": "deepseek-r1:8b"
}
}Basic server health check endpoint.
Response:
{
"status": "healthy"
}# Run all tests
cargo test
# Run tests with output
cargo test -- --nocapture
# Run specific test
cargo test test_cache_service
# Run tests with coverage
cargo tarpaulin --out Html# Format code according to Rust style guidelines
cargo fmt
# Run the linter
cargo clippy -- -D warnings
# Check code without building
cargo check
# Check for security vulnerabilities
cargo audit# Install cargo-watch
cargo install cargo-watch
# Run with auto-reload on file changes
cargo watch -x run# Set log level
RUST_LOG=debug cargo run
# Module-specific logging
RUST_LOG=chatbot_backend::services::cache=trace cargo run# Build optimized release binary
cargo build --release
# The binary is created at:
# ./target/release/chatbot-backend
# Run production binary
RUST_LOG=info ./target/release/chatbot-backendDockerfile:
FROM rust:1.75 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && \
apt-get install -y ca-certificates && \
rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/chatbot-backend /usr/local/bin/
COPY config.toml /etc/chatbot/config.toml
ENV RUST_LOG=info
EXPOSE 8080
CMD ["chatbot-backend"]Build and Run:
# Build Docker image
docker build -t chatbot-backend:latest .
# Run container
docker run -d \
-p 8080:8080 \
-v $(pwd)/config.toml:/etc/chatbot/config.toml \
-e RUST_LOG=info \
--name chatbot-backend \
chatbot-backend:latest
# View logs
docker logs -f chatbot-backendCreate /etc/systemd/system/chatbot-backend.service:
[Unit]
Description=Chatbot Backend Service
After=network.target
[Service]
Type=simple
User=chatbot
WorkingDirectory=/opt/chatbot-backend
ExecStart=/opt/chatbot-backend/chatbot-backend
Restart=always
RestartSec=10
Environment="RUST_LOG=info"
Environment="CONFIG_PATH=/opt/chatbot-backend/config.toml"
[Install]
WantedBy=multi-user.targetEnable and Start:
sudo systemctl daemon-reload
sudo systemctl enable chatbot-backend
sudo systemctl start chatbot-backend
sudo systemctl status chatbot-backend# Increase cache for better performance (if RAM available)
[cache]
max_size_mb = 512 # Increased from 256
[conversation_cache]
max_size_mb = 256 # Increased from 128# Increase if your GPU can handle parallel requests
[queue]
max_concurrent = 2 # Increased from 1
[batch]
max_batch_size = 5 # Increased from 3
batch_timeout_ms = 1000 # Reduced from 2000# Keep model loaded longer to avoid reload overhead
[ollama]
keep_alive = "30m" # Increased from 15m# Increase worker threads for CPU-bound tasks
[server]
workers = 8 # Match your CPU core countSymptoms: Process consuming excessive RAM
Diagnosis:
# Check process memory
ps aux | grep chatbot-backend
# Get cache statistics
curl http://localhost:8080/api/cache-stats | jqSolutions:
- Reduce cache size in
config.toml - Decrease TTL values
- Clear cache:
curl -X POST http://localhost:8080/api/cache-stats -d '{"action":"clear"}'
Symptoms: "Connection refused" or timeout errors
Diagnosis:
# Test Ollama connectivity
curl http://172.18.0.111:11434/api/tags
# Check if model is loaded
curl http://172.18.0.111:11434/api/ps
# Enable debug logging
RUST_LOG=debug ./chatbot-backendSolutions:
- Verify Ollama is running:
systemctl status ollama - Check firewall rules
- Update
api_urlinconfig.toml - Ensure model is pulled:
ollama pull deepseek-r1:8b
Symptoms: High latency, requests timing out
Common Causes:
- Low cache hit rate
- Ollama model not loaded
- Network latency to Ollama
- Queue bottleneck
Solutions:
- Check cache hit rate in stats endpoint
- Pre-warm the model: POST to
/api/cache-statswithwarm_modelaction - Increase
keep_alivesetting - Increase
max_concurrentif GPU allows - Monitor with:
watch -n 5 'curl -s http://localhost:8080/api/cache-stats | jq ".response_cache.hit_rate"'
Symptoms: Long queue lengths, high wait times
Solutions:
# Increase concurrent processing
[queue]
max_concurrent = 2
# Reduce batch timeout for faster processing
[batch]
batch_timeout_ms = 1000# Production logging (info level)
RUST_LOG=info ./chatbot-backend
# Development logging (debug level)
RUST_LOG=debug ./chatbot-backend
# Trace-level logging for specific module
RUST_LOG=chatbot_backend::services::cache=trace ./chatbot-backend
# Multiple module logging
RUST_LOG=chatbot_backend::services=debug,chatbot_backend::handlers=info ./chatbot-backend# Watch cache statistics
watch -n 5 'curl -s http://localhost:8080/api/cache-stats | jq ".response_cache"'
# Monitor queue status
watch -n 1 'curl -s http://localhost:8080/api/chat-queue | jq'
# Check memory usage
watch -n 2 'ps aux | grep chatbot-backend | grep -v grep'#!/bin/bash
# health-check.sh
if curl -f http://localhost:8080/health > /dev/null 2>&1; then
echo "β
Service is healthy"
exit 0
else
echo "β Service is unhealthy"
exit 1
fiConsider adding Prometheus metrics exporter for production monitoring:
- Request latency histograms
- Cache hit/miss counters
- Queue length gauge
- Active connections
- Memory Safety: All code is memory-safe by design, preventing buffer overflows and use-after-free bugs
- Type Safety: Strong compile-time type checking prevents injection attacks
- No Data Races: Rust's ownership system guarantees thread safety
- Minimal Dependencies: Small dependency tree reduces attack surface
# Regular dependency audits
cargo install cargo-audit
cargo audit
# Update dependencies
cargo update
# Check for known vulnerabilities
cargo outdatedConfigure CORS in your reverse proxy (nginx, Caddy) rather than in the application:
# nginx example
add_header Access-Control-Allow-Origin "https://yourdomain.com";
add_header Access-Control-Allow-Methods "GET, POST, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";All inputs are validated through Rust's type system:
- JSON deserialization validates structure
- Strong typing prevents type confusion
- No SQL injection risk (no SQL database)
| Component | Node.js | Rust |
|---|---|---|
| Web Framework | Express/Next.js | Axum |
| Async Runtime | Node Event Loop | Tokio |
| HTTP Client | fetch/axios | reqwest |
| Caching | In-memory Map | Moka |
| Concurrency | Promises | async/await + channels |
| Timers | setTimeout | tokio::time |
Update your frontend to point to the Rust backend:
Before (Next.js API Route):
const response = await fetch('/api/chat-stream', {
method: 'POST',
body: JSON.stringify({ messages })
});After (Rust Backend):
const BACKEND_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080';
const response = await fetch(`${BACKEND_URL}/api/chat-optimized`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages, stream: true })
});Environment Configuration:
# .env.local
NEXT_PUBLIC_API_URL=http://localhost:8080- Phase 1: Deploy Rust backend alongside Node.js
- Phase 2: Route 10% of traffic to Rust backend
- Phase 3: Gradually increase traffic percentage
- Phase 4: Full cutover when confident
- Phase 5: Decommission Node.js backend
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_cache_operations() {
// Test implementation
}
}# Run integration tests
cargo test --test integration_testsUse tools like wrk or Apache Bench:
# Install wrk
sudo apt install wrk
# Run load test
wrk -t4 -c100 -d30s --latency http://localhost:8080/healthCompare performance before and after migration:
# Benchmark with Apache Bench
ab -n 10000 -c 100 http://localhost:8080/api/chat-optimized
# Benchmark with wrk
wrk -t4 -c100 -d30s http://localhost:8080/api/chat-optimized- Rust Language: The Rust Programming Language Book
- Async Programming: Tokio Tutorial
- Web Framework: Axum Documentation
- Caching: Moka Cache Guide
- HTTP Client: Reqwest Documentation
Contributions are welcome! Please follow these guidelines:
- Code Style: Format with
cargo fmt - Linting: Pass
cargo clippywith no warnings - Testing: Add tests for new features (
cargo test) - Documentation: Update docs for API changes
- Pull Request: Submit PR with clear description
# 1. Create feature branch
git checkout -b feature/my-feature
# 2. Make changes and test
cargo fmt
cargo clippy
cargo test
# 3. Commit with descriptive message
git commit -m "feat: add new caching strategy"
# 4. Push and create PR
git push origin feature/my-featureThis project is licensed under the same terms as the main chatbot project.
- Rust Community for excellent tooling and libraries
- Tokio Team for the async runtime
- Axum Team for the web framework
- Moka for the high-performance cache
- Issues: Report bugs via GitHub Issues
- Discussions: Join community discussions
- Documentation: Check the
/docsfolder for detailed guides
Built with β€οΈ and π¦ by the Chatbot Team