Low Memory Mode¶
Run NornicDB in resource-constrained environments like Docker containers, Raspberry Pi, or VMs with limited RAM.
Overview¶
NornicDB's Low Memory Mode reduces RAM usage by 50-70% compared to default settings, enabling deployment on systems with as little as 512MB of available memory. This is essential for:
- Docker containers with default 2GB memory limits
- Raspberry Pi and other ARM SBCs
- Cloud VMs with limited RAM (t2.micro, etc.)
- Development environments running multiple services
- Edge deployments where resources are scarce
Quick Start¶
Environment Variable¶
Docker¶
docker run -d \
--name nornicdb \
-p 7474:7474 \
-p 7687:7687 \
-e NORNICDB_LOW_MEMORY=true \
timothyswt/nornicdb-arm64-metal:latest
Docker Compose¶
services:
nornicdb:
image: timothyswt/nornicdb-arm64-metal:latest
environment:
- NORNICDB_LOW_MEMORY=true
- GOGC=100 # Recommended with low memory mode
ports:
- "7474:7474"
- "7687:7687"
volumes:
- nornicdb-data:/data
Command Line Flag¶
Memory Usage Comparison¶
| Mode | BadgerDB RAM | Typical Total | Use Case |
|---|---|---|---|
| High Performance (default) | ~1GB | 1.5-2GB | Servers with 8GB+ RAM |
| Default | ~150MB | 300-500MB | General purpose |
| Low Memory | ~50MB | 150-300MB | Resource-constrained |
Breakdown by Component¶
| Component | High Performance | Default | Low Memory |
|---|---|---|---|
| BadgerDB MemTable | 128MB × 5 | 64MB × 3 | 8MB × 1 |
| Value Log | 256MB | 128MB | 32MB |
| Block Cache | 256MB | 128MB | 8MB |
| Index Cache | 128MB | 64MB | 4MB |
| Total Storage Layer | ~1GB | ~150MB | ~50MB |
Configuration Options¶
Environment Variables¶
| Variable | Type | Default | Description |
|---|---|---|---|
NORNICDB_LOW_MEMORY | bool | false | Enable low memory mode |
NORNICDB_BADGER_HIGH_PERFORMANCE | bool | true | High performance mode (mutually exclusive with low memory) |
GOGC | int | 100 | Go garbage collector target percentage |
CLI Flags¶
nornicdb serve --help
Flags:
--low-memory Use minimal RAM (for resource constrained environments)
--badger-high-performance Enable BadgerDB high performance mode (default true)
--gc-percent GC aggressiveness (100=default, lower=more aggressive)
Priority Order¶
--low-memoryflag overrides everythingNORNICDB_LOW_MEMORY=trueenvironment variable- Default: Auto-detect based on available system memory (planned)
Performance Impact¶
Low memory mode trades some performance for reduced RAM usage:
| Metric | High Performance | Low Memory | Impact |
|---|---|---|---|
| Write throughput | 50,000 ops/sec | 20,000 ops/sec | -60% |
| Read throughput | 100,000 ops/sec | 80,000 ops/sec | -20% |
| Query latency (p50) | 1ms | 2ms | +100% |
| Query latency (p99) | 5ms | 15ms | +200% |
| Startup time | 2s | 1s | -50% |
Note: These numbers are approximate and vary by workload. For most use cases, low memory mode provides acceptable performance.
Docker Memory Limits¶
Docker Desktop defaults to 2GB memory. With NornicDB's high-performance mode + embedding model (~1.2GB), this can cause OOM kills.
Symptoms of OOM¶
# Container repeatedly restarts
docker ps
CONTAINER ID STATUS PORTS
abc123 Restarting (137) 5 seconds ago
# Exit code 137 = SIGKILL (OOM)
docker logs nornicdb
Solution: Enable Low Memory Mode¶
# docker-compose.yml
services:
nornicdb:
image: timothyswt/nornicdb-arm64-metal:latest
environment:
- NORNICDB_LOW_MEMORY=true
- GOGC=100
# Optional: Set explicit memory limit
deploy:
resources:
limits:
memory: 1G
Alternative: Increase Docker Memory¶
# Docker Desktop: Settings > Resources > Memory > 4GB+
# Or use explicit limit
docker run --memory=4g nornicdb ...
Embedding Model Considerations¶
The embedded BGE-M3 model requires ~1.2GB RAM. In low memory mode:
- Use external embedding service (Ollama, OpenAI) instead of local model
- Or increase container memory to 2GB+
# Option 1: External embeddings (recommended for low memory)
services:
nornicdb:
environment:
- NORNICDB_LOW_MEMORY=true
- NORNICDB_EMBEDDING_PROVIDER=ollama
- NORNICDB_EMBEDDING_URL=http://ollama:11434
ollama:
image: ollama/ollama:latest
# Ollama manages its own memory
# Option 2: Local embeddings with more memory
services:
nornicdb:
environment:
- NORNICDB_EMBEDDING_PROVIDER=local
deploy:
resources:
limits:
memory: 2.5G # 1.2GB model + 1GB BadgerDB + headroom
WAL Compaction¶
Low memory mode works well with automatic WAL compaction to prevent disk bloat:
services:
nornicdb:
environment:
- NORNICDB_LOW_MEMORY=true
- NORNICDB_WAL_ENABLED=true
volumes:
- nornicdb-data:/data
# WAL will auto-compact every 5 minutes
# Snapshots stored in /data/snapshots
Manual WAL Cleanup¶
If your WAL has already grown large:
# Stop NornicDB
docker stop nornicdb
# Remove bloated WAL (data is safe in BadgerDB)
rm -f /path/to/data/wal/wal.log
# Restart with low memory mode
docker start nornicdb
Raspberry Pi Deployment¶
For Raspberry Pi 4 (2GB+ RAM):
# Use ARMv8 image with low memory mode
docker run -d \
--name nornicdb \
-p 7474:7474 \
-p 7687:7687 \
-e NORNICDB_LOW_MEMORY=true \
-e NORNICDB_EMBEDDING_PROVIDER=ollama \
-e GOGC=50 \
-v nornicdb-data:/data \
--restart unless-stopped \
timothyswt/nornicdb-arm64:latest
For Raspberry Pi 3 (1GB RAM):
# Minimal configuration - disable local embeddings
docker run -d \
--name nornicdb \
-p 7474:7474 \
-p 7687:7687 \
-e NORNICDB_LOW_MEMORY=true \
-e NORNICDB_EMBEDDING_ENABLED=false \
-e GOGC=30 \
-v nornicdb-data:/data \
--restart unless-stopped \
timothyswt/nornicdb-arm64:latest
Programmatic Configuration¶
Go API¶
import "github.com/orneryd/nornicdb/pkg/nornicdb"
config := nornicdb.DefaultConfig()
config.LowMemoryMode = true // Enable low memory mode
db, err := nornicdb.Open("/data/nornicdb", config)
if err != nil {
log.Fatal(err)
}
defer db.Close()
Storage Engine Options¶
import "github.com/orneryd/nornicdb/pkg/storage"
// Create low-memory BadgerDB engine
opts := storage.BadgerOptions{
DataDir: "/data/nornicdb",
LowMemory: true,
}
engine, err := storage.NewBadgerEngineWithOptions(opts)
Monitoring Memory Usage¶
Container Stats¶
NornicDB Metrics¶
# Memory metrics endpoint
curl http://localhost:7474/metrics | grep memory
# Key metrics:
# - go_memstats_alloc_bytes: Current allocations
# - go_memstats_sys_bytes: Total memory from OS
# - badger_lsm_size_bytes: LSM tree size
# - badger_vlog_size_bytes: Value log size
Health Check¶
# Check if NornicDB is healthy
curl http://localhost:7474/health
# Response includes memory info
{
"status": "healthy",
"memory": {
"allocated": "45MB",
"system": "120MB",
"gc_pause_ns": 1234567
}
}
Troubleshooting¶
Still Running Out of Memory¶
-
Check actual usage:
-
Lower GC target:
-
Disable features:
-
Use swap (last resort):
Performance Too Slow¶
Low memory mode prioritizes RAM over speed. If performance is unacceptable:
- Increase available memory and disable low memory mode
- Use SSD storage to compensate for reduced caching
- Optimize queries to reduce memory pressure
- Consider horizontal scaling with multiple instances
WAL Growing Despite Low Memory Mode¶
WAL growth is managed separately from memory mode. Ensure auto-compaction is enabled:
Best Practices¶
Do ✅¶
- Use
NORNICDB_LOW_MEMORY=truefor containers with < 4GB RAM - Set
GOGC=100(or lower) alongside low memory mode - Use external embedding services (Ollama) instead of local models
- Monitor memory usage with
docker stats - Enable WAL auto-compaction
Don't ❌¶
- Don't enable both
LOW_MEMORYandHIGH_PERFORMANCE - Don't load large embedding models (>500MB) in low memory mode
- Don't disable WAL compaction (causes disk bloat)
- Don't set memory limits below 512MB
Related Documentation¶
- WAL Compaction - Automatic disk space management
- Docker Deployment - Complete Docker guide
- Raspberry Pi - Edge deployment guide
- Performance Benchmarks - Performance comparison
Memory issues? → Troubleshooting Guide
Need more performance? → Consider upgrading to a system with 8GB+ RAM