Version: 1.0.0
Category: API Patterns
Purpose: Guide for AI agents on choosing between polling and streaming for real-time data
This pattern helps AI agents decide when to use polling (repeated API requests) versus streaming (GRASS/NATS real-time updates) for accessing game state data. Each approach has trade-offs in terms of performance, accuracy, and resource usage.
Characteristics:
Examples:
Characteristics:
Examples:
Characteristics:
Examples:
| Factor | Polling | Streaming |
|---|---|---|
| Latency | High (poll interval) | Low (real-time) |
| Accuracy | Stale until next poll | Real-time |
| API Calls | Many (repeated requests) | Few (one connection) |
| Rate Limits | Consumes quota | No rate limits |
| Complexity | Simple | Moderate |
| Resource Usage | CPU/Network per poll | Persistent connection |
| Error Handling | Per-request | Connection-level |
| Offline Support | None | Reconnection needed |
Approach: Poll at regular intervals
Implementation:
{
"pattern": "fixed-interval-polling",
"interval": 5000,
"unit": "milliseconds",
"endpoint": "/api/planet/{planet_id}/shield/health"
}
Example:
{
"polling": {
"interval": 5000,
"action": "Poll planet shield every 5 seconds",
"code": "setInterval(() => pollPlanetShield(), 5000)"
}
}
Use When:
Approach: Adjust poll interval based on activity
Implementation:
{
"pattern": "adaptive-polling",
"intervals": {
"active": 1000,
"inactive": 10000,
"idle": 60000
},
"trigger": "activity-detected"
}
Example:
{
"adaptivePolling": {
"duringRaid": {
"interval": 1000,
"reason": "High activity, need frequent updates"
},
"normal": {
"interval": 5000,
"reason": "Normal activity"
},
"idle": {
"interval": 30000,
"reason": "Low activity, reduce polling"
}
}
}
Use When:
Approach: Poll when specific events occur
Implementation:
{
"pattern": "event-triggered-polling",
"trigger": "external-event",
"action": "poll-on-demand"
}
Example:
{
"eventTriggered": {
"onUserAction": "Poll player data",
"onNotification": "Poll related entity",
"onTimer": "Poll at scheduled time"
}
}
Use When:
Approach: Subscribe to one specific subject
Implementation:
{
"pattern": "single-subject-streaming",
"subject": "structs.planet.2-1",
"events": ["raid_status", "fleet_arrive", "fleet_depart"]
}
Example:
{
"subscription": {
"subject": "structs.planet.2-1",
"description": "Monitor specific planet",
"events": [
"raid_status",
"fleet_arrive",
"fleet_advance",
"fleet_depart"
]
}
}
Use When:
Approach: Subscribe to multiple entities with pattern
Implementation:
{
"pattern": "wildcard-streaming",
"subject": "structs.player.*",
"description": "Monitor all players"
}
Example:
{
"subscription": {
"subject": "structs.player.*",
"description": "Monitor all player updates",
"filter": "Process only relevant players"
}
}
Use When:
Approach: Subscribe to multiple specific subjects
Implementation:
{
"pattern": "multi-subject-streaming",
"subjects": [
"structs.player.1-1",
"structs.planet.2-1",
"structs.guild.0-1"
]
}
Example:
{
"subscriptions": {
"player": "structs.player.1-1",
"planet": "structs.planet.2-1",
"guild": "structs.guild.0-1"
}
}
Use When:
Approach: Load initial state via polling, then stream updates
Implementation:
{
"pattern": "initial-load-streaming",
"steps": [
{
"step": 1,
"method": "polling",
"action": "GET /api/player/{id}",
"description": "Load initial player data"
},
{
"step": 2,
"method": "streaming",
"action": "Subscribe to structs.player.{id}",
"description": "Stream updates"
}
]
}
Benefits:
Approach: Use streaming, fallback to polling if connection lost
Implementation:
{
"pattern": "streaming-with-fallback",
"primary": "streaming",
"fallback": "polling",
"reconnect": true,
"fallbackInterval": 5000
}
Example:
{
"strategy": {
"primary": {
"method": "streaming",
"subject": "structs.planet.2-1"
},
"fallback": {
"method": "polling",
"interval": 5000,
"trigger": "streaming-connection-lost"
},
"reconnect": {
"enabled": true,
"strategy": "exponential-backoff"
}
}
}
Benefits:
Approach: Stream high-frequency data, poll low-frequency data
Implementation:
{
"pattern": "selective-streaming",
"streaming": {
"data": ["planet_shield", "fleet_status", "raid_status"],
"reason": "High frequency, real-time needed"
},
"polling": {
"data": ["player_profile", "guild_info", "struct_types"],
"interval": 300000,
"reason": "Low frequency, acceptable latency"
}
}
Benefits:
Factors:
Optimization:
{
"optimization": {
"reduceInterval": "When rate limit allows",
"batchRequests": "When possible",
"cacheResponses": "To reduce API calls",
"prioritizeEndpoints": "Focus on critical data"
}
}
Factors:
Optimization:
{
"optimization": {
"filterEvents": "Process only relevant events",
"batchProcessing": "Process multiple events together",
"connectionPooling": "Reuse connections",
"backpressure": "Handle high event rates"
}
}
API Calls: High (repeated requests) Rate Limit Usage: High Network Bandwidth: Moderate Server Load: High (many requests)
Example:
API Calls: Low (one connection) Rate Limit Usage: None Network Bandwidth: Low (persistent connection) Server Load: Low (one connection)
Example:
High Frequency (changes every few seconds):
Low Frequency (changes every few minutes):
Initial Load: Polling (fast, simple) Updates: Streaming (real-time, efficient)
Metrics:
Always:
When Polling:
Use Case: Monitor planet shield during raid
Implementation:
{
"useCase": "planet-shield-monitoring",
"method": "streaming",
"reason": "High frequency updates during raid",
"implementation": {
"subscribe": "structs.planet.2-1",
"filter": "raid_status events",
"action": "Update shield health on event"
}
}
Benefits:
Use Case: Display player profile information
Implementation:
{
"useCase": "player-profile",
"method": "polling",
"reason": "Changes infrequently",
"implementation": {
"interval": 300000,
"endpoint": "/api/player/{id}",
"cache": true,
"ttl": 300
}
}
Benefits:
Use Case: Display guild information with real-time member updates
Implementation:
{
"useCase": "guild-dashboard",
"method": "hybrid",
"implementation": {
"initialLoad": {
"method": "polling",
"endpoints": [
"/api/guild/{id}",
"/api/guild/{id}/members/count",
"/api/guild/{id}/power/stats"
]
},
"updates": {
"method": "streaming",
"subjects": [
"structs.guild.{id}",
"structs.player.*"
],
"filter": "guild-related events"
}
}
}
Benefits:
Start
│
├─ Data changes every few seconds?
│ ├─ Yes → Use Streaming
│ └─ No → Continue
│
├─ Need real-time accuracy?
│ ├─ Yes → Use Streaming
│ └─ No → Continue
│
├─ High update frequency expected?
│ ├─ Yes → Use Streaming
│ └─ No → Continue
│
├─ Simple implementation preferred?
│ ├─ Yes → Use Polling
│ └─ No → Continue
│
└─ Use Hybrid (Initial Load + Streaming)
protocols/streaming.md - Complete GRASS/NATS streaming guideprotocols/query-protocol.md - Polling/query patternspatterns/caching.md - Caching strategies (complements polling)patterns/rate-limiting.md - Rate limit handling (affects polling)Pattern Version: 1.0.0 - January 2025