Prometheus Distributed Client
A Prometheus metrics client with persistent storage backends (Redis or SQLite) for short-lived processes and distributed systems.
Why Use This?
The official prometheus_client stores metrics in memory, which doesn't work well for:
- Short-lived processes that exit before Prometheus can scrape them or cannot expose a
/metricsendpoint - Multiprocess applications (web servers with multiple workers, parallel jobs, task queues)
- Distributed systems where multiple instances need to share metrics
- Serverless functions that need metrics to persist across invocations
This library solves these problems by storing metrics in Redis or SQLite, allowing:
- ✅ Short-lived processes can write metrics without running an HTTP server
- ✅ Multiprocess applications can aggregate metrics efficiently in one place
- ✅ Metrics persist across process boundaries and restarts
- ✅ Multiple processes can update the same metrics atomically
- ✅ Separate HTTP server can serve metrics from storage
- ✅ Automatic TTL/expiration to prevent stale data
- ✅ Full compatibility with Prometheus exposition format
Installation
pip install prometheus-distributed-client
For Redis backend:
pip install prometheus-distributed-client redis
For SQLite backend (included in Python standard library):
pip install prometheus-distributed-client
Quick Start
Redis Backend
from redis import Redis
from prometheus_client import CollectorRegistry, generate_latest
from prometheus_distributed_client import setup
from prometheus_distributed_client.redis import Counter, Gauge, Histogram
# Setup Redis backend
setup(
redis=Redis(host='localhost', port=6379),
redis_prefix='myapp',
redis_expire=3600 # TTL in seconds
)
# Create registry and metrics
REGISTRY = CollectorRegistry()
requests = Counter(
'http_requests_total',
'Total HTTP requests',
['method', 'endpoint'],
registry=REGISTRY
)
# Use metrics in your application
requests.labels(method='GET', endpoint='/api/users').inc()
# Serve metrics (in separate process or same)
print(generate_latest(REGISTRY).decode('utf8'))
SQLite Backend
import sqlite3
from prometheus_client import CollectorRegistry, generate_latest
from prometheus_distributed_client import setup
from prometheus_distributed_client.sqlite import Counter, Gauge, Histogram
# Setup SQLite backend (no TTL or prefix needed)
setup(sqlite='metrics.db') # or setup(sqlite=sqlite3.connect(':memory:'))
# Use exactly like Redis backend
REGISTRY = CollectorRegistry()
requests = Counter('http_requests_total', 'Total requests', registry=REGISTRY)
requests.inc()
Key Difference: TTL Behavior
- Redis: Uses TTL to prevent pollution in the shared central database
- SQLite: No TTL needed - file-based storage is automatically cleaned up when the file is deleted (e.g., container restart)
Supported Metric Types
All standard Prometheus metric types are supported:
- Counter: Monotonically increasing values
- Gauge: Values that can go up or down
- Summary: Observations with count and sum
- Histogram: Observations in configurable buckets
Architecture
Storage Format
Both backends use a unified storage format that prevents component desynchronization:
Redis:
Key: prometheus_myapp_requests
Fields:
_total:{"method":"GET","endpoint":"/api"} → 42
_created:{"method":"GET","endpoint":"/api"} → 1234567890.0
SQLite:
metric_key | subkey | value
------------------------+-------------------------------------------+-------------
requests | _total:{"method":"GET","endpoint":"/api"} | 42
requests | _created:{"method":"GET","endpoint":"/api"}| 1234567890.0
This design ensures:
- All metric components share the same key/row
- TTL applies atomically to the entire metric (Redis only)
- No desynchronization between
_total,_created, etc.
Comparison with Alternatives
vs Pushgateway
The Prometheus Pushgateway is another solution for short-lived processes, but has limitations:
| Feature | prometheus-distributed-client | Pushgateway |
|---|---|---|
| Multiple processes updating same metric | ✅ Atomic updates | ❌ Last write wins |
| Automatic metric expiration | ✅ Configurable TTL | ❌ Manual deletion |
| Label-based updates | ✅ Supports all labels | ⚠️ Can overwrite groups |
| Storage backend | Redis or SQLite | In-memory |
| Deployment complexity | Library (no extra service) | Requires separate service |
vs Multiprocess Mode
For multiprocess applications (e.g., Gunicorn with multiple workers), prometheus-distributed-client provides:
- ✅ Centralized storage: All metrics in one place (Redis or SQLite)
- ✅ Simple collection: Single
/metricsendpoint to scrape - ✅ Atomic updates: Race-free increments across processes
- ✅ Easy cleanup: Automatic TTL-based expiration
- ✅ Better observability: Query metrics directly from storage for debugging
Advanced Usage
Custom TTL (Redis Only)
# Short TTL for transient metrics
setup(redis=redis, redis_expire=60) # 1 minute
# Long TTL for important metrics
setup(redis=redis, redis_expire=86400) # 24 hours
# Note: SQLite doesn't use TTL
Multiple Applications Sharing Backend
# Application 1
setup(redis=redis, redis_prefix='app1')
# Application 2
setup(redis=redis, redis_prefix='app2')
# Metrics are isolated by prefix
Flask Integration
from flask import Flask
from prometheus_client import generate_latest
app = Flask(__name__)
@app.route('/metrics')
def metrics():
return generate_latest(REGISTRY)
Manual Cleanup (SQLite)
SQLite doesn't use TTL. To manually clean up metrics:
# Clear all metrics
conn = get_sqlite_conn()
cursor = conn.cursor()
cursor.execute("DELETE FROM metrics")
conn.commit()
# Or delete the database file
import os
os.remove('metrics.db')
Testing
The library includes comprehensive test suites for both backends:
# Install dependencies
poetry install
# Run all tests
make test
# Run specific backend tests
poetry run pytest tests/redis_test.py -v
poetry run pytest tests/sqlite_test.py -v
For Redis tests, create .redis.json:
{
"host": "localhost",
"port": 6379,
"db": 0
}
Performance Considerations
Redis
- Pros: Atomic operations, high performance, distributed, shared across applications
- Cons: Requires Redis server, network latency, needs TTL to prevent pollution
- Best for: Distributed systems, high concurrency, shared metrics collection
- TTL: Required (default 3600s) to prevent stale metrics in shared database
SQLite
- Pros: No external dependencies, simple deployment, no TTL complexity
- Cons: File locking, less concurrent performance, not shared across hosts
- Best for: Single-server applications, embedded systems, Docker containers
- TTL: Not needed - file cleanup happens on container restart/file deletion
Development
# Install dependencies
poetry install
# Run linters
make lint
# Build package
make build
# Publish to PyPI
make publish
License
GPLv3 - See LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Credits
Built by François Schmidts and contributors.
Based on the official prometheus_client.
Metadata
Release files for prometheus-distributed-client 2.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| prometheus_distributed_client-2.1.5.tar.gz | 21.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| prometheus_distributed_client-2.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.5 kB
Release files / prometheus_distributed_client-2.1.5.tar.gz
| Download URL | prometheus_distributed_client-2.1.5.tar.gz |
|---|---|
| Size | 21.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fa86f234699ac2762873b5e72f544fe30a09965c2aaae7abcb034178ef6beaa3
|
|
BLAKE2b-256 checksum How to use checksums |
284c08838a91d8192ae41e9750e7a5d32fac0f30d090db721bd260a2b1595e5e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.3.2 CPython/3.14.2 Linux/6.18.8-200.fc43.x86_64
|
Release files / prometheus_distributed_client-2.1.5-py3-none-any.whl
| Download URL | prometheus_distributed_client-2.1.5-py3-none-any.whl |
|---|---|
| Size | 21.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
47fe31afb689101ea84a874a5b39eec81181de4f6c4a598307508fc74d8a110e
|
|
BLAKE2b-256 checksum How to use checksums |
d45e1253487f591e4c6a569bfc001ae5e40c2a25c75448ec8f0a2372276a8b15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.3.2 CPython/3.14.2 Linux/6.18.8-200.fc43.x86_64
|
Security for prometheus-distributed-client 2.1.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.