QuestDB Real-time Analytics
QuestDB time-series database with Grafana dashboards.
Overview
QuestDB is a high-performance, open-source time-series database designed for real-time analytics and IoT applications. Built from the ground up in Java and C++, QuestDB leverages columnar storage and vectorized execution to deliver exceptional ingestion rates (over 4 million rows per second) and sub-millisecond query performance. It supports both SQL queries and the InfluxDB Line Protocol for data ingestion, making it compatible with existing monitoring tools and applications. This stack combines QuestDB's powerful time-series capabilities with Grafana's visualization platform and NGINX as a reverse proxy. QuestDB handles high-frequency data ingestion through its ILP port while serving analytical queries via its PostgreSQL wire protocol, Grafana connects directly to QuestDB to create real-time dashboards and alerting, and NGINX provides load balancing and SSL termination for production deployments. This architecture enables organizations to collect, store, and visualize massive amounts of time-series data with minimal latency. DevOps engineers building monitoring infrastructure, IoT developers processing sensor data, and financial institutions tracking market data will find this combination particularly valuable. QuestDB's unique approach to time-series storage, combined with Grafana's extensive visualization options and NGINX's proven reliability, creates a robust analytics platform that scales from startup prototypes to enterprise-grade deployments handling billions of data points daily.
Key Features
- QuestDB's columnar storage engine with SIMD-optimized queries for sub-millisecond response times
- Native InfluxDB Line Protocol support on port 9009 for high-frequency data ingestion
- PostgreSQL wire protocol compatibility enabling direct Grafana data source connections
- QuestDB's built-in web console for interactive SQL queries and database management
- Grafana's time-series specific visualizations including time series panels and stat panels
- NGINX reverse proxy configuration for load balancing across QuestDB instances
- QuestDB's automatic data partitioning by time intervals for optimized storage and queries
- Grafana alerting integration with QuestDB's real-time query capabilities
Common Use Cases
- 1IoT sensor data collection and real-time monitoring dashboards for manufacturing facilities
- 2Financial market data ingestion and trading analytics with millisecond-latency requirements
- 3Application performance monitoring with high-cardinality metrics and custom Grafana panels
- 4Infrastructure monitoring collecting system metrics from thousands of servers
- 5Real-time business intelligence dashboards for e-commerce transaction analysis
- 6Cryptocurrency trading platforms requiring high-frequency price data storage and visualization
- 7Smart city initiatives processing traffic, environmental, and utility sensor data
Prerequisites
- Docker Engine 20.10+ and Docker Compose 2.0+ for container orchestration
- Minimum 2GB RAM available (QuestDB: 512MB, Grafana: 512MB, NGINX: 256MB)
- Ports 9000, 8812, 9009, 3000, and 80 available on the host system
- Basic understanding of SQL queries and time-series data concepts
- Familiarity with Grafana dashboard creation and data source configuration
- Understanding of InfluxDB Line Protocol format for data ingestion
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 questdb: 3 image: questdb/questdb:latest4 container_name: questdb5 restart: unless-stopped6 ports: 7 - "${QDB_HTTP_PORT:-9000}:9000"8 - "${QDB_PG_PORT:-8812}:8812"9 - "${QDB_ILP_PORT:-9009}:9009"10 volumes: 11 - questdb_data:/var/lib/questdb1213 grafana: 14 image: grafana/grafana:latest15 container_name: qdb-grafana16 restart: unless-stopped17 ports: 18 - "${GRAFANA_PORT:-3000}:3000"19 environment: 20 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}21 volumes: 22 - grafana_data:/var/lib/grafana2324 nginx: 25 image: nginx:alpine26 container_name: qdb-nginx27 restart: unless-stopped28 ports: 29 - "${NGINX_PORT:-80}:80"30 volumes: 31 - ./nginx.conf:/etc/nginx/nginx.conf:ro3233volumes: 34 questdb_data: 35 grafana_data: .env Template
.env
1# QuestDB Analytics2QDB_HTTP_PORT=90003QDB_PG_PORT=88124QDB_ILP_PORT=90095GRAFANA_PORT=30006GRAFANA_PASSWORD=admin7NGINX_PORT=80Usage Notes
- 1QuestDB Console at http://localhost:9000
- 2PostgreSQL wire on port 8812
- 3ILP for high-frequency inserts on 9009
- 4Grafana at http://localhost:3000
Individual Services(3 services)
Copy individual services to mix and match with your existing compose files.
questdb
questdb:
image: questdb/questdb:latest
container_name: questdb
restart: unless-stopped
ports:
- ${QDB_HTTP_PORT:-9000}:9000
- ${QDB_PG_PORT:-8812}:8812
- ${QDB_ILP_PORT:-9009}:9009
volumes:
- questdb_data:/var/lib/questdb
grafana
grafana:
image: grafana/grafana:latest
container_name: qdb-grafana
restart: unless-stopped
ports:
- ${GRAFANA_PORT:-3000}:3000
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- grafana_data:/var/lib/grafana
nginx
nginx:
image: nginx:alpine
container_name: qdb-nginx
restart: unless-stopped
ports:
- ${NGINX_PORT:-80}:80
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 questdb:5 image: questdb/questdb:latest6 container_name: questdb7 restart: unless-stopped8 ports:9 - "${QDB_HTTP_PORT:-9000}:9000"10 - "${QDB_PG_PORT:-8812}:8812"11 - "${QDB_ILP_PORT:-9009}:9009"12 volumes:13 - questdb_data:/var/lib/questdb1415 grafana:16 image: grafana/grafana:latest17 container_name: qdb-grafana18 restart: unless-stopped19 ports:20 - "${GRAFANA_PORT:-3000}:3000"21 environment:22 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}23 volumes:24 - grafana_data:/var/lib/grafana2526 nginx:27 image: nginx:alpine28 container_name: qdb-nginx29 restart: unless-stopped30 ports:31 - "${NGINX_PORT:-80}:80"32 volumes:33 - ./nginx.conf:/etc/nginx/nginx.conf:ro3435volumes:36 questdb_data:37 grafana_data:38EOF3940# 2. Create the .env file41cat > .env << 'EOF'42# QuestDB Analytics43QDB_HTTP_PORT=900044QDB_PG_PORT=881245QDB_ILP_PORT=900946GRAFANA_PORT=300047GRAFANA_PASSWORD=admin48NGINX_PORT=8049EOF5051# 3. Start the services52docker compose up -d5354# 4. View logs55docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/questdb-realtime-stack/run | bashTroubleshooting
- QuestDB 'cairo.exception.CairoException: could not open read-only': Ensure questdb_data volume has correct permissions (chown 10001:10001)
- Grafana 'Bad Gateway' when connecting to QuestDB: Verify QuestDB PostgreSQL port 8812 is accessible and use 'questdb:8812' as host in data source
- High memory usage during QuestDB ingestion: Increase commit lag settings in QuestDB configuration or reduce batch sizes in ILP client
- QuestDB queries timing out in Grafana: Add query timeout parameters and consider adding time range filters to dashboard queries
- NGINX 502 errors: Check that upstream QuestDB and Grafana containers are running and healthy using docker ps
- QuestDB ILP ingestion failures: Verify client is sending properly formatted InfluxDB Line Protocol and check QuestDB logs for parsing errors
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Ad Space
Shortcuts: C CopyF FavoriteD Download