The O-RAN RIC is only as powerful as the applications running on it. xApps (on Near-RT RIC, 10ms-1s loop) and rApps (on Non-RT RIC, >1s loop) are containerized, third-party applications that implement AI/ML-based RAN optimization. They are the reason O-RAN exists — without them, the RIC is just an expensive empty platform. In this article, we explore the top use cases, the development lifecycle, ML model deployment, and the critical challenge of conflict resolution when multiple xApps try to control the same cell.
xApps vs rApps: Quick Reference
| Aspect | xApp (Near-RT RIC) | rApp (Non-RT RIC) |
|---|---|---|
| Control Loop | 10ms to 1 second | >1 second (minutes to hours) |
| Interface to RAN | E2 (E2SM-KPM, E2SM-RC) | A1 policies (via Near-RT RIC) or O1 |
| Use Cases | Traffic steering, HO optimization, QoS, interference | Coverage optimization, energy saving, capacity planning, ML training |
| Data Access | Real-time KPIs from E2 nodes | Historical data from data lake + A1 enrichment |
| ML Models | Inference only (pre-trained models) | Training + deployment of models to xApps |
| Deployment | Containerized (Kubernetes pod) | Containerized (Kubernetes pod) |
xApps vs rApps: When to Use Which
Timescale determines where your intelligence runs
The golden rule: if your decision needs to happen in <1 second, it is an xApp. If it can wait, it is an rApp. Traffic steering (move this UE NOW) = xApp. Coverage optimization (adjust tilts over the next hour) = rApp. Model training (retrain every night) = rApp. The Non-RT RIC trains models and sets policies; the Near-RT RIC executes them in real-time.
xApp or rApp?
Use Case: Traffic Steering xApp
Move UEs between cells/carriers/slices in real-time
Traffic steering is the flagship xApp use case. The xApp monitors per-cell load (PRB utilization, active UEs, throughput) via E2SM-KPM, identifies congested cells, and sends handover/redirect commands via E2SM-RC to move UEs to less-loaded cells, carriers, or slices. Decision latency: 100-500ms. KPI impact: +15-25% cell-edge throughput, -30% congestion events.
1. Subscribe to Load KPIs
E2 Subscription: PRB.Used.DL.Avg, RRC.ConnMean, DL.THP per cell. Reporting period: 100ms. Covers 100-500 cells per xApp instance.
2. ML Decision
Model predicts: which UEs to move, to which target cell, at what time. Inputs: current load, predicted load (next 5min), UE RSRP to neighbors, UE QoS requirements.
3. E2 Control
Send E2SM-RC CONTROL message: handover specific UE to target cell. Or: change CIO to influence future handovers. Or: activate inter-frequency redirect.
4. Feedback Loop
Monitor KPIs after action. Did throughput improve? Did the target cell become congested? Adjust model weights. Continuous learning.
Use Case: Handover Optimization xApp
AI-optimized A3 parameters per cell-pair
This xApp subscribes to handover KPIs (HO success/failure/ping-pong counts) via E2SM-KPM and adjusts per-cell-pair parameters (A3-Offset, TTT, CIO) via E2SM-RC. Unlike traditional SON MRO (fixed +/-1dB steps), the AI model optimizes multiple parameters simultaneously using reinforcement learning. Production results: HOSR 97% to 99.1%, ping-pong -62%.
Use Case: QoS Management xApp
SLA-aware resource allocation per slice per cell
In a 5G network with multiple slices (eMBB, URLLC, mMTC), this xApp ensures each slice meets its SLA. It monitors per-slice KPIs (throughput, latency, packet loss) via E2SM-KPM and adjusts scheduling weights, PRB allocation, and admission control via E2SM-RC. When URLLC latency approaches the SLA threshold, the xApp can preempt eMBB resources to protect URLLC.
URLLC latency is at 9ms (SLA = 10ms). eMBB throughput is at 80 Mbps (SLA = 50 Mbps). PRBs are 95% utilized. What should the QoS xApp do?
Use Case: Anomaly Detection xApp
Sleeping cells, interference, and KPI degradation
This xApp uses autoencoders (trained by rApp on Non-RT RIC) to detect cells behaving abnormally: sleeping cells (low traffic, no alarms), sudden KPI degradation (HOSR drop, throughput collapse), interference patterns (periodic PIM, external). It receives per-cell KPIs via E2SM-KPM, calculates reconstruction error, and raises alerts when error exceeds threshold. Can also trigger automated recovery: cell restart, parameter reset, or neighbor compensation.
xApp Development Lifecycle
From idea to production: containerization, testing, deployment
An xApp is a Docker container deployed on the Near-RT RIC (Kubernetes). The development lifecycle: (1) Define use case and required KPIs, (2) Implement E2 subscription/control logic using the RIC SDK (C++/Python/Go), (3) Package as Docker image with xApp descriptor (JSON), (4) Test in RIC simulation environment (E2 simulator), (5) Deploy to staging RIC with shadow mode (read-only), (6) Production deployment with kill switch.
1. Develop
Use O-RAN SC RIC SDK (C++/Python). Implement E2 subscribe/indicate/control handlers. Define xApp descriptor (name, version, E2SM types, config).
2. Containerize
Package as Docker image. Include ML model files, config, and dependencies. Image size: typically 200-500MB.
3. Test
Deploy on RIC test environment with E2 simulator. Verify E2 subscriptions work, control actions execute correctly. Load test with 500+ simulated cells.
4. Deploy
Shadow mode first (observe only, no control). Then gradual rollout: 10 cells -> 100 cells -> full network. Kill switch: auto-disable if KPIs degrade >5%.
A new traffic steering xApp is ready. What is the safest deployment approach?
ML Model Lifecycle in O-RAN
Train on Non-RT RIC, deploy to xApp via A1, monitor drift
The ML lifecycle spans both RICs: (1) Data collection: Non-RT RIC aggregates historical KPIs from data lake, (2) Training: rApp trains model (XGBoost/LSTM/RL) on Non-RT RIC or external ML platform, (3) Validation: Test on held-out data + shadow mode validation, (4) Deployment: Push model to xApp via A1 interface (model package), (5) Monitoring: Track model accuracy over time, detect drift, trigger retraining when accuracy drops below threshold.
Conflict Resolution
What happens when two xApps want to change the same cell?
This is the hardest unsolved problem in O-RAN. Scenario: the Traffic Steering xApp wants to increase CIO on Cell A (push users to Cell B), but the HO Optimization xApp wants to decrease CIO (reduce ping-pong from Cell A to Cell B). Both send E2 CONTROL messages to the same cell. Who wins? Three approaches: (1) Priority-based: assign static priorities to xApps, (2) Conflict Manager: a dedicated component in the RIC that mediates, (3) A1 Policy constraints: Non-RT RIC sets boundaries that xApps cannot exceed.
Traffic Steering wants CIO +3dB. HO Optimization wants CIO -1dB. Same cell. How to resolve?
Final Assessment
10 questions on O-RAN xApps & rApps