Skip to content

Case study · Cost & latency & Observability

520 million parameters every 15 minutes

A configuration-driven telecom data platform processing 200M configuration and 320M performance parameters per 15-minute cycle on Golang, Kafka, Kubernetes and PostgreSQL. The project that shaped how I think about bounded resources — and why I trust it more than any AI credential I have.

Sustained ingestion
520M / 15 min
My role
Technical Lead — architecture, backend, performance
Stack
GolangApache KafkaKubernetesPostgreSQLOracleAzure Data ExplorerTemporal

What broke

Throughput was fine in steady state and collapsed on late-arriving batches. The pipeline had no backpressure — it had optimism, which is a different thing.

This is not an AI project, and it is the one I would point to first if you wanted to know whether I can be trusted with a production system.

A telecom operator needed configuration management (CM) and performance management (PM) data from network equipment ingested, transformed, and landed in analytical stores on a fixed 15-minute cycle. 200 million configuration parameters and 320 million performance parameters per cycle — 520 million in total, every quarter hour, indefinitely.

The hard constraint was not volume. It was that the cycle is fixed. If a 15-minute batch takes 16 minutes, you do not have a slow pipeline; you have a queue that grows forever.

The part that mattered: configuration, not code

New telecom data sources arrived constantly, each with its own format, transformation rules and destination. The naive path is a new pipeline per source, which becomes a codebase nobody can change safely.

Instead the platform read source connectors, processing logic, transformation rules and destination connectors from configuration and assembled the pipeline at runtime. Onboarding a new data source became a config change with metadata in PostgreSQL, not a deployment.

Architecture

One framework, many pipelines, assembled from config

Every stage is bounded. The interesting decisions are about what happens when a stage cannot keep up — because at this cadence, something eventually cannot.

Select a stage to see the decision made there.

01 Pipeline configPostgreSQL metadata

Source definitions, field mappings, transformation rules and destinations live as metadata. A new pipeline is a row set, not a release. This is the decision the whole platform rests on.

Tradeoff: A config-driven framework is harder to reason about than explicit code — a bug can come from data rather than logic. We paid for that with strict config validation on write and a dry-run mode.

What broke

Steady state was comfortable. Then a network region delivered a delayed batch, and the pipeline received roughly two cycles of data inside one cycle window.

Throughput did not degrade gracefully — it collapsed. Workers accepted everything they were handed, memory pressure rose, Kubernetes started evicting pods, evicted work was redelivered, and redelivery added load to an already overloaded system. A 20% input spike produced an outage, which is the signature of a system with no backpressure.

The fix was unglamorous and is the lesson I carry into every agent system I now look at:

  • Bound every queue and buffer explicitly. An unbounded buffer is a delayed crash.
  • Reject or shed load rather than accept work you cannot finish. Refusing work is a valid, observable behaviour. Accepting it and dying is not.
  • Make redelivery idempotent, or retries amplify the incident that caused them.
  • Alert on the trend, not the threshold. Cycle time creeping from 9 to 12 minutes is the actionable signal; hitting 15 is the incident.

Why this is on a page about AI agents

Everything in that list applies directly to agent systems, and almost none of it is being applied.

An agent run with no step ceiling is an unbounded queue. An agent that retries a failing tool without backoff is redelivery amplification. An agent system with no per-run token budget is a pipeline that accepts work it cannot afford to finish. A cost alert that fires at the monthly budget is alerting at the threshold instead of the trend.

The AI industry is rediscovering, expensively, what data engineering learned in the 2010s. When I say I make agents survive production, this is the experience I am drawing on — the failure taxonomy is largely these same lessons, translated.

Numbers

  • 520M parameters per 15-minute cycle sustained — 200M CM, 320M PM.
  • New data sources onboarded via configuration, with no application deployment.
  • Cycle-time headroom maintained deliberately, so a delayed batch is absorbed rather than amplified.