Architecture
Understanding Toggly's architecture helps you make informed decisions about how to integrate and use the platform effectively.
High-Level Overview
Toggly uses a dual-architecture approach optimized for different deployment scenarios:
- Server-side SDKs: Fetch feature definitions and evaluate locally
- Client-side SDKs: Receive pre-evaluated feature flags
┌────────────────────────────────────────────────────────┐
│ Toggly Service │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Dashboard │ │ Feature │ │ Metrics │ │
│ │ UI │ │ Store │ │ Pipeline │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└────────────────────────────────────────────────────────┘
│ │
│ │
┌────┴────┐ ┌────┴────┐
│ │ │ │
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Server │ │ Server │ │ Client │ │ Client │
│ SDK │ │ SDK │ │ SDK │ │ SDK │
│ (.NET) │ │ (PHP) │ │ (JS) │ │(React) │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
Server-Side Architecture
Server-side SDKs (.NET, PHP, Go, etc.) fetch feature definitions and evaluate them locally in your application.
How It Works
-
Fetch Definitions: SDK fetches feature flag definitions from
https://definitions.toggly.io:/definitions/{appKey}/{environment}(unsigned)/definitions-signed/{appKey}/{environment}(signed with ECDSA)
-
Local Evaluation: SDK evaluates features locally using:
- Microsoft.FeatureManagement (for .NET)
- Custom evaluation logic (for other languages)
- Applies targeting rules, segments, and experiments
-
Real-Time Updates:
- Polling every 5 minutes
- WebSocket connection for instant updates
- ETag support for efficient updates
-
Metrics & Statistics:
- Sends usage statistics via gRPC
- Sends custom metrics via gRPC
- Batched every minute
-
Snapshot Support:
- Can load cached definitions on startup
- Supports offline operation
- Updates snapshots when API is available
Server-Side Data Flow
┌─────────────┐
│ Your Server │
│ Application │
└──────┬──────┘
│
│ 1. Fetch Definitions
▼
┌─────────────────────────────────────┐
│ TogglyFeatureProvider │
│ - GET definitions.toggly.io/... │
│ - WebSocket for live updates │
│ - ETag for conditional requests │
└──────┬──────────────────────────────┘
│
│ 2. Store & Cache
▼
┌─────────────────────────────────────┐
│ In-Memory Cache │
│ - Feature definitions │
│ - JWK sets (for signed defs) │
└──────┬──────────────────────────────┘
│
│ 3. Evaluate Locally
▼
┌─────────────────────────────────────┐
│ IFeatureManager │
│ - Apply targeting rules │
│ - Check segments │
│ - Evaluate experiments │
└──────┬──────────────────────────────┘
│
│ 4. Return Result
▼
┌─────────────┐
│ Your Code │
│ if (feature)│
└─────────────┘
│
│ 5. Send Metrics
▼
┌─────────────────────────────────────┐
│ gRPC Services │
│ - Usage statistics │
│ - Custom metrics │
└─────────────────────────────────────┘
Client-Side Architecture
Client-side SDKs (JavaScript, React, Vue, Angular, Flutter, etc.) receive pre-evaluated feature flags. You can fetch these flags from two sources:
- Toggly Definitions Worker: Direct connection to
definitions.toggly.io. - Your Backend Application: Proxy flags through your own server.
Option 1: Fetching from Toggly API
The standard approach connects directly to the definitions worker.
- Fetch pre-evaluated signed flags: SDK fetches boolean flags from:
https://definitions.toggly.io/evaluated-signed/{appKey}/{environment}(signed booleans)https://definitions.toggly.io/evaluated-variants-signed/{appKey}/{environment}(when variants are enabled)- Optional: Include user identity as query parameter (
?u=identityor?userId=identity)
- No raw definitions on device: Flags are evaluated on the worker; the client receives booleans (and optional signatures).
- Caching: Remote flags are cached in memory / storage for fast access.
- Device-local post-filter (optional): Apps may AND worker booleans with local prerequisites at read time — see Post-filter gates.
Option 2: Fetching from Your Backend (Recommended)
Serving feature flags from your own backend application is often the ideal approach because it guarantees synchronization between your backend and frontend states.
How it works:
- Backend Evaluation: Your server-side application (already using Toggly SDK) evaluates all feature flags for the current request context.
- API Endpoint: Your backend exposes the evaluated results (e.g., via a bootstrapped global variable or an API endpoint).
- Frontend Usage: The client-side SDK is initialized with these pre-evaluated flags instead of fetching them from Toggly's CDN.
Benefits:
- Consistency: Frontend and backend rely on the exact same evaluation for a given request.
- Efficiency: No extra HTTP request needed if flags are injected into the initial HTML response.
- Security: You have complete control over which flags are exposed to the client.
Client-Side Data Flow (Direct)
┌─────────────┐
│ Browser │
│ Application │
└──────┬──────┘
│
│ 1. Fetch Flags
▼
┌─────────────────────────────────────┐
│ Toggly Client SDK │
│ - GET definitions.toggly.io/... │
│ - evaluated-signed (+ optional sig)│
│ - Optional local post-filter read │
└──────┬──────────────────────────────┘
│
│ 2. Receive Pre-Evaluated Flags
▼
┌───────────── ────────────────────────┐
│ Toggly Service │
│ - Evaluates features server-side │
│ - Returns boolean flags │
│ - { "feature-key": true } │
└──────┬──────────────────────────────┘
│
│ 3. Cache & Return
▼
┌─────────────────────────────────────┐
│ Local Cache │
│ - In-memory storage │
│ - 3-minute refresh interval │
└──────┬──────────────────────────────┘
│
│ 4. Use Flags
▼
┌─────────────┐
│ Your Code │
│ if (flags. │
│ feature) │
└─────────────┘
Key Differences
| Aspect | Server-Side SDKs | Client-Side SDKs |
|---|---|---|
| Endpoint | definitions.toggly.io/definitions/{appKey}/{environment} | definitions.toggly.io/evaluated-signed/{appKey}/{environment} |
| Response | Feature definitions (rules, filters) | Pre-evaluated boolean flags |
| Evaluation | Local (in your application) | Server-side (by Toggly) |
| Update Method | Polling (5 min) + WebSocket | Polling (5 min) + WebSocket |
| Metrics | gRPC (usage stats, custom metrics) | None (optional via separate API) |
| Security | Supports signed definitions (ECDSA) | Supports signed definitions (ECDSA) |
| Offline Support | Snapshot providers | Cached flags + defaults |
| User Context | Full context for targeting | Optional identity parameter |
Communication Protocols
HTTP REST API
Server-Side (https://definitions.toggly.io):
GET /definitions/{appKey}/{environment}- Get feature definitions (unsigned)GET /definitions-signed/{appKey}/{environment}- Get signed feature definitionsGET /.well-known/jwks- Get JSON Web Key Set
Client-Side (https://definitions.toggly.io):
GET /evaluated-signed/{appKey}/{environment}- Get signed pre-evaluated flagsGET /evaluated-variants-signed/{appKey}/{environment}- Get signed flags with variants (when enabled)- Optional:
?u={identity}(or?userId=) - Include user identity
WebSocket
Client-side and server-side SDKs use WebSocket on the definitions worker for real-time sync signals:
wss://definitions.toggly.io/{appKey}/ws?rev={cachedRevision}
Protocol (client-side SDKs):
- Connect with optional
?rev=(cached definitions revision from last fetch) - Receive
{ type: "sync", etag, lastUpdated, unchanged? }on connect - Skip HTTP fetch when
unchanged: true - On
{ type: "flags-updated", etag, lastUpdated }, fetch only if revision differs - On
{ type: "signing-key-updated", kid, lastUpdated }, refetch JWKS and definitions
See WebSocket sync for the full client protocol.
Server-side (.NET and similar): connect to the same definitions worker WebSocket; update signals trigger a definitions refresh.
gRPC
Server-side SDKs use gRPC for high-performance metrics:
- Usage.UsageClient: Sends feature usage statistics
- Metrics.MetricsClient: Sends custom experiment metrics
- Batched and sent every minute
- Automatic retry with exponential backoff
Data Flow
Server-Side Feature Evaluation
- Initial Load: SDK fetches definitions from
https://definitions.toggly.io/definitions/{appKey}/{environment} - Cache: Definitions cached in memory
- Evaluation: When your code checks a feature, SDK evaluates locally:
- Applies targeting rules
- Checks user segments
- Evaluates experiments
- Returns boolean result
- Updates: WebSocket or polling keeps definitions fresh
- Metrics: Usage and metrics sent via gRPC
Client-Side Feature Check
- Initial Load: SDK fetches flags from
https://definitions.toggly.io/evaluated-signed/{appKey}/{environment} - Cache: Flags and definitions revision cached in memory (and optionally persistent storage)
- Check: Your code reads boolean value directly
- Refresh: WebSocket sync signals + interval polling; HTTP uses
If-None-Matchfor 304 responses - Fallback: Uses cached flags or defaults on error
Feature Flag Update
- Dashboard Change: Admin updates feature flag in dashboard
- Storage: Change stored in Feature Store
- Server-Side: WebSocket notifies SDKs, or polling picks up change
- Client-Side: WebSocket
flags-updated(with revision) or next poll fetches updated flags; HTTP returns 304 when unchanged - Cache Update: SDK caches updated values
- Audit: Change recorded in audit log
Security & Compliance
Privacy by Design
Toggly is designed to minimize data collection and ensure end-user privacy:
- Aggregated Metrics: Feature usage stats (total requests, unique users) are aggregated locally in your application (server-side SDKs) or in the hosted Toggly Clients app (for client-side SDKs).
- No PII Collection: We only receive aggregated counts and hashed identifiers for statistical purposes. We do not collect or store raw end-user data or PII (Personally Identifiable Information) from your application traffic.
- Targeting Data: While you can define user segments with specific attributes (e.g., email, plan, country) for targeting purposes, this data is strictly used for evaluating feature flags in real-time and is not harvested, sold, or used for any other purpose.
Data Encryption
- All API communication uses TLS 1.3
- Server-side definitions can be signed with ECDSA (ES256)
- Feature flag configurations are encrypted in transit and at rest
Authentication & Authorization
- App Keys: Public keys for both server-side and client-side SDKs
- Server-side: Used to fetch definitions
- Client-side: Used to fetch pre-evaluated flags (read-only, safe for frontend)
- Signed Definitions: Server-side SDKs can verify definitions using JWK sets
- Key Whitelisting: Optional whitelist of allowed key IDs for enhanced security
- SSO/SAML: Enterprise customers can use single sign-on
- SCIM: Automated user provisioning for enterprise
Audit & Compliance
- All changes are logged with full audit trails
- User actions are tracked with timestamps and user IDs
- Compliance with SOC 2 Type II, ISO 27001, and GDPR
- Data retention policies configurable per organization
- Right to erasure and data portability support
Performance Optimizations
- In-Memory Caching: Feature definitions cached locally
- ETag Support: Single definitions revision on HTTP (
If-None-Match,X-Definitions-Revision) and WebSocket (?rev=,sync) - Snapshot Providers: Fast startup with cached definitions
- WebSocket Updates: Instant updates without polling delay
- Batched Metrics: Usage stats and metrics batched every minute
Client-Side SDKs
- Lightweight: Receives simple boolean flags (no evaluation overhead)
- Efficient Caching: Flags cached in memory with configurable refresh
- Fast Response: Pre-evaluated flags reduce latency
- Graceful Degradation: Falls back to cached flags or defaults on error
Scalability
Toggly is designed to handle:
- High throughput: Millions of evaluations per second
- Global scale: Low latency worldwide via CDN for client-side SDKs
- High availability: 99.99% uptime SLA
- Auto-scaling: Automatic scaling based on load
- Distributed Evaluation: Server-side SDKs evaluate locally, reducing API load
Regional Deployment
Toggly supports regional deployments for:
- Data residency: Keep data in specific regions
- Compliance: Meet regional data protection requirements
- Performance: Lower latency for regional users
Choosing the Right SDK
Use Server-Side SDKs When:
- You need complex targeting rules evaluated in your backend
- You want to track detailed usage statistics and metrics
- You need offline support with snapshot providers
- You require signed definitions for security
- You want real-time updates via WebSocket
Use Client-Side SDKs When:
- You're building a frontend application (web, mobile)
- You want lightweight, fast flag checks
- You want to track detailed usage statistics and metrics (same as server-side)
Next Steps
- Learn about .NET SDK Architecture for detailed server-side SDK information
- Understand Environments
- Explore Segments and Targeting
- Review Metrics and Events
- Check out SDK Documentation for your platform