# Tikker Performance Optimization Guide
## Performance Benchmarks
Baseline performance metrics on standard hardware (2CPU, 2GB RAM):
### API Service (C Tools Integration)
- Health Check: ~15ms (p50), <50ms (p99)
- Daily Stats: ~80ms (p50), <150ms (p99)
- Top Words: ~120ms (p50), <250ms (p99)
- Throughput: ~40-60 req/s
### AI Service
- Health Check: ~10ms (p50), <50ms (p99)
- Text Analysis: ~2-5s (depends on text length and API availability)
- Throughput: ~0.5 req/s (limited by OpenAI API)
### Visualization Service
- Health Check: ~12ms (p50), <50ms (p99)
- Bar Chart: ~150ms (p50), <300ms (p99)
- Line Chart: ~160ms (p50), <320ms (p99)
- Pie Chart: ~140ms (p50), <280ms (p99)
- Throughput: ~5-8 req/s
## Running Benchmarks
### Quick Benchmark
```bash
python scripts/benchmark.py
```
### Benchmark Against Remote Server
```bash
python scripts/benchmark.py http://production-server
```
### Detailed Test Results
```bash
pytest tests/test_performance.py -v --tb=short
```
## Optimization Strategies
### 1. Database Optimization
#### Vacuum Database
Regular database maintenance improves query performance.
```bash
docker-compose exec api sqlite3 tikker.db "VACUUM;"
```
Impact: 5-15% query speed improvement
#### Create Indexes
Add indexes for frequently queried columns:
```sql
CREATE INDEX idx_words_frequency ON words(frequency DESC);
CREATE INDEX idx_events_timestamp ON events(timestamp);
CREATE INDEX idx_events_date ON events(date);
```
Impact: 30-50% improvement for indexed queries
#### Query Optimization
Use EXPLAIN QUERY PLAN to analyze slow queries:
```bash
sqlite3 tikker.db "EXPLAIN QUERY PLAN SELECT * FROM words ORDER BY frequency LIMIT 10;"
```
### 2. Caching Strategies
#### Redis Caching for Frequent Queries
Add Redis for popular word list caching:
```python
import redis
cache = redis.Redis(host='localhost', port=6379)
def get_top_words(limit=10):
key = f"top_words:{limit}"
cached = cache.get(key)
if cached:
return json.loads(cached)
result = query_database(limit)
cache.setex(key, 3600, json.dumps(result))
return result
```
Impact: 10-100x improvement for cached queries
#### Add to docker-compose.yml:
```yaml
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
```
### 3. Python Optimization
#### Enable Optimization
```dockerfile
ENV PYTHONOPTIMIZE=2
ENV PYTHONDONTWRITEBYTECODE=1
```
#### Use Async I/O
Current API already uses FastAPI (async), good baseline.
#### Profile Code
Identify bottlenecks:
```bash
python -m cProfile -s cumtime -m pytest tests/test_services.py
```
### 4. C Tools Optimization
#### Compile Flags
Update Makefile with optimization flags:
```makefile
CFLAGS = -O3 -march=native -Wall -Wextra
```
Impact: 20-40% improvement in execution speed
#### Binary Stripping
Reduce binary size:
```bash
strip build/bin/tikker-*
```
Impact: Faster loading, reduced disk I/O
### 5. Network Optimization
#### Connection Pooling
Add HTTP connection pooling in wrapper:
```python
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
```
#### Service Co-location
Run services on same host to reduce latency:
- Typical inter-service latency: ~5-10ms
- Same-host latency: <1ms
### 6. Memory Optimization
#### Monitor Memory Usage
```bash
docker stats
# Or detailed analysis
docker-compose exec api ps aux
```
#### Reduce Buffer Sizes
In c_tools_wrapper.py:
```python
# Limit concurrent subprocess calls
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(max_workers=4)
```
#### Garbage Collection Tuning
```python
import gc
gc.set_threshold(10000)
```
### 7. Container Resource Limits
Update docker-compose.yml:
```yaml
services:
api:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
```
### 8. Load Balancing
For production deployments with multiple instances:
```yaml
nginx:
image: nginx:latest
ports:
- "8000:8000"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- api1
- api2
- api3
```
nginx.conf:
```nginx
upstream api {
server api1:8000;
server api2:8000;
server api3:8000;
}
server {
listen 8000;
location / {
proxy_pass http://api;
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
}
}
```
## Performance Tuning Checklist
- [ ] Database vacuumed and indexed
- [ ] Python optimization flags enabled
- [ ] C compilation optimizations applied
- [ ] Connection pooling configured
- [ ] Caching strategy implemented
- [ ] Memory limits set appropriately
- [ ] Load balancing configured (if needed)
- [ ] Monitoring and logging enabled
- [ ] Benchmarks show acceptable latency
- [ ] Throughput meets SLA requirements
## Monitoring Performance
### Key Metrics to Track
1. **Latency (p50, p95, p99)**
- Target: p50 <100ms, p99 <500ms
2. **Throughput (req/s)**
- Target: >20 req/s per service
3. **Error Rate**
- Target: <0.1%
4. **Resource Usage**
- CPU: <80% sustained
- Memory: <80% allocated
- Disk: <90% capacity
### Prometheus Metrics
Add to FastAPI apps:
```python
from prometheus_client import Counter, Histogram, generate_latest
request_count = Counter('api_requests_total', 'Total requests')
request_duration = Histogram('api_request_duration_seconds', 'Request duration')
@app.middleware("http")
async def add_metrics(request, call_next):
start = time.time()
response = await call_next(request)
duration = time.time() - start
request_count.inc()
request_duration.observe(duration)
return response
@app.get("/metrics")
def metrics():
return generate_latest()
```
## Troubleshooting Performance Issues
### High CPU Usage
1. Profile code: `python -m cProfile`
2. Check for infinite loops in C tools
3. Reduce concurrent operations
### High Memory Usage
1. Monitor with `docker stats`
2. Check for memory leaks in C code
3. Implement garbage collection tuning
4. Use connection pooling
### Slow Queries
1. Run EXPLAIN QUERY PLAN
2. Add missing indexes
3. Verify statistics are current
4. Consider query rewriting
### Network Latency
1. Check service co-location
2. Verify DNS resolution
3. Monitor with `tcpdump`
4. Consider service mesh (istio)
### Database Lock Issues
1. Check for long-running transactions
2. Verify concurrent access limits
3. Consider read replicas
4. Increase timeout values
## Advanced Optimization
### Async Database Access
Consider async SQLite driver for true async I/O:
```python
from aiosqlite import connect
async def get_stats():
async with connect('tikker.db') as db:
cursor = await db.execute('SELECT * FROM events')
return await cursor.fetchall()
```
### Compiled C Extensions
Convert performance-critical Python code to C extensions:
```c
// stats.c
PyObject* get_daily_stats(PyObject* self, PyObject* args) {
// High-performance C implementation
}
```
### Graph Query Optimization
For complex analyses, consider graph database:
```
Events → Words → Patterns
Analysis becomes graph traversal instead of SQL joins
```
## SLA Targets
Recommended SLA targets for Tikker:
| Metric | Target | Priority |
|--------|--------|----------|
| API Availability | 99.5% | Critical |
| Health Check Latency | <50ms | Critical |
| Stats Query Latency | <200ms | High |
| Word Search Latency | <300ms | High |
| Report Generation | <5s | Medium |
| AI Analysis | <10s | Low |
## Performance Testing in CI/CD
Add performance regression testing:
```bash
# Run baseline benchmark
python scripts/benchmark.py baseline
# Run benchmark
python scripts/benchmark.py current
# Compare and fail if regression
python scripts/compare_benchmarks.py baseline current --fail-if-slower 10%
```
## Further Reading
- SQLite Performance: https://www.sqlite.org/bestcase.html
- FastAPI Performance: https://fastapi.tiangolo.com/
- Python Optimization: https://docs.python.org/3/library/profile.html