-
Notifications
You must be signed in to change notification settings - Fork 1
HTTP2_SERVER_PUSH_CDC
HTTP/2 Server Push enables proactive delivery of CDC (Change Data Capture) events to clients without polling. This significantly reduces latency and bandwidth compared to traditional polling-based approaches.
┌─────────────────────────────────────────────┐
│ HTTP/2 Client (Browser/App) │
│ │
│ 1. Subscribe: GET /cdc/subscribe │
└──────────────────┬──────────────────────────┘
│
│ HTTP/2 Connection
│ (TLS with ALPN "h2")
▼
┌─────────────────────────────────────────────┐
│ ThemisDB HTTP/2 Server │
│ │
│ 2. Track subscribed streams │
│ 3. On DB change: Broadcast Server Push │
└──────────────────┬──────────────────────────┘
│
│ PUSH_PROMISE + Pushed Response
│ Path: /cdc/event/{sequence}
▼
┌─────────────────────────────────────────────┐
│ HTTP/2 Client Receives Event │
│ │
│ Response Body: CDC Event JSON │
│ { │
│ "type": "cdc_event", │
│ "sequence": 123, │
│ "key": "user:1001", │
│ "value": {...}, │
│ "operation": "PUT" │
│ } │
└─────────────────────────────────────────────┘
Request:
GET /cdc/subscribe HTTP/2
Host: localhost:8443Response:
{
"status": "subscribed",
"message": "HTTP/2 Server Push enabled for CDC events"
}When a database change occurs, the server automatically pushes events:
Push Promise:
PUSH_PROMISE Frame
Stream ID: 1 (client stream)
Promised Stream ID: 2 (server push)
:method: GET
:path: /cdc/event/123
:scheme: https
:authority: localhost
Pushed Response:
HTTP/2 200
content-type: application/json
x-cdc-sequence: 123
{
"type": "cdc_event",
"sequence": 123,
"key": "user:1001",
"value": {
"name": "Alice",
"age": 30
},
"operation": "PUT",
"timestamp": "2025-12-18T18:00:00Z"
}Enable HTTP/2 Server Push in config.json:
{
"enable_tls": true,
"enable_http2": true,
"http2_max_concurrent_streams": 100,
"http2_initial_window_size": 65535,
"cdc_server_push_enabled": true
}// Modern browsers support HTTP/2 Server Push automatically
async function subscribeToCDC() {
const response = await fetch('/cdc/subscribe');
const data = await response.json();
console.log('Subscribed:', data.message);
// Pushed resources are automatically cached by browser
// Access them via Resource Timing API
performance.getEntriesByType('resource').forEach(entry => {
if (entry.name.includes('/cdc/event/')) {
console.log('CDC Event pushed:', entry.name);
}
});
}const http2 = require('http2');
const client = http2.connect('https://localhost:8443');
// Subscribe to CDC
const req = client.request({
':path': '/cdc/subscribe',
':method': 'GET'
});
req.on('response', (headers) => {
console.log('Subscribed to CDC');
});
// Handle Server Push
client.on('stream', (pushedStream, headers) => {
const path = headers[':path'];
if (path.startsWith('/cdc/event/')) {
let data = '';
pushedStream.on('data', (chunk) => {
data += chunk;
});
pushedStream.on('end', () => {
const event = JSON.parse(data);
console.log('CDC Event received:', event);
});
}
});
req.end();import httpx
import json
# HTTP/2 client
client = httpx.Client(http2=True)
# Subscribe to CDC
response = client.get('https://localhost:8443/cdc/subscribe')
print(f"Subscribed: {response.json()}")
# Note: Python httpx doesn't expose push promises directly
# Use WebSocket for Python CDC streaming instead# Subscribe and receive pushed events
curl --http2 https://localhost:8443/cdc/subscribe \
--verbose \
--output /dev/null \
--include
# Note: curl 7.57.0+ supports HTTP/2 Server Push
# Pushed resources are saved to disk automatically| Feature | HTTP/2 Server Push | WebSocket |
|---|---|---|
| Protocol | HTTP/2 over TLS | WebSocket over HTTP/1.1 or HTTP/2 |
| Connection | Reuses existing HTTP/2 | Separate WebSocket upgrade |
| Directionality | Server → Client only | Bidirectional |
| Browser Support | Automatic (transparent) | Requires WebSocket API |
| Latency | Low (push on change) | Very low (continuous) |
| Bandwidth | Efficient (no polling) | Very efficient (streaming) |
| Use Case | Occasional updates | Continuous streaming |
| Setup Complexity | Simple (standard HTTP/2) | Moderate (upgrade required) |
Recommendation:
- Use HTTP/2 Server Push for occasional CDC notifications with minimal client-side code
- Use WebSocket CDC for high-frequency updates or bidirectional communication
Client ----[Poll Request]----> Server (no changes)
Client <---[Empty Response]--- Server
Client ----[Poll Request]----> Server (no changes)
Client <---[Empty Response]--- Server
Client ----[Poll Request]----> Server (has changes!)
Client <---[CDC Event]-------- Server
Cost: 3 roundtrips, 2 wasted requests
Latency: Up to poll_interval
Client ----[Subscribe]-------> Server
Client <---[Subscribed]------- Server
... wait for actual changes ...
Client <====[PUSH: CDC Event]= Server (proactive!)
Cost: 1 roundtrip setup, 0 wasted requests
Latency: ~0ms (immediate on change)
Latency Improvement: 95%+ reduction (no polling delay)
Bandwidth Savings: 90%+ reduction (no empty poll responses)
ThemisDB uses nghttp2 library for HTTP/2 Server Push:
// Create push promise
int32_t promised_stream_id;
nghttp2_submit_push_promise(
session,
NGHTTP2_FLAG_NONE,
stream_id, // Client stream
promise_headers,
num_headers,
&promised_stream_id // Output: server push stream ID
);
// Send pushed response on promised stream
nghttp2_submit_response(
session,
promised_stream_id, // Push stream (even number)
response_headers,
num_headers,
&data_provider
);- Client streams: Odd numbers (1, 3, 5, 7, ...)
- Server push streams: Even numbers (2, 4, 6, 8, ...)
Each push creates a new server-initiated stream ID.
- TLS Required: Server Push only works over HTTPS (HTTP/2 requires TLS in browsers)
- ALPN Negotiation: "h2" must be negotiated during TLS handshake
-
Push Limits: Respect
http2_max_concurrent_streamssetting - Authorization: CDC subscription requires same auth as regular requests
Track Server Push performance:
{
"http2_server_push": {
"total_push_promises": 12345,
"total_pushed_responses": 12345,
"active_cdc_subscriptions": 42,
"push_errors": 0,
"average_push_latency_ms": 5.2
}
}[INFO] HTTP/2 stream 1 subscribed to CDC with Server Push
[DEBUG] HTTP/2 Server Push promise created for stream 1, promised stream 2
[DEBUG] HTTP/2 Server Push sent CDC event to stream 1, sequence 123
Check:
- HTTPS enabled (
enable_tls: true) - HTTP/2 enabled (
THEMIS_ENABLE_HTTP2=ON) - ALPN negotiated "h2" (check logs)
- Client supports HTTP/2 Server Push (modern browsers do)
Cause: Client sent SETTINGS_ENABLE_PUSH: 0
Solution: Client must enable push in SETTINGS frame
Cause: Exceeded http2_max_concurrent_streams
Solution: Increase limit or close inactive streams
- RFC 9113: HTTP/2 - Section 8.4 Server Push
- nghttp2 Documentation
- MDN: HTTP/2 Server Push
- Add push cache control headers
- Implement push promise validation
- Add push rate limiting per client
- Create dashboard for monitoring push metrics
- Add support for filter-based push (only specific keys)
- Architecture-ACCESS-MODEL-IMPLEMENTATION-SUMMARY
- Architecture-ADR-003-pg-dump-sql-parser
- Architecture-BASEENTITY-PRINCIPLE
- Architecture-CACHE-STORAGE-INTEGRATION
- Architecture-CMAKE-ARCHITECTURE
- Architecture-CMAKE-FLAGS-REFERENCE
- Architecture-CMAKE-MODULAR-ARCHITECTURE
- Architecture-CONCERNS-ARCHITECTURE-DIAGRAM
- Architecture-CONCERNS-IMPLEMENTATION-SUMMARY
- Architecture-CONTENT-MODEL
- Architecture-COPILOT-THEMISDB-GRAPH-RAG-BACKEND-ARCHITECTURE
- Architecture-CRYPTO-AND-KEYS
- Architecture-FEATURE-FLAGS-REFERENCE
- Architecture-GPU-ARCHITECTURE-REVIEW-TEMPLATE
- Architecture-HTTP-SHUTDOWN-HARDENING
- Architecture-MIGRATION-GUIDE-CONCERNS
- Architecture-MIGRATION-GUIDE-v13-v14
- Architecture-MODULARIZATION-GUIDE
- Architecture-MODULAR-ARCHITECTURE-ROADMAP
- Architecture-MODULE-ARCHITECTURE-INDEX
- Architecture-P1D01-ISSMPLUGIN-DESIGN-REVIEW
- Architecture-P1-D01-ISSMPLUGIN-DESIGN-REVIEW
- Architecture-P1-D08-MAMBA-GOVERNANCE-CONTRACT
- Architecture-P1-P2-IMPLEMENTATION-COMPLETION-INDEX
- Architecture-PHASE0-COMPLETION-ASSESSMENT
- Architecture-PHASE3-QUERYENGINE-DI-ARCHITECTURE
- Architecture-PHASE4-INDEX-MANAGER-DI
- Architecture-POSTGRESQL-WIRE-PROTOCOL
- Architecture-QUERYENGINE-IMPLEMENTATION-GUIDE
- Architecture-QUERY-SCHEDULING
- Architecture-RAFT-CONSENSUS-DESIGN
- Architecture-README
- Architecture-README-SSM-HYBRID-IMPLEMENTATION
- Architecture-REFACTORING-SUMMARY
- Architecture-RESOURCE-POOLING
- Architecture-SOURCE-DIRECTORY-GUIDE
- Architecture-THEMIS-CORE-GUIDE
- Architecture-UNIFIED-ACCESS-MODEL
- Architecture-WAL-GRPC-MTLS-CONFIGURATION
- Architecture-WIRE-PROTOCOL-RETRY
- Architecture-boltzmann-observability-draft
- Architecture-experimental-logarithmic-vector-storage
- Architecture-llm-wiki-mvp-adr
- Architecture-rewrite-engine-architecture
- Architecture-rope-api-architecture
- Architecture-ssm-gguf-mamba-status
- Architecture-ssm-hybrid-analysis
- Architecture-ssm-hybrid-rollout-plan
- Architecture-ssm-plugin-interface-design-review
- Architecture-transaction-coordinators
- Architecture-wiki-secondary-index
- Architecture-wire-protocol
- Governance-DISABLED-STUB-POLICY
- Governance-DOCS-PR-POLICY
- Governance-GA-PROMOTION-SIGN-OFF
- Governance-GITHUB-MILESTONES-SETUP
- Governance-MATURITY-CLAIM-VERIFICATION-CHECKLIST
- Governance-MATURITY-EVIDENCE-REGISTRY
- Governance-MERGE-GATE-BOT-CONFIG
- Governance-MERGE-GATE-STATUS-LIVE
- Governance-PHASE3-ENFORCEMENT-RUNBOOK
- Governance-PHASE-1-CLOSURE-REPORT
- Governance-PHASE-CLOSURE-POLICY
- Governance-PHASE-DEPENDENCY-GRAPH
- Governance-PLUGIN-SUBMODULE-ROLLBACK
- Governance-PRODUCTION-READY-2026-DELIVERY-PLAN
- Governance-PR-VERSION-TARGETING
- Governance-PR-VERSION-TARGETING-BACKFILL
- Governance-QUERY-MODULE-STATUS
- Governance-README
- Governance-RELEASE-PROMOTION-GATE-POLICY
- Governance-RELEASE-VALIDATION-CHECKLIST
- Governance-SECURITY-MODULE-5671-EVIDENCE-SUMMARY
- Governance-SHARDING-P6-RESIDUAL-RISK-ACCEPTANCE
- Governance-SOURCECODE-COMPLIANCE-GOVERNANCE
- Governance-UPDATES-DEVELOPMENT-STATUS-SIGN-OFF
- Governance-WAVE-C-IMPLEMENTATION-COMPLETE
- Module-acceleration-Roadmap
- Module-access-model-Roadmap
- Module-ai-Roadmap
- Module-analytics-Roadmap
- Module-api-Roadmap
- Module-aql-Roadmap
- Module-auth-Roadmap
- Module-base-Roadmap
- Module-cache-Roadmap
- Module-cdc-Roadmap
- Module-chaos-Roadmap
- Module-chimera-Roadmap
- Module-config-Roadmap
- Module-content-Roadmap
- Module-core-Roadmap
- Module-distributed-knowledge-Roadmap
- Module-distributed-tensor-Roadmap
- Module-document-Roadmap
- Module-ethics-ai-Roadmap
- Module-evaluation-Roadmap
- Module-execution-Roadmap
- Module-exporters-Roadmap
- Module-failover-Roadmap
- Module-geo-Roadmap
- Module-governance-Roadmap
- Module-gpu-Roadmap
- Module-graph-Roadmap
- Module-image-analysis-Roadmap
- Module-importers-Roadmap
- Module-index-Roadmap
- Module-ingestion-Roadmap
- Module-llama-cpp-Roadmap
- Module-llm-Roadmap
- Module-llm-streaming-Roadmap
- Module-llm-wiki-Roadmap
- Module-maintenance-Roadmap
- Module-metadata-Roadmap
- Module-network-Roadmap
- Module-observability-Roadmap
- Module-onnx-clip-Roadmap
- Module-performance-Roadmap
- Module-plugins-Roadmap
- Module-process-Roadmap
- Module-projects-Roadmap
- Module-prompt-engineering-Roadmap
- Module-query-Roadmap
- Module-rag-Roadmap
- Module-replication-Roadmap
- Module-retrieval-Roadmap
- Module-rpc-grpc-Roadmap
- Module-scheduler-Roadmap
- Module-scraper-Roadmap
- Module-search-Roadmap
- Module-security-Roadmap
- Module-server-Roadmap
- Module-sharding-Roadmap
- Module-stable-diffusion-Roadmap
- Module-storage-Roadmap
- Module-temporal-Roadmap
- Module-tensor-Roadmap
- Module-themis-Roadmap
- Module-timeseries-Roadmap
- Module-toolbox-Roadmap
- Module-training-Roadmap
- Module-transaction-Roadmap
- Module-updates-Roadmap
- Module-user-storage-encrypted-Roadmap
- Module-utils-Roadmap
- Module-vector-search-Roadmap
- Module-voice-Roadmap
- Module-whisper-Roadmap