NebularStack
Website

Backend Implementation Ideas

This is an example architecture, a way to conceptualize how you could build a scalable platform around lunar, not a prescription. lunar imposes almost nothing on your backend. It simply calls your HTTP API for configuration and decisions (see the RADIUS Integration guide), so you are free to build the backend however suits your stack. What follows is one proven shape that scales cleanly from a single box to a region-wide platform.

An example scalable architecture

/static/lunar/radius/design.png

The key idea is to split the two very different workloads lunar sends you. Authentication is synchronous and on a tight deadline (lunar waits only a couple of seconds for an accept/reject) so it must be answered inline, fast. Accounting is fire-and-forget (lunar fast-ACKs it and delivers it out-of-band) so it should never sit on the request path. Build each accordingly.

Lunar instances -> HTTP/2

Your lunar nodes are the clients. Terminate their connections on HTTP/2 over TLS: lunar keeps many connections open and multiplexes requests over them, so HTTP/2 cuts per-request connection overhead dramatically on the hot auth path.

Load balancer (nginx / HAProxy)

Put an L7 load balancer in front. It terminates TLS, keeps connections alive to the backends, and spreads requests across however many backend servers you run. This is the same pattern lunar's own install uses, and it is where you add or remove backend capacity without ever touching lunar.

Backend servers (stateless)

Run several identical, stateless backend processes behind the load balancer. Stateless is what lets you scale horizontally. Any server can answer any request, so you add capacity simply by adding servers. Each server:

  • Answers auth directly. Look the subscriber up, verify the credential (PAP / CHAP / MS-CHAP, see the integration guide), decide, and return the reply attributes, all within lunar's deadline. Keep this path lean and put a cache in front of your user store (below) so the common case never hits the database.

  • Publishes accounting to Kafka. Do not write accounting to your database on the request. Publish each accounting record to Kafka and return 200 immediately, so the receive path stays fast and absorbs bursts.

Kafka for accounting

Kafka decouples receiving accounting from processing it. Partition the topic by a stable key (the NAS, or the subscriber/session) so all records for one session land on the same partition and are processed in order, and so you scale throughput by adding partitions.

Background workers

Run a pool of workers that consume the Kafka partitions and do the slow work off the hot path: persist sessions, roll up usage, update balances, trigger CoA on quota exhaustion, and so on. Because the work is partitioned, you scale by adding workers (up to the partition count), and each partition is handled by exactly one worker at a time, which preserves per-session ordering.

Supporting services

Around that core, the usual building blocks each do one job well:

  • MariaDB Galera: highly redundant for subscriber credentials, scales extremely well in cluster of nodes.

  • Redis: IP Pools and caching. Cache subscriber records, session state and rate-limit counters so the synchronous auth path rarely touches the primary database.

  • Elasticsearch: logs. Ship your backend logs (and lunar's remote log stream) here for search and diagnostics.

  • InfluxDB / TimescaleDB: time-series. Store usage counters and per-session metrics as time series for dashboards, quotas and billing rollups.

Scaling further: sharding and partitioning

Beyond adding servers and partitions, you can shard and partition the backend itself, splitting subscribers across independent backend groups. Each group has its own database, cache and worker pool, so no single store is a bottleneck and failures stay contained.

This is exactly how we built NebularStack. Its sharding and partitioning is entirely in-house (not an off-the-shelf add-on) and represents years of engineering effort dedicated to making it incredibly fast and scalable. It runs many stacks in a single region, and we shard and partition per stack across the backends. Each stack gets isolated, independently scalable capacity while sharing one regional footprint. The result is a platform tuned, over many iterations, to sustain very high request rates with predictable, low latency.

Where to go from here

You do not have to build all of this yourself. At Interstellio we can help you design and build a backend and platform like this for your network. Or you can use it today with NebularStack, our ready-made subscriber management platform that already implements the lunar backend and everything above. Inquire at info@interstellio.io.