Skip to main content

License sync

Once linked, your instance will:

  • Validate the license on startup
  • Sync usage data every hour by default (configurable via LICENSE_SYNC_INTERVAL_SECONDS, accepted range 60..3600 seconds)
  • Cache limits locally for fast quota checks
  • Report instance health and service stats

Sync runs in-process — you don't need to configure an external cron job or Kubernetes CronJob. Your instance starts syncing automatically after boot.

If a sync fails​

If the hub is unreachable or rejects the sync, your instance continues to use cached limits for up to 24 hours (cache TTL) + 24 hours (grace period) before resource creation is blocked. In practice a short outage is invisible to your users.

The last error from the most recent failed sync is persisted and shown on your Admin dashboard (/admin) as a red banner with the error text and timestamp — no need to check server logs or a Kubernetes dashboard. A Retry Sync button on the same card lets you trigger an immediate sync without restarting the instance.

Sync Response​

The license sync returns limits and feature flags that your instance uses to gate functionality:

{
"valid": true,
"limits": {
"projects": 20,
"apps": 50,
"databases": 25,
"domains": 50,
"customDomains": 10,
"freeSubdomains": 5,
"purchasableDomains": 0,
"teamMembers": 20,
"buildMinutes": 2000,
"storageBytes": 268435456000,
"instances": 3
},
"features": {
"whiteLabel": false,
"customDomains": true,
"domainPurchase": false,
"aiAssistant": true,
"multiServer": true,
"prioritySupport": false
},
"effectiveRemaining": {
"projects": 8,
"apps": 22,
"databases": 12,
"domains": 20,
"customDomains": 4,
"purchasedDomains": 5,
"freeSubdomains": 7,
"teamMembers": 5,
"buildMinutes": 1150,
"storageBytes": 214748364800
},
"warnings": [],
"billingPeriodReset": "2025-02-01T00:00:00Z",
"gracePeriodHours": 24,
"cacheExpiresAt": "2025-01-12T00:00:00Z"
}

Domain Limits​

The sync response includes domain-specific limits:

LimitDescription
domainsTotal domain slots (legacy)
customDomainsUser-provided custom domains allowed
freeSubdomainsFree *.kuploy.app subdomains allowed
purchasableDomainsDomains purchasable through the platform (Enterprise only)

Multi-Instance Aggregate Quotas​

If your plan allows multiple instances (Business: 3, Enterprise: unlimited), usage is aggregated across all instances under the same license.

For example, with a Growth plan (20 project limit):

  • Instance A has 8 projects
  • Instance B has 5 projects
  • Instance C has 3 projects
  • Aggregate: 16/20 (80%) — a warning is triggered

Rather than echoing every instance's raw counts back to each instance, kuploy.app sends each instance a per-resource effectiveRemaining number — how many more of each resource that instance may still create under the license. In the example above, each instance would see projects: 4 in its sync response, and its local canCreate() gate allows up to 4 more projects before the aggregate limit is reached.

Instances never see sibling instances' individual counts; only the pre-computed headroom. Warnings and thresholds are also computed server-side and included in the sync response.

Offline Behavior​

If your instance can't reach the license hub:

  1. Cached limits continue to work
  2. Local quota enforcement remains active
  3. Usage deltas are queued for next sync
  4. A warning banner appears in the dashboard

When connection is restored, your instance will sync all pending usage data.

Cache State Machine​

The license cache follows this state progression:

StateDescriptionBehavior
freshValid license, cache within TTLFull operation allowed
staleValid license, cache expired, in grace periodOperations allowed, warning banner shown
frozenGrace period expired, cannot reach serverNew resource creation blocked
emptyNo license configuredBlocks creation if LICENSE_KEY expected
invalidLicense validation failedNew resource creation blocked