August was about closing the loop on billing. The billing infrastructure from June needed enforcement teeth — containers from cancelled subscriptions should stop running, and our usage numbers should match what the payment provider sees. Both of those shipped. On the platform side, Docker Hub tag browsing landed so applications can select image versions without leaving the admin panel, and node management got a set of tools for operating at scale.
Here’s everything that landed.
Billing enforcement
When a subscription is revoked, the platform now stops that organization’s containers immediately. Previously, containers kept running after cancellation — free compute past the paid period. Since Polar cancels at period end, by the time the revoke webhook fires the customer has already received everything they paid for, so there’s no reason to keep their sessions alive.
The revoke webhook path fires an asynchronous stopContainersForOrg after the revocation transaction completes. It’s async because Polar expects a fast response and each container stop can take seconds; it’s targeted so one org’s cancellation never touches other orgs.
An hourly enforcement cron runs as a backstop for anything the webhook path missed — a pod that died mid-stop, an org without a usable session:stop token. The cron retries those on the next sweep. A configurable grace period (BILLING_ENFORCEMENT_GRACE_HOURS) defaults to zero but can be restored if policy changes.
On the admin side, a new super-admin card on the subscription types page lets operators trigger the enforcement sweep manually, bypassing the cron schedule. The button goes through a confirmation dialog and shows results inline: stopped count, per-container failures, and orgs skipped for lacking a usable token.
Billing reconciliation
Both sides of the metering pipeline can look healthy while silently diverging — our ingest returns 200 even when the meter filter doesn’t match, and Polar’s meter can’t know what we intended to send. A new reconciliation service now compares them.
For each org with an active subscription, the service sums the per-day values from our billing_usage_reports table against the consumed units on the customer’s active Polar meters. The epsilon is 0.01 vCPU-hours; per-meter breakdown is included so a stray meter is visible. An active-subscription org with no reachable Polar customer always counts as drift.
A nightly cron at 00:20 UTC (after the 00:05 usage report) WARN-logs each drift row, making divergence alertable from the log pipeline. A GET /v1/billing/reconciliation endpoint is available for on-demand checks by super admins.
Alongside reconciliation, the system now tracks unbilled trial-pool usage by paying organizations — month-to-date vCPU-hours per active-subscription org on pools outside the billing pool, plus the billed total for the same window so the ratio is visible at a glance.
Docker Hub tag browser
The platform can now browse Docker Hub repository tags directly from the API. A new /registry/{registry}/repositories/{repository} endpoint queries Docker Hub’s REST API, authenticates against the registry, and returns paginated image tags.
This is wired into the application flow — when configuring or updating an application, the available image tags are visible without leaving the admin panel or manually checking Docker Hub. A new registry:read scope was added to the permission model to control access to this endpoint.
The implementation separates the Docker Hub REST API (used for tag listing and authentication) from the Docker Hub Registry API (used for image pulls), with documentation clarifying the distinction for future contributors.
Smaller changes
Node management overhaul. The nodes table in the admin panel now supports filtering by node pool, region, provider, state, and availability — with URL state persistence so filter settings survive navigation. Mass availability updates let operators toggle multiple nodes at once instead of one by one. A new endpoint lists distinct provider names for easier filtering.
Node scheduling priority. The orchestrator now considers node priority when placing containers, preferring more recently updated nodes first. This gives operators a lever to steer placement toward preferred infrastructure.
TLS port bindings. Port bindings now accept a TLS parameter when creating an application. The warm pool code was updated to account for TLS in port sets, and the published_ports table now records the original container port. This extends the TLS groundwork from June closer to production readiness.
Trial node pool isolation. New organizations are now assigned to a trial node pool instead of default. This makes trial workloads explicitly separable from production traffic at the infrastructure level.
Resource profile validation. The application form now enforces resource limits based on the user’s subscription tier. Trial users see their limits clearly; super admins can override. The validation runs on both individual and mass application updates.
Tag management access control. The tagKeep attribute — which controls how many image tags are retained per application — is now restricted to super admins. Non-super-admin users default to 1 on creation; updates ignore the field entirely for regular users.
Container cleanup. Container cleanup is now triggered every time a container exits or is destroyed, rather than relying on a separate sweep. This ensures stale container state is removed promptly.
Host provider tracking. Container history now records the host provider name, so infrastructure reports can break down usage by provider.
Contact Us link. The admin panel navigation now includes a “Contact Us” mailto link, replacing the “Go to Production” button with conditional rendering based on billing feature availability.
What’s coming next
Billing enforcement and reconciliation are in place — the billing pipeline is now end-to-end: metering, invoicing, enforcement, and drift detection. The Docker Hub tag browser opens the door to tag selection in the application creation flow. TLS port bindings are progressing toward general availability. Node priority and mass management tools continue to evolve as the fleet grows.
Questions about any of these changes? See the admin panel docs or reach out directly.
More platform updates: ← June 2026