Skip to main content

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

VariableDescriptionExample
NATS_URLNATS server URL(s)nats://nats:4222
NATS_STREAM_DLRJetStream stream nameSMS_DLR
DATABASE_URLPostgreSQL connection stringpostgresql://dlr_svc:***@pg:5432/ghasi
DB_POOL_MINMin connection pool size5
DB_POOL_MAXMax connection pool size20
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collectorhttp://otel-collector:4318
LOG_LEVELPino log levelinfo
PORTHTTP probe port3000

5. Multi-Region Considerations

In active-active multi-region deployments:

  • Each region runs its own dlr-processor replica 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.