DLR Processor — Deployment Topology
Status: populated Owner: Platform Engineering Last updated: 2026-04-18 Companion: LOCAL_DEV_SETUP · OBSERVABILITY
1. Kubernetes Workload
apiVersion: apps/v1
kind: Deployment
metadata:
name: dlr-processor
namespace: sms-gateway
spec:
replicas: 3
selector:
matchLabels:
app: dlr-processor
template:
spec:
containers:
- name: dlr-processor
image: ghasi/dlr-processor:latest
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet: { path: /health, port: 3000 }
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet: { path: /ready, port: 3000 }
initialDelaySeconds: 5
periodSeconds: 10
envFrom:
- secretRef: { name: dlr-processor-secrets }
- configMapRef: { name: dlr-processor-config }
2. Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: dlr-processor-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: dlr-processor
minReplicas: 3
maxReplicas: 10
metrics:
- type: External
external:
metric:
name: nats_consumer_pending_messages
selector:
matchLabels:
consumer: dlr-processor
target:
type: AverageValue
averageValue: "500"
Scale-out trigger: NATS dlr-processor consumer pending message count > 500 per replica.
3. Network Topology
[NATS JetStream Cluster] ──(internal)──► dlr-processor pods
dlr-processor pods ──(internal PG)────► PostgreSQL (orch + dlr schemas)
dlr-processor pods ──(internal NATS)──► billing.events, webhook.dispatch, sms.dlr.unmatched
No inbound internet traffic. No Kong route. No public endpoint.
4. Environment Variables
| Variable | Description | Example |
|---|---|---|
NATS_URL | NATS server URL(s) | nats://nats:4222 |
NATS_STREAM_DLR | JetStream stream name | SMS_DLR |
DATABASE_URL | PostgreSQL connection string | postgresql://dlr_svc:***@pg:5432/ghasi |
DB_POOL_MIN | Min connection pool size | 5 |
DB_POOL_MAX | Max connection pool size | 20 |
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP collector | http://otel-collector:4318 |
LOG_LEVEL | Pino log level | info |
PORT | HTTP probe port | 3000 |
5. Multi-Region Considerations
In active-active multi-region deployments:
- Each region runs its own
dlr-processorreplica set. - NATS geo-replicated stream ensures each region's processors see all DLRs.
- PostgreSQL cross-region writes must route to the primary via service mesh (Consul Connect or Linkerd).
- Orphan reconciliation job is single-region (runs in primary region only).
6. Secrets Management
Secrets stored in HashiCorp Vault; injected via Vault Agent sidecar as Kubernetes Secrets at pod start. Rotation: 90-day automated schedule.